bulkupload
|
|
@ -108,6 +108,7 @@
|
||||||
"Webkul\\Notification\\": "packages/Webkul/Notification/src",
|
"Webkul\\Notification\\": "packages/Webkul/Notification/src",
|
||||||
"Webkul\\Sitemap\\": "packages/Webkul/Sitemap/src",
|
"Webkul\\Sitemap\\": "packages/Webkul/Sitemap/src",
|
||||||
"Webkul\\Marketplace\\": "packages/Webkul/Marketplace/src",
|
"Webkul\\Marketplace\\": "packages/Webkul/Marketplace/src",
|
||||||
|
"Webkul\\Bulkupload\\": "packages/Webkul/Bulkupload/src",
|
||||||
"Sarga\\Shop\\": "packages/Sarga/Shop/src",
|
"Sarga\\Shop\\": "packages/Sarga/Shop/src",
|
||||||
"Sarga\\API\\": "packages/Sarga/API",
|
"Sarga\\API\\": "packages/Sarga/API",
|
||||||
"Sarga\\Admin\\": "packages/Sarga/Admin/src",
|
"Sarga\\Admin\\": "packages/Sarga/Admin/src",
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,6 @@ return [
|
||||||
\Webkul\User\Providers\ModuleServiceProvider::class,
|
\Webkul\User\Providers\ModuleServiceProvider::class,
|
||||||
\Webkul\Velocity\Providers\ModuleServiceProvider::class,
|
\Webkul\Velocity\Providers\ModuleServiceProvider::class,
|
||||||
\Webkul\Sitemap\Providers\ModuleServiceProvider::class,
|
\Webkul\Sitemap\Providers\ModuleServiceProvider::class,
|
||||||
|
\Webkul\Bulkupload\Providers\ModuleServiceProvider::class,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
/package-lock.json
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
# CHANGELOG for v1.3.x
|
||||||
|
|
||||||
|
#### This changelog consists the bug & security fixes and new features being included in the releases listed below.
|
||||||
|
|
||||||
|
## **v1.3.3(24th of Oct, 2021)** - _Release_
|
||||||
|
|
||||||
|
- [compatible] Compatible with bagisto v1.3.3.
|
||||||
|
|
||||||
|
## **v1.3.2(27th of Sept, 2021)** - _Release_
|
||||||
|
|
||||||
|
- [compatible] Compatible with bagisto v1.3.2.
|
||||||
|
- [fix] datagrid issue with bagisto v1.3.2.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright 2010-2020, Webkul Software
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
# Bagisto Bulk Upload
|
||||||
|
|
||||||
|
By using this add-on, the admin can mass/bulk upload products of all types: simple, configurable, virtual, grouped, bundle, downloadable, booking.
|
||||||
|
|
||||||
|
It packs in lots of demanding features that allows your business to scale in no time:
|
||||||
|
|
||||||
|
- Product can be upload by CSV / XLS files.
|
||||||
|
- Data profile creation feature for admin.
|
||||||
|
- Each attribute has a different column.
|
||||||
|
- Image attachment with the product within CSV/XLS.
|
||||||
|
- If there is any error in the CSV / XLS file, then products will not be uploaded and hence customer/admin will come to know about the error.
|
||||||
|
|
||||||
|
## Requirements:
|
||||||
|
|
||||||
|
- **Bagisto**: v1.3.3
|
||||||
|
|
||||||
|
## Installation with composer:
|
||||||
|
- Run the following command
|
||||||
|
```
|
||||||
|
composer require bagisto/bagisto-bulk-upload
|
||||||
|
```
|
||||||
|
|
||||||
|
- Goto vendor/bagisto/bagisto-bulkupload and copy the storage folder and merge it into the root of your project.
|
||||||
|
|
||||||
|
- Goto config/concord.php file and add following line under 'modules'
|
||||||
|
```php
|
||||||
|
\Webkul\Bulkupload\Providers\ModuleServiceProvider::class
|
||||||
|
```
|
||||||
|
|
||||||
|
- Run these commands below to complete the setup
|
||||||
|
```
|
||||||
|
composer dump-autoload
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
php artisan migrate
|
||||||
|
php artisan storage:link
|
||||||
|
php artisan route:cache
|
||||||
|
php artisan config:cache
|
||||||
|
php artisan vendor:publish
|
||||||
|
```
|
||||||
|
-> Press 0 and then press enter to publish all assets and configurations.
|
||||||
|
|
||||||
|
## Installation without composer:
|
||||||
|
|
||||||
|
- Unzip the respective extension zip and then merge "packages" and "storage" folders into project root directory.
|
||||||
|
- Goto config/app.php file and add following line under 'providers'
|
||||||
|
|
||||||
|
```
|
||||||
|
Webkul\Bulkupload\Providers\BulkUploadServiceProvider::class
|
||||||
|
```
|
||||||
|
|
||||||
|
- Goto composer.json file and add following line under 'psr-4'
|
||||||
|
|
||||||
|
```
|
||||||
|
"Webkul\\Bulkupload\\": "packages/Webkul/Bulkupload/src"
|
||||||
|
```
|
||||||
|
|
||||||
|
- Goto config/concord.php file and add following line under 'modules'
|
||||||
|
|
||||||
|
```php
|
||||||
|
\Webkul\Bulkupload\Providers\ModuleServiceProvider::class
|
||||||
|
```
|
||||||
|
|
||||||
|
- Run these commands below to complete the setup
|
||||||
|
|
||||||
|
```
|
||||||
|
composer dump-autoload
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
php artisan migrate
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
php artisan storage:link
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
php artisan route:cache
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
php artisan vendor:publish
|
||||||
|
|
||||||
|
-> Press 0 and then press enter to publish all assets and configurations.
|
||||||
|
```
|
||||||
|
|
||||||
|
> That's it, now just execute the project on your specified domain.
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"name": "bagisto/bagisto-bulk-upload",
|
||||||
|
"description": "Add products using CSV or XLS in bagisto.",
|
||||||
|
"keywords": [
|
||||||
|
"bagisto",
|
||||||
|
"product upload",
|
||||||
|
"bulk upload"
|
||||||
|
],
|
||||||
|
"homepage": "https://github.com/bagisto/bagisto-bulk-upload",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Prateek Srivastava",
|
||||||
|
"email": "prateek.srivastava781@webkul.com",
|
||||||
|
"homepage": "https://bagisto.com",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"konekt/concord": "^1.2"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Webkul\\Bulkupload\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Webkul\\Bulkupload\\Providers\\BulkUploadServiceProvider"
|
||||||
|
],
|
||||||
|
"aliases": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimum-stability": "dev"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "npm run development",
|
||||||
|
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||||
|
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||||
|
"watch-poll": "cross-env npm run watch -- --watch-poll --progress",
|
||||||
|
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||||
|
"prod": "npm run production",
|
||||||
|
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"axios": "^0.18",
|
||||||
|
"cross-env": "^5.1.4",
|
||||||
|
"laravel-mix": "^2.1",
|
||||||
|
"laravel-mix-merge-manifest": "^0.1.1",
|
||||||
|
"jquery": "^3.2",
|
||||||
|
"vue": "^2.1.10"
|
||||||
|
},
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
.bulk-upload-icon{background-image:url("../images/Icon-Bulk-Upload.svg")}.active .bulk-upload-icon,.bulk-upload-icon{width:48px;height:48px;display:inline-block;background-size:cover}.active .bulk-upload-icon{background-image:url("../images/Icon-Bulk-Upload-Active.svg")}progress{margin:15px 0 15px 34px;width:70%;height:15px}.icon{background-size:cover;display:inline-block}.icon.check-accent{width:22px;height:18px;background-image:url("../images/check-accent.svg")}.icon.icon-crossed{width:18px;height:15px;background-image:url("../images/Icon-Crossed.svg")}.icon.cross-accent{width:22px;height:18px;background-image:url("../images/cross-accent.svg")}.icon.finish-icon{width:22px;height:18px;background-image:url("../images/finish.svg")}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
.bulk-upload-icon {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
display: inline-block;
|
||||||
|
background-size: cover;
|
||||||
|
background-image: url("../images/Icon-Bulk-Upload.svg");
|
||||||
|
}
|
||||||
|
.active.bulk-upload-icon,
|
||||||
|
.active .bulk-upload-icon {
|
||||||
|
background-image: url("../images/Icon-Bulk-Upload-Active.svg");
|
||||||
|
}
|
||||||
|
progress {
|
||||||
|
margin: 15px 0 15px 34px;
|
||||||
|
width: 70%;
|
||||||
|
height: 15px;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
background-size: cover;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.icon.check-accent {
|
||||||
|
background-image: url("../images/check-accent.svg");
|
||||||
|
width: 22px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
.icon.icon-crossed {
|
||||||
|
width: 18px;
|
||||||
|
height: 15px;
|
||||||
|
background-image: url("../images/Icon-Crossed.svg");
|
||||||
|
}
|
||||||
|
.icon.cross-accent {
|
||||||
|
width: 22px;
|
||||||
|
height: 18px;
|
||||||
|
background-image: url("../images/cross-accent.svg");
|
||||||
|
}
|
||||||
|
.icon.finish-icon {
|
||||||
|
width: 22px;
|
||||||
|
height: 18px;
|
||||||
|
background-image: url("../images/finish.svg");
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 51.1 (57501) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Icon-Bulk-Upload-Active</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Icon-Bulk-Upload-Active" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M12.9981102,12.047248 L37.9981102,12.0000018 C38.5503939,11.9989581 38.9989545,12.4458264 38.9999982,12.9981102 C38.9999994,12.9987401 39,12.9993701 39,13 L39,37.9962168 C39,38.5485015 38.5522847,38.9962168 38,38.9962168 C37.9993701,38.9962168 37.9987401,38.9962162 37.9981102,38.996215 L12.9981102,38.9489688 C12.4465643,38.9479265 12,38.5005175 12,37.9489706 L12,13.0472462 C12,12.4956993 12.4465643,12.0482903 12.9981102,12.047248 Z" id="Rectangle-15" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<path d="M9,33.9508587 L9,11.0453581 C9,9.94226441 9.89312856,9.04744638 10.9962203,9.04536171 L33.9962203,9.00189524" id="Path" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<path d="M12,17.202381 L39,17.202381" id="Path-29" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<path d="M31.25,31 L31.25,35" id="Path-30-Copy-2" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<path d="M34.25,31 L34.25,35" id="Path-30-Copy-3" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<path d="M26,22 L26,31" id="Path-30" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<polyline id="Path-38" stroke="#0041FF" stroke-width="2" transform="translate(26.000000, 25.000000) rotate(45.000000) translate(-26.000000, -25.000000) " points="23 28 23 22 29 22"></polyline>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 51.1 (57501) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Icon-Bulk-Upload</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Icon-Bulk-Upload" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<path d="M12.9981102,12.047248 L37.9981102,12.0000018 C38.5503939,11.9989581 38.9989545,12.4458264 38.9999982,12.9981102 C38.9999994,12.9987401 39,12.9993701 39,13 L39,37.9962168 C39,38.5485015 38.5522847,38.9962168 38,38.9962168 C37.9993701,38.9962168 37.9987401,38.9962162 37.9981102,38.996215 L12.9981102,38.9489688 C12.4465643,38.9479265 12,38.5005175 12,37.9489706 L12,13.0472462 C12,12.4956993 12.4465643,12.0482903 12.9981102,12.047248 Z" id="Rectangle-15" stroke="#8E8E8E" stroke-width="2" fill-rule="nonzero"></path>
|
||||||
|
<path d="M9,33.9508587 L9,11.0453581 C9,9.94226441 9.89312856,9.04744638 10.9962203,9.04536171 L33.9962203,9.00189524" id="Path" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill-rule="nonzero"></path>
|
||||||
|
<path d="M12,17.202381 L39,17.202381" id="Path-29" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
|
<path d="M31.25,31 L31.25,35" id="Path-30-Copy-2" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
|
<path d="M34.25,31 L34.25,35" id="Path-30-Copy-3" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
|
<path d="M26,22 L26,31" id="Path-30" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
|
<polyline id="Path-38" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(26.000000, 25.000000) rotate(45.000000) translate(-26.000000, -25.000000) " points="23 28 23 22 29 22"></polyline>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Icon-Crossed</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Icon-Crossed" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<path d="M9,8.35557738 L12.2221131,5.13346429 C12.4000655,4.9555119 12.6885833,4.9555119 12.8665357,5.13346429 C13.0444881,5.31141669 13.0444881,5.59993452 12.8665357,5.77788691 L9.64442262,9 L12.8665357,12.2221131 C13.0444881,12.4000655 13.0444881,12.6885833 12.8665357,12.8665357 C12.6885833,13.0444881 12.4000655,13.0444881 12.2221131,12.8665357 L9,9.64442262 L5.77788691,12.8665357 C5.59993452,13.0444881 5.31141669,13.0444881 5.13346429,12.8665357 C4.9555119,12.6885833 4.9555119,12.4000655 5.13346429,12.2221131 L8.35557738,9 L5.13346429,5.77788691 C4.9555119,5.59993452 4.9555119,5.31141669 5.13346429,5.13346429 C5.31141669,4.9555119 5.59993452,4.9555119 5.77788691,5.13346429 L9,8.35557738 Z" id="Combined-Shape" fill="#8E8E8E"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Check-Accent</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Check-Accent" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<polyline id="Path-2" stroke="#0041FF" stroke-width="3" points="2 10 6 14 15 5"></polyline>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 606 B |
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Cross-Accent</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Cross-Accent" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M4.5,13.5 L13.5,4.5" id="Path-2" stroke="#0041FF" stroke-width="3" transform="translate(9.000000, 9.000000) scale(-1, 1) translate(-9.000000, -9.000000) "></path>
|
||||||
|
<path d="M4.5,13.5 L13.5,4.5" id="Path-2" stroke="#0041FF" stroke-width="3"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 778 B |
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 50 (54983) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>tab/heading/icon/finish</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="tab/heading/icon/finish" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="Group" transform="translate(6.000000, 8.000000)" stroke="#242424" stroke-width="3">
|
||||||
|
<rect id="Rectangle-10" x="1.5" y="1.5" width="17" height="10"></rect>
|
||||||
|
</g>
|
||||||
|
<rect id="Rectangle-2" fill="#242424" x="8" y="13" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy-2" fill="#242424" x="14" y="13" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy-5" fill="#242424" x="20" y="13" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy" fill="#242424" x="11" y="10" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy-3" fill="#242424" x="17" y="10" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy" fill="#242424" x="11" y="16" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy-4" fill="#242424" x="17" y="16" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle" fill="#242424" transform="translate(7.500000, 16.500000) rotate(90.000000) translate(-7.500000, -16.500000) " x="-2" y="15" width="19" height="3"></rect>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"/css/bk_upload.css": "/css/bk_upload.css?id=b316e32901a4fff5f3a0",
|
||||||
|
"/css/bulk-admin.css": "/css/bulk-admin.css?id=d3639ab33677e9640729"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'key' => 'catalog.bulkupload',
|
||||||
|
'name' => 'bulkupload::app.admin.bulk-upload.manage-bulk-upload',
|
||||||
|
'route' => 'admin.dataflow-profile.index',
|
||||||
|
'sort' => 5,
|
||||||
|
'icon-class' => '',
|
||||||
|
], [
|
||||||
|
'key' => 'catalog.bulkupload.data-flow-profile',
|
||||||
|
'name' => 'bulkupload::app.admin.bulk-upload.data-flow-profile.index',
|
||||||
|
'route' => 'admin.dataflow-profile.index',
|
||||||
|
'sort' => 1,
|
||||||
|
'icon-class' => '',
|
||||||
|
], [
|
||||||
|
'key' => 'catalog.bulkupload.upload-files',
|
||||||
|
'name' => 'bulkupload::app.admin.bulk-upload.upload-files.index',
|
||||||
|
'route' => 'admin.bulk-upload.index',
|
||||||
|
'sort' => 2,
|
||||||
|
'icon-class' => '',
|
||||||
|
], [
|
||||||
|
'key' => 'catalog.bulkupload.run-profile',
|
||||||
|
'name' => 'bulkupload::app.admin.bulk-upload.run-profile.index',
|
||||||
|
'route' => 'admin.run-profile.index',
|
||||||
|
'sort' => 3,
|
||||||
|
'icon-class' => '',
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'key' => 'bulkupload',
|
||||||
|
'name' => 'bulkupload::app.admin.system.bulkupload',
|
||||||
|
'sort' => 5
|
||||||
|
], [
|
||||||
|
'key' => 'bulkupload.settings',
|
||||||
|
'name' => 'bulkupload::app.admin.system.settings',
|
||||||
|
'sort' => 1,
|
||||||
|
], [
|
||||||
|
'key' => 'bulkupload.settings.general',
|
||||||
|
'name' => 'bulkupload::app.admin.system.general',
|
||||||
|
'sort' => 1,
|
||||||
|
'fields' => [
|
||||||
|
[
|
||||||
|
'name' => 'status',
|
||||||
|
'title' => 'bulkupload::app.admin.system.status',
|
||||||
|
'type' => 'boolean',
|
||||||
|
'channel_based' => true,
|
||||||
|
'locale_based' => false
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Contracts;
|
||||||
|
|
||||||
|
interface DataFlowProfile
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Contracts;
|
||||||
|
|
||||||
|
interface ImportProduct
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\DataGrids\Admin;
|
||||||
|
|
||||||
|
use DB;
|
||||||
|
use Webkul\Ui\DataGrid\DataGrid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Profile Datagrid class
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ProfileDataGrid extends DataGrid
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
protected $index = 'id';
|
||||||
|
|
||||||
|
public function prepareQueryBuilder()
|
||||||
|
{
|
||||||
|
$queryBuilder = DB::table('bulkupload_data_flow_profiles')
|
||||||
|
->leftJoin('attribute_families', 'bulkupload_data_flow_profiles.attribute_family_id', '=', 'attribute_families.id')
|
||||||
|
->select('bulkupload_data_flow_profiles.id',
|
||||||
|
'bulkupload_data_flow_profiles.name as profile_name', 'attribute_families.name', 'bulkupload_data_flow_profiles.locale_code', 'bulkupload_data_flow_profiles.created_at');
|
||||||
|
|
||||||
|
$this->addFilter('created_at', 'bulkupload_data_flow_profiles.created_at');
|
||||||
|
$this->addFilter('profile_name', 'bulkupload_data_flow_profiles.name');
|
||||||
|
$this->addFilter('name', 'attribute_families.name');
|
||||||
|
|
||||||
|
$this->setQueryBuilder($queryBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addColumns()
|
||||||
|
{
|
||||||
|
$this->addColumn([
|
||||||
|
'index' => 'profile_name',
|
||||||
|
'label' => trans('bulkupload::app.admin.bulk-upload.data-flow-profile.name'),
|
||||||
|
'type' => 'string',
|
||||||
|
'searchable' => true,
|
||||||
|
'sortable' => true,
|
||||||
|
'filterable' => true
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->addColumn([
|
||||||
|
'index' => 'name',
|
||||||
|
'label' => trans('admin::app.catalog.products.familiy'),
|
||||||
|
'type' => 'string',
|
||||||
|
'searchable' => true,
|
||||||
|
'sortable' => true,
|
||||||
|
'filterable' => true
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->addColumn([
|
||||||
|
'index' => 'locale_code',
|
||||||
|
'label' => trans('bulkupload::app.admin.bulk-upload.data-flow-profile.data-grid.locale_code'),
|
||||||
|
'type' => 'string',
|
||||||
|
'searchable' => true,
|
||||||
|
'sortable' => true,
|
||||||
|
'filterable' => true
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->addColumn([
|
||||||
|
'index' => 'created_at',
|
||||||
|
'label' => trans('bulkupload::app.admin.bulk-upload.data-flow-profile.data-grid.created-at'),
|
||||||
|
'type' => 'datetime',
|
||||||
|
'sortable' => true,
|
||||||
|
'searchable' => false,
|
||||||
|
'filterable' => true
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function prepareActions()
|
||||||
|
{
|
||||||
|
$this->addAction([
|
||||||
|
'type' => 'Edit',
|
||||||
|
'method' => 'GET',
|
||||||
|
'route' => 'bulkupload.admin.profile.edit',
|
||||||
|
'icon' => 'icon pencil-lg-icon',
|
||||||
|
'title' => ''
|
||||||
|
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->addAction([
|
||||||
|
'type' => trans('admin::app.datagrid.delete'),
|
||||||
|
'method' => 'POST',
|
||||||
|
'route' => 'bulkupload.admin.profile.delete',
|
||||||
|
'confirm_text' => trans('ui::app.datagrid.massaction.delete'),
|
||||||
|
'icon' => 'icon trash-icon',
|
||||||
|
'title' => ''
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->enableAction = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function prepareMassActions()
|
||||||
|
{
|
||||||
|
$this->addMassAction([
|
||||||
|
'type' => 'delete',
|
||||||
|
'label' => 'Delete',
|
||||||
|
'action' => route('bulkupload.admin.profile.massDelete'),
|
||||||
|
'method' => 'POST',
|
||||||
|
'title' => ''
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreateBulkuploadDataflowprofilesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('bulkupload_data_flow_profiles', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->string('name');
|
||||||
|
$table->integer('attribute_family_id')->unsigned();
|
||||||
|
$table->foreign('attribute_family_id', 'bulkupload_foreign_attribute_family_id')->references('id')->on('attribute_families')->onDelete('cascade');
|
||||||
|
$table->boolean('run_status')->default(0);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('bulkupload_data_flow_profiles');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateImportProductsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('import_products', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
|
||||||
|
$table->integer('attribute_family_id')->unsigned();
|
||||||
|
$table->foreign('attribute_family_id', 'import_admin_foreign_attribute_family_id')->references('id')->on('attribute_families')->onDelete('cascade');
|
||||||
|
|
||||||
|
$table->integer('data_flow_profile_id')->unsigned();
|
||||||
|
$table->foreign('data_flow_profile_id', 'import_admin_foreign_data_flow_profile_id')->references('id')->on('bulkupload_data_flow_profiles')->onDelete('cascade');
|
||||||
|
|
||||||
|
$table->boolean('is_downloadable')->default(0);
|
||||||
|
$table->string('upload_link_files');
|
||||||
|
|
||||||
|
$table->boolean('is_links_have_samples')->default(0);
|
||||||
|
$table->string('upload_link_sample_files');
|
||||||
|
|
||||||
|
$table->boolean('is_samples_available')->default(0);
|
||||||
|
$table->string('upload_sample_files');
|
||||||
|
|
||||||
|
$table->string('file_path');
|
||||||
|
$table->string('image_path');
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('import_products');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AlterBulkuploadDataFlowProfilesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('bulkupload_data_flow_profiles', function(Blueprint $table) {
|
||||||
|
$table->string('locale_code');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Helpers;
|
||||||
|
|
||||||
|
use Webkul\Bulkupload\Repositories\ImportProductRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\DataFlowProfileRepository;
|
||||||
|
|
||||||
|
class ImportProduct
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ImportProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ImportProductRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $importProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DataFlowProfileRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\DataFlowProfileRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $dataFlowProfileRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ImportProductRepository $importProductRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\DataFlowProfileRepository $dataFlowProfileRepository
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ImportProductRepository $importProductRepository,
|
||||||
|
DataFlowProfileRepository $dataFlowProfileRepository
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->importProductRepository = $importProductRepository;
|
||||||
|
|
||||||
|
$this->dataFlowProfileRepository = $dataFlowProfileRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* store import products for profile execution
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store()
|
||||||
|
{
|
||||||
|
request()->validate ([
|
||||||
|
'attribute_family' => 'required',
|
||||||
|
'file_path' => 'required',
|
||||||
|
'image_path' => 'mimetypes:application/zip|max:10000',
|
||||||
|
'data_flow_profile' => 'required',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$valid_extension = ['csv', 'xls', 'xlsx'];
|
||||||
|
$valid_image_extension = ['zip', 'rar'];
|
||||||
|
|
||||||
|
$imageDir = 'imported-products/admin/images';
|
||||||
|
$fileDir = 'imported-products/admin/files';
|
||||||
|
$linkFilesDir = 'imported-products/admin/link-files';
|
||||||
|
$linkSampleFilesDir = 'imported-products/admin/link-sample-files';
|
||||||
|
$sampleFileDir = 'imported-products/admin/sample-file';
|
||||||
|
|
||||||
|
$attribute_family_id = request()->attribute_family;
|
||||||
|
$data_flow_profile_id = request()->data_flow_profile;
|
||||||
|
|
||||||
|
$image = request()->file('image_path');
|
||||||
|
$file = request()->file('file_path');
|
||||||
|
$linkFiles = request()->file('link_files');
|
||||||
|
$linkSampleFiles = request()->file('link_sample_files');
|
||||||
|
$sampleFile = request()->file('sample_file');
|
||||||
|
|
||||||
|
if (! isset($image)) {
|
||||||
|
$image = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request()->is_downloadable) {
|
||||||
|
$product['is_downloadable'] = 1;
|
||||||
|
|
||||||
|
if (! empty($linkFiles) && in_array($linkFiles->getClientOriginalExtension(), $valid_image_extension)) {
|
||||||
|
$uploadedLinkFiles = $linkFiles->storeAs($linkFilesDir, uniqid().'.'.$linkFiles->getClientOriginalExtension());
|
||||||
|
|
||||||
|
$product['upload_link_files'] = $uploadedLinkFiles;
|
||||||
|
} else {
|
||||||
|
session()->flash('error', trans('bulkupload::app.admin.bulk-upload.messages.file-format-error'));
|
||||||
|
|
||||||
|
return redirect()->route('admin.bulk-upload.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request()->is_link_have_sample) {
|
||||||
|
$product['is_links_have_samples'] = 1;
|
||||||
|
|
||||||
|
if (in_array($linkSampleFiles->getClientOriginalExtension(), $valid_image_extension)) {
|
||||||
|
$uploadedLinkSampleFiles = $linkSampleFiles->storeAs($linkSampleFilesDir, uniqid().'.'.$linkSampleFiles->getClientOriginalExtension());
|
||||||
|
|
||||||
|
$product['upload_link_sample_files'] = $uploadedLinkSampleFiles;
|
||||||
|
} else {
|
||||||
|
session()->flash('error', trans('bulkupload::app.admin.bulk-upload.messages.file-format-error'));
|
||||||
|
|
||||||
|
return redirect()->route('admin.bulk-upload.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request()->is_sample) {
|
||||||
|
$product['is_samples_available'] = 1;
|
||||||
|
|
||||||
|
if (in_array($sampleFile->getClientOriginalExtension(), $valid_image_extension)) {
|
||||||
|
$uploadedSampleFiles = $sampleFile->storeAs($sampleFileDir, uniqid().'.'.$sampleFile->getClientOriginalExtension());
|
||||||
|
|
||||||
|
$product['upload_sample_files'] = $uploadedSampleFiles;
|
||||||
|
} else {
|
||||||
|
session()->flash('error', trans('bulkupload::app.admin.bulk-upload.messages.file-format-error'));
|
||||||
|
|
||||||
|
return redirect()->route('admin.bulk-upload.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$product['data_flow_profile_id'] = $data_flow_profile_id;
|
||||||
|
$product['attribute_family_id'] = $attribute_family_id;
|
||||||
|
|
||||||
|
if ((! empty($image) && in_array($image->getClientOriginalExtension(), $valid_image_extension)) && (in_array($file->getClientOriginalExtension(), $valid_extension))) {
|
||||||
|
$uploadedImage = $image->storeAs($imageDir, uniqid().'.'.$image->getClientOriginalExtension());
|
||||||
|
|
||||||
|
$product['image_path'] = $uploadedImage;
|
||||||
|
|
||||||
|
$uploadedFile = $file->storeAs($fileDir, uniqid().'.'.$file->getClientOriginalExtension());
|
||||||
|
|
||||||
|
$product['file_path'] = $uploadedFile;
|
||||||
|
} else if ( empty($image) && (in_array($file->getClientOriginalExtension(), $valid_extension))) {
|
||||||
|
$product['image_path'] = '';
|
||||||
|
|
||||||
|
$uploadedFile = $file->storeAs($fileDir, uniqid().'.'.$file->getClientOriginalExtension());
|
||||||
|
|
||||||
|
$product['file_path'] = $uploadedFile;
|
||||||
|
} else {
|
||||||
|
session()->flash('error', trans('bulkupload::app.admin.bulk-upload.messages.file-format-error'));
|
||||||
|
|
||||||
|
return redirect()->route('admin.bulk-upload.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->importProductRepository->findOneByField('data_flow_profile_id', $data_flow_profile_id);
|
||||||
|
|
||||||
|
if ($data) {
|
||||||
|
$this->dataFlowProfileRepository->update(['run_status' => '0'], $data_flow_profile_id);
|
||||||
|
|
||||||
|
$this->importProductRepository->Update($product, $data->id);
|
||||||
|
|
||||||
|
session()->flash('success',trans('bulkupload::app.admin.bulk-upload.messages.update-profile'));
|
||||||
|
|
||||||
|
return redirect()->route('admin.bulk-upload.index');
|
||||||
|
} else {
|
||||||
|
$importNewProductsStore = $this->importProductRepository->create($product);
|
||||||
|
|
||||||
|
session()->flash('success',trans('bulkupload::app.admin.bulk-upload.messages.profile-saved'));
|
||||||
|
|
||||||
|
return redirect()->route('admin.bulk-upload.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,188 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use Webkul\Attribute\Repositories\AttributeFamilyRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ImportProductRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\DataFlowProfileRepository;
|
||||||
|
|
||||||
|
class BulkUploadController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* DataFlowProfileRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\DataFlowProfileRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $dataFlowProfileRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeFamilyRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeFamilyRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $attributeFamilyRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ImportProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ImportProductRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $importProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $product = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains route related configuration
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $_config;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\DataFlowProfileRepository $dataFlowProfileRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ImportProductRepository $importProductRepository
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
AttributeFamilyRepository $attributeFamilyRepository,
|
||||||
|
DataFlowProfileRepository $dataFlowProfileRepository,
|
||||||
|
ImportProductRepository $importProductRepository
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->_config = request('_config');
|
||||||
|
|
||||||
|
$this->attributeFamilyRepository = $attributeFamilyRepository;
|
||||||
|
|
||||||
|
$this->importProductRepository = $importProductRepository;
|
||||||
|
|
||||||
|
$this->dataFlowProfileRepository = $dataFlowProfileRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$profiles = null;
|
||||||
|
$families = $this->attributeFamilyRepository->all();
|
||||||
|
$allProfiles = $this->importProductRepository->get()->toArray();
|
||||||
|
|
||||||
|
if (! empty($allProfiles)) {
|
||||||
|
foreach ($allProfiles as $allProfile) {
|
||||||
|
$profilers[] = $allProfile['data_flow_profile_id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($profilers as $key => $profiler) {
|
||||||
|
$profiles[] = $this->dataFlowProfileRepository->findByfield(['id' => $profilers[$key], 'run_status' => '0']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return view($this->_config['view'], compact('families', 'profiles'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store()
|
||||||
|
{
|
||||||
|
request()->validate([
|
||||||
|
'name' => 'required|unique:bulkupload_data_flow_profiles',
|
||||||
|
'attribute_family' => 'required',
|
||||||
|
'locale_code' => 'required'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$dataFlowProfileAdmin['name'] = request()->name;
|
||||||
|
$dataFlowProfileAdmin['attribute_family_id'] = request()->attribute_family;
|
||||||
|
$dataFlowProfileAdmin['locale_code'] = request()->locale_code;
|
||||||
|
|
||||||
|
|
||||||
|
$this->dataFlowProfileRepository->create($dataFlowProfileAdmin);
|
||||||
|
|
||||||
|
session()->flash('success',trans('bulkupload::app.admin.bulk-upload.messages.profile-saved'));
|
||||||
|
|
||||||
|
return redirect()->route('admin.dataflow-profile.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function edit($id)
|
||||||
|
{
|
||||||
|
$families = $this->attributeFamilyRepository->all();
|
||||||
|
$profiles = $this->dataFlowProfileRepository->findOrFail($id);
|
||||||
|
|
||||||
|
return view($this->_config['view'], compact('families', 'profiles'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function update($id)
|
||||||
|
{
|
||||||
|
$product = $this->dataFlowProfileRepository->update(request()->except('_token'), $id);
|
||||||
|
$families = $this->attributeFamilyRepository->all();
|
||||||
|
$profiles = $this->dataFlowProfileRepository->findOrFail($id);
|
||||||
|
|
||||||
|
session()->flash('success', trans('admin::app.response.update-success', ['name' => 'Product']));
|
||||||
|
|
||||||
|
return redirect()->route('admin.dataflow-profile.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$product = $this->dataFlowProfileRepository->findOrFail($id)->delete();
|
||||||
|
|
||||||
|
session()->flash('success',trans('bulkupload::app.admin.bulk-upload.messages.profile-deleted'));
|
||||||
|
|
||||||
|
return response()->json(['message' => true], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mass Delete the dataflowprofiles
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function massDestroy()
|
||||||
|
{
|
||||||
|
$profileIds = explode(',', request()->input('indexes'));
|
||||||
|
|
||||||
|
foreach ($profileIds as $profileId) {
|
||||||
|
$profile = $this->dataFlowProfileRepository->find($profileId);
|
||||||
|
|
||||||
|
if (isset($profile)) {
|
||||||
|
$this->dataFlowProfileRepository->delete($profileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session()->flash('success', trans('admin::app.catalog.products.mass-delete-success'));
|
||||||
|
|
||||||
|
return redirect()->route($this->_config['redirect']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
|
use Illuminate\Routing\Controller as BaseController;
|
||||||
|
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
|
|
||||||
|
class Controller extends BaseController
|
||||||
|
{
|
||||||
|
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,341 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use Webkul\Admin\Imports\DataGridImport;
|
||||||
|
use Maatwebsite\Excel\Validators\Failure;
|
||||||
|
use Webkul\Bulkupload\Helpers\ImportProduct;
|
||||||
|
use Webkul\Bulkupload\Repositories\ImportProductRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\DataFlowProfileRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\SimpleProductRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\ConfigurableProductRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\VirtualProductRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\DownloadableProductRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\GroupedProductRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\BundledProductRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\BookingProductRepository;
|
||||||
|
|
||||||
|
class HelperController extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SimpleProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\SimpleProductRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $simpleProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConfigurableProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\ConfigurableProductRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $configurableProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VirtualProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\VirtualProductRepository;
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $virtualProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DownloadableProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\DownloadableProductRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $downloadableProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BundledProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\BundledProductRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $bundledProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BookingProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\BookingProductRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $bookingProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GroupedProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\GroupedProductRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $groupedProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DataFlowProfileRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\DataFlowProfileRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $dataFlowProfileRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ImportProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ImportProductRepository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $importProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $product = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ImportProduct helper
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Helpers\ImportProduct
|
||||||
|
*/
|
||||||
|
protected $importProduct;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ImportProductRepository $importProductRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\DataFlowProfileRepository $dataFlowProfileRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\SimpleProductRepository $simpleProductRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\ConfigurableProductRepository $configurableProductRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\VirtualProductRepository $virtualProductRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\DownloadableProductRepository $downloadableProductRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\BundledProductRepository $bundledProductRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\BookingProductRepository $bookingProductRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\GroupedProductRepository $groupedProductRepository
|
||||||
|
* @param \Webkul\Bulkupload\Helpers\ImportProduct $importProduct
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ImportProductRepository $importProductRepository,
|
||||||
|
DataFlowProfileRepository $dataFlowProfileRepository,
|
||||||
|
SimpleProductRepository $simpleProductRepository,
|
||||||
|
ConfigurableProductRepository $configurableProductRepository,
|
||||||
|
VirtualProductRepository $virtualProductRepository,
|
||||||
|
DownloadableProductRepository $downloadableProductRepository,
|
||||||
|
BundledProductRepository $bundledProductRepository,
|
||||||
|
BookingProductRepository $bookingProductRepository,
|
||||||
|
GroupedProductRepository $groupedProductRepository,
|
||||||
|
ImportProduct $importProduct
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->importProductRepository = $importProductRepository;
|
||||||
|
|
||||||
|
$this->dataFlowProfileRepository = $dataFlowProfileRepository;
|
||||||
|
|
||||||
|
$this->simpleProductRepository = $simpleProductRepository;
|
||||||
|
|
||||||
|
$this->configurableProductRepository = $configurableProductRepository;
|
||||||
|
|
||||||
|
$this->virtualProductRepository = $virtualProductRepository;
|
||||||
|
|
||||||
|
$this->downloadableProductRepository = $downloadableProductRepository;
|
||||||
|
|
||||||
|
$this->bundledProductRepository = $bundledProductRepository;
|
||||||
|
|
||||||
|
$this->bookingProductRepository = $bookingProductRepository;
|
||||||
|
|
||||||
|
$this->groupedProductRepository = $groupedProductRepository;
|
||||||
|
|
||||||
|
$this->importProduct = $importProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download sample files.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function downloadFile()
|
||||||
|
{
|
||||||
|
$items = [];
|
||||||
|
|
||||||
|
foreach (config('product_types') as $item) {
|
||||||
|
$item['children'] = [];
|
||||||
|
|
||||||
|
array_push($items, $item);
|
||||||
|
}
|
||||||
|
|
||||||
|
$types = core()->sortItems($items);
|
||||||
|
|
||||||
|
foreach ($types as $key => $productType) {
|
||||||
|
if (request()->download_sample == $key.'-csv') {
|
||||||
|
return response()->download(public_path('storage/downloads/sample-files/bulk'.$key.'productupload.csv'));
|
||||||
|
} else if (request()->download_sample == $key.'-xls') {
|
||||||
|
return response()->download(public_path('storage/downloads/sample-files/bulk'.$key.'productupload.xlsx'));
|
||||||
|
} else if (empty(request()->download_sample)) {
|
||||||
|
return redirect()->back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get profiles on basis of attribute family
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAllDataFlowProfiles()
|
||||||
|
{
|
||||||
|
$attribute_family_id = request()->attribute_family_id;
|
||||||
|
|
||||||
|
$dataFlowProfiles = $this->dataFlowProfileRepository->findByField('attribute_family_id', request()->attribute_family_id);
|
||||||
|
|
||||||
|
return ['dataFlowProfiles' => $dataFlowProfiles];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read count of records in CSV/XLSX
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function readCSVData()
|
||||||
|
{
|
||||||
|
$countCSV = 0;
|
||||||
|
|
||||||
|
$dataFlowProfileRecord = $this->importProductRepository->findOneByField('data_flow_profile_id', request()->data_flow_profile_id);
|
||||||
|
|
||||||
|
$this->dataFlowProfileRepository->update(['run_status' => '1'], request()->data_flow_profile_id);
|
||||||
|
|
||||||
|
if ($dataFlowProfileRecord) {
|
||||||
|
$csvData = (new DataGridImport)->toArray($dataFlowProfileRecord->file_path)[0];
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($csvData); $i++) {
|
||||||
|
if ($csvData[$i]['type'] == 'configurable') {
|
||||||
|
$countCSV += 1;
|
||||||
|
} else if ($csvData[0]['type'] != 'configurable') {
|
||||||
|
$countCSV = count($csvData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $countCSV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* store import products for profile execution
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function importNewProductsStore()
|
||||||
|
{
|
||||||
|
$dataFlowProfileId = request()->data_flow_profile;
|
||||||
|
|
||||||
|
if ($dataFlowProfileId) {
|
||||||
|
$importedProducts = $this->importProduct->store();
|
||||||
|
|
||||||
|
return $importedProducts;
|
||||||
|
} else {
|
||||||
|
session()->flash('error', trans('bulkupload::app.admin.bulk-upload.messages.data-profile-not-selected'));
|
||||||
|
|
||||||
|
return back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* profile execution to upload products
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function runProfile()
|
||||||
|
{
|
||||||
|
$data_flow_profile_id = request()->data_flow_profile_id;
|
||||||
|
$numberOfCSVRecord = request()->numberOfCSVRecord;
|
||||||
|
$countOfStartedProfiles = request()->countOfStartedProfiles;
|
||||||
|
$product = [];
|
||||||
|
$imageZipName = null;
|
||||||
|
|
||||||
|
$dataFlowProfileRecord = $this->importProductRepository->findOneByField
|
||||||
|
('data_flow_profile_id', $data_flow_profile_id);
|
||||||
|
|
||||||
|
if ($dataFlowProfileRecord) {
|
||||||
|
$csvData = (new DataGridImport)->toArray($dataFlowProfileRecord->file_path)[0];
|
||||||
|
|
||||||
|
if (isset($dataFlowProfileRecord->image_path) && ($dataFlowProfileRecord->image_path != "") ) {
|
||||||
|
$imageZipName = $this->storeImageZip($dataFlowProfileRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($numberOfCSVRecord >= 0) {
|
||||||
|
for ($i = $countOfStartedProfiles; $i < count($csvData); $i++) {
|
||||||
|
$product['loopCount'] = $i;
|
||||||
|
|
||||||
|
switch($csvData[$i]['type']) {
|
||||||
|
case "simple":
|
||||||
|
$simpleProduct = $this->simpleProductRepository->createProduct(request()->all(), $imageZipName, $product);
|
||||||
|
|
||||||
|
return response()->json($simpleProduct);
|
||||||
|
|
||||||
|
case "virtual":
|
||||||
|
$virtualProduct = $this->virtualProductRepository->createProduct(request()->all(), $imageZipName);
|
||||||
|
|
||||||
|
return response()->json($virtualProduct);
|
||||||
|
case "downloadable":
|
||||||
|
$downloadableProduct = $this->downloadableProductRepository->createProduct(request()->all(), $imageZipName);
|
||||||
|
|
||||||
|
return response()->json($downloadableProduct);
|
||||||
|
case "grouped":
|
||||||
|
$groupedProduct = $this->groupedProductRepository->createProduct(request()->all(), $imageZipName);
|
||||||
|
|
||||||
|
return response()->json($groupedProduct);
|
||||||
|
case "booking":
|
||||||
|
$bookingProduct = $this->bookingProductRepository->createProduct(request()->all(), $imageZipName);
|
||||||
|
|
||||||
|
return response()->json($bookingProduct);
|
||||||
|
case "bundle":
|
||||||
|
$bundledProduct = $this->bundledProductRepository->createProduct(request()->all(), $imageZipName);
|
||||||
|
|
||||||
|
return response()->json($bundledProduct);
|
||||||
|
case "configurable" OR "variant":
|
||||||
|
$configurableProduct = $this->configurableProductRepository->createProduct(request()->all(), $imageZipName, $product);
|
||||||
|
|
||||||
|
return response()->json($configurableProduct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response()->json([
|
||||||
|
"success" => true,
|
||||||
|
"message" => "CSV Product Successfully Imported"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function storeImageZip($dataFlowProfileRecord)
|
||||||
|
{
|
||||||
|
$imageZip = new \ZipArchive();
|
||||||
|
|
||||||
|
$extractedPath = storage_path('app/public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id.'/');
|
||||||
|
|
||||||
|
if ($imageZip->open(storage_path('app/public/'.$dataFlowProfileRecord->image_path))) {
|
||||||
|
for ($i = 0; $i < $imageZip->numFiles; $i++) {
|
||||||
|
$filename = $imageZip->getNameIndex($i);
|
||||||
|
$imageZipName = pathinfo($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageZip->extractTo($extractedPath);
|
||||||
|
$imageZip->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
$listOfImages = scandir($extractedPath.$imageZipName['dirname'].'/');
|
||||||
|
|
||||||
|
foreach ($listOfImages as $key => $imageName) {
|
||||||
|
if (preg_match_all('/[\'"]/', $imageName)) {
|
||||||
|
$fileName = preg_replace('/[\'"]/', '',$imageName);
|
||||||
|
|
||||||
|
rename($extractedPath.$imageZipName['dirname'].'/'.$imageName, $extractedPath.$imageZipName['dirname'].'/'.$fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $imageZipName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
Route::group(['middleware' => ['web']], function () {
|
||||||
|
|
||||||
|
Route::prefix(config('app.admin_url'))->group(function () {
|
||||||
|
|
||||||
|
Route::group(['middleware' => ['admin']], function () {
|
||||||
|
Route::prefix('bulkupload')->group(function () {
|
||||||
|
|
||||||
|
// Bulk Upload Products
|
||||||
|
Route::get('/upload-files', 'Webkul\Bulkupload\Http\Controllers\Admin\BulkUploadController@index')->defaults('_config', [
|
||||||
|
'view' => 'bulkupload::admin.bulk-upload.upload-files.index'
|
||||||
|
])->name('admin.bulk-upload.index');
|
||||||
|
|
||||||
|
Route::get('/run-profile', 'Webkul\Bulkupload\Http\Controllers\Admin\BulkUploadController@index')->defaults('_config', [
|
||||||
|
'view' => 'bulkupload::admin.bulk-upload.run-profile.index'
|
||||||
|
])->name('admin.run-profile.index');
|
||||||
|
|
||||||
|
Route::post('/read-csv', 'Webkul\Bulkupload\Http\Controllers\Admin\HelperController@readCSVData')
|
||||||
|
->name('bulk-upload-admin.read-csv');
|
||||||
|
|
||||||
|
Route::post('/getprofiles', 'Webkul\Bulkupload\Http\Controllers\Admin\HelperController@getAllDataFlowProfiles')
|
||||||
|
->name('bulk-upload-admin.get-all-profile');
|
||||||
|
|
||||||
|
// Download Sample Files
|
||||||
|
Route::post('/download','Webkul\Bulkupload\Http\Controllers\Admin\HelperController@downloadFile')->defaults('_config',[
|
||||||
|
'view' => 'bulkupload::admin.bulk-upload.upload-files.index'
|
||||||
|
])->name('download-sample-files');
|
||||||
|
|
||||||
|
// import new products
|
||||||
|
Route::post('/importnew', 'Webkul\Bulkupload\Http\Controllers\Admin\HelperController@importNewProductsStore')->defaults('_config',['view' => 'bulkupload::admin.bulk-upload.upload-files.index' ])->name('import-new-products-form-submit');
|
||||||
|
|
||||||
|
Route::prefix('dataflowprofile')->group(function () {
|
||||||
|
Route::get('/', 'Webkul\Bulkupload\Http\Controllers\Admin\BulkUploadController@index')->defaults('_config', [
|
||||||
|
'view' => 'bulkupload::admin.bulk-upload.data-flow-profile.index'
|
||||||
|
])->name('admin.dataflow-profile.index');
|
||||||
|
|
||||||
|
Route::post('/addprofile', 'Webkul\Bulkupload\Http\Controllers\Admin\BulkUploadController@store')->defaults('_config', [
|
||||||
|
'view' => 'bulkupload::admin.bulk-upload.data-flow-profile.index'
|
||||||
|
])->name('bulkupload.bulk-upload.dataflow.add-profile');
|
||||||
|
|
||||||
|
Route::post('/runprofile', 'Webkul\Bulkupload\Http\Controllers\Admin\HelperController@runProfile')->defaults('_config', [
|
||||||
|
'view' => 'bulkupload::admin.bulk-upload.run-profile.progressbar'
|
||||||
|
])->name('bulk-upload-admin.run-profile');
|
||||||
|
|
||||||
|
// edit actions
|
||||||
|
Route::post('/delete/{id}','Webkul\Bulkupload\Http\Controllers\Admin\BulkUploadController@destroy')->name('bulkupload.admin.profile.delete');
|
||||||
|
|
||||||
|
Route::get('/edit/{id}', 'Webkul\Bulkupload\Http\Controllers\Admin\BulkUploadController@edit')->defaults('_config', [
|
||||||
|
'view' => 'bulkupload::admin.bulk-upload.data-flow-profile.edit'
|
||||||
|
])->name('bulkupload.admin.profile.edit');
|
||||||
|
|
||||||
|
Route::post('/update/{id}', 'Webkul\Bulkupload\Http\Controllers\Admin\BulkUploadController@update')->defaults('_config', [
|
||||||
|
'view' => 'bulkupload::admin.bulk-upload.data-flow-profile.index'
|
||||||
|
])->name('admin.bulk-upload.dataflow.update-profile');
|
||||||
|
|
||||||
|
//mass destroy
|
||||||
|
Route::post('/massdestroy', 'Webkul\Bulkupload\Http\Controllers\Admin\BulkUploadController@massDestroy')->defaults('_config', [
|
||||||
|
'redirect' => 'admin.dataflow-profile.index'
|
||||||
|
])->name('bulkupload.admin.profile.massDelete');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Webkul\Bulkupload\Contracts\DataFlowProfile as DataFlowProfileContract;
|
||||||
|
use Webkul\Attribute\Models\AttributeFamily;
|
||||||
|
|
||||||
|
|
||||||
|
class DataFlowProfile extends Model implements DataFlowProfileContract
|
||||||
|
{
|
||||||
|
protected $guarded = [];
|
||||||
|
|
||||||
|
protected $table = "bulkupload_data_flow_profiles";
|
||||||
|
|
||||||
|
public function attribute_family()
|
||||||
|
{
|
||||||
|
return $this->hasOne(AttributeFamily::class, 'id', 'attribute_family_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Models;
|
||||||
|
|
||||||
|
use Konekt\Concord\Proxies\ModelProxy;
|
||||||
|
|
||||||
|
class DataFlowProfileProxy extends ModelProxy
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Webkul\Bulkupload\Contracts\ImportProduct as ImportProductContract;
|
||||||
|
|
||||||
|
class ImportProduct extends Model implements ImportProductContract
|
||||||
|
{
|
||||||
|
protected $table = "import_products";
|
||||||
|
|
||||||
|
protected $guarded = [];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Models;
|
||||||
|
|
||||||
|
use Konekt\Concord\Proxies\ModelProxy;
|
||||||
|
|
||||||
|
class ImportProductProxy extends ModelProxy
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class BulkUploadServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
include __DIR__ . '/../Http/admin-routes.php';
|
||||||
|
|
||||||
|
$this->app->register(ModuleServiceProvider::class);
|
||||||
|
$this->app->register(EventServiceProvider::class);
|
||||||
|
|
||||||
|
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
|
||||||
|
|
||||||
|
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'bulkupload');
|
||||||
|
|
||||||
|
$this->loadViewsFrom(__DIR__ . '/../Resources/views', 'bulkupload');
|
||||||
|
|
||||||
|
$this->publishes([
|
||||||
|
__DIR__ . '/../../publishable/assets' => public_path('themes/default/assets'),
|
||||||
|
], 'public');
|
||||||
|
|
||||||
|
$this->publishes([
|
||||||
|
__DIR__ . '/../Resources/views/admin/bulk-upload/layouts/nav-aside.blade.php' => resource_path('views/vendor/admin/layouts/nav-aside.blade.php'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
view()->composer(['bulkupload::admin.bulk-upload.upload-files.index'], function ($view) {
|
||||||
|
$items = [];
|
||||||
|
|
||||||
|
foreach (config('product_types') as $item) {
|
||||||
|
$item['children'] = [];
|
||||||
|
|
||||||
|
array_push($items, $item);
|
||||||
|
}
|
||||||
|
|
||||||
|
$types = core()->sortItems($items);
|
||||||
|
|
||||||
|
$view->with('productTypes', $types);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
$this->registerConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register package config.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function registerConfig()
|
||||||
|
{
|
||||||
|
$this->mergeConfigFrom(
|
||||||
|
dirname(__DIR__) . '/Config/system.php', 'core'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->mergeConfigFrom(
|
||||||
|
dirname(__DIR__) . '/Config/admin-menu.php', 'menu.admin'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
use Illuminate\Support\Facades\Event;
|
||||||
|
|
||||||
|
class EventServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Bootstrap services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
Event::listen('bagisto.admin.layout.head', function($viewRenderEventManager) {
|
||||||
|
$viewRenderEventManager->addTemplate('bulkupload::admin.bulk-upload.style');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Providers;
|
||||||
|
|
||||||
|
use Konekt\Concord\BaseModuleServiceProvider;
|
||||||
|
|
||||||
|
class ModuleServiceProvider extends BaseModuleServiceProvider
|
||||||
|
{
|
||||||
|
protected $models = [
|
||||||
|
\Webkul\Bulkupload\Models\ImportProduct::class,
|
||||||
|
\Webkul\Bulkupload\Models\DataFlowProfile::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Repositories;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Illuminate\Support\Facades\Event;
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
use Webkul\Product\Models\ProductAttributeValue;
|
||||||
|
use Webkul\Product\Repositories\ProductRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductImageRepository;
|
||||||
|
|
||||||
|
class BulkProductRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductRepository
|
||||||
|
*/
|
||||||
|
protected $productRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductAttributeValueRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductAttributeValueRepository
|
||||||
|
*/
|
||||||
|
protected $productAttributeValueRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductInventoryRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductInventoryRepository
|
||||||
|
*/
|
||||||
|
protected $productInventoryRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductImageRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductImageRepository
|
||||||
|
*/
|
||||||
|
protected $productImageRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new repository instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $productAttributeValueRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ProductRepository $productRepository,
|
||||||
|
ProductAttributeValueRepository $productAttributeValueRepository,
|
||||||
|
ProductInventoryRepository $productInventoryRepository,
|
||||||
|
ProductImageRepository $productImageRepository,
|
||||||
|
App $app)
|
||||||
|
{
|
||||||
|
$this->productAttributeValueRepository = $productAttributeValueRepository;
|
||||||
|
|
||||||
|
$this->productRepository = $productRepository;
|
||||||
|
|
||||||
|
$this->productInventoryRepository = $productInventoryRepository;
|
||||||
|
|
||||||
|
$this->productImageRepository = $productImageRepository;
|
||||||
|
|
||||||
|
parent::__construct($app);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Product\Contracts\Product';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update configurable product variants
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @param integer $id
|
||||||
|
* @param string $attribute
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function productRepositoryUpdateForVariants(array $data, $id, $attribute = "id")
|
||||||
|
{
|
||||||
|
Event::dispatch('catalog.product.update.before', $id);
|
||||||
|
|
||||||
|
$product = $this->find($id);
|
||||||
|
|
||||||
|
$configurable = app('Webkul\Product\Type\Configurable');
|
||||||
|
|
||||||
|
if ($product->parent_id && $configurable->checkVariantOptionAvailabiliy($data, $product)) {
|
||||||
|
$data['parent_id'] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
$product->update($data);
|
||||||
|
|
||||||
|
$attributes = $product->attribute_family->custom_attributes;
|
||||||
|
|
||||||
|
foreach ($attributes as $attribute) {
|
||||||
|
if (! isset($data[$attribute->code]) || (in_array($attribute->type, ['date', 'datetime']) && ! $data[$attribute->code]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ($attribute->type == 'multiselect' || $attribute->type == 'checkbox') {
|
||||||
|
$data[$attribute->code] = implode(",", $data[$attribute->code]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($attribute->type == 'image' || $attribute->type == 'file') {
|
||||||
|
$dir = 'product';
|
||||||
|
if (gettype($data[$attribute->code]) == 'object') {
|
||||||
|
$data[$attribute->code] = request()->file($attribute->code)->store($dir);
|
||||||
|
} else {
|
||||||
|
$data[$attribute->code] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$attributeValue = $this->productAttributeValueRepository->findOneWhere([
|
||||||
|
'product_id' => $product->id,
|
||||||
|
'attribute_id' => $attribute->id,
|
||||||
|
'channel' => $attribute->value_per_channel ? $data['channel'] : null,
|
||||||
|
'locale' => $attribute->value_per_locale ? $data['locale'] : null
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (! $attributeValue) {
|
||||||
|
$this->productAttributeValueRepository->create([
|
||||||
|
'product_id' => $product->id,
|
||||||
|
'attribute_id' => $attribute->id,
|
||||||
|
'value' => $data[$attribute->code],
|
||||||
|
'channel' => $attribute->value_per_channel ? $data['channel'] : null,
|
||||||
|
'locale' => $attribute->value_per_locale ? $data['locale'] : null
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$this->productAttributeValueRepository->update([
|
||||||
|
ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code]
|
||||||
|
], $attributeValue->id
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($attribute->type == 'image' || $attribute->type == 'file') {
|
||||||
|
Storage::delete($attributeValue->text_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request()->route()->getName() != 'admin.catalog.products.massupdate') {
|
||||||
|
if (isset($data['categories'])) {
|
||||||
|
$product->categories()->sync($data['categories']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($data['up_sell'])) {
|
||||||
|
$product->up_sells()->sync($data['up_sell']);
|
||||||
|
} else {
|
||||||
|
$data['up_sell'] = [];
|
||||||
|
$product->up_sells()->sync($data['up_sell']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($data['cross_sell'])) {
|
||||||
|
$product->cross_sells()->sync($data['cross_sell']);
|
||||||
|
} else {
|
||||||
|
$data['cross_sell'] = [];
|
||||||
|
$product->cross_sells()->sync($data['cross_sell']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($data['related_products'])) {
|
||||||
|
$product->related_products()->sync($data['related_products']);
|
||||||
|
} else {
|
||||||
|
$data['related_products'] = [];
|
||||||
|
$product->related_products()->sync($data['related_products']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$previousVariantIds = $product->variants->pluck('id');
|
||||||
|
if (isset($data['variants'])) {
|
||||||
|
foreach ($data['variants'] as $variantId => $variantData) {
|
||||||
|
if (str_contains($variantId, 'variant_')) {
|
||||||
|
$permutation = [];
|
||||||
|
foreach ($product->super_attributes as $superAttribute) {
|
||||||
|
$permutation[$superAttribute->id] = $variantData[$superAttribute->code];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->productRepository>createVariant($product, $permutation, $variantData);
|
||||||
|
} else {
|
||||||
|
if (is_numeric($index = $previousVariantIds->search($variantId))) {
|
||||||
|
$previousVariantIds->forget($index);
|
||||||
|
}
|
||||||
|
|
||||||
|
$variantData['channel'] = $data['channel'];
|
||||||
|
$variantData['locale'] = $data['locale'];
|
||||||
|
|
||||||
|
$this->productRepository->updateVariant($variantData, $variantId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->productInventoryRepository->saveInventories($data, $product);
|
||||||
|
|
||||||
|
$this->productImageRepository->uploadImages($data, $product);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($data['channels'])) {
|
||||||
|
$product['channels'] = $data['channels'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Event::dispatch('catalog.product.update.after', $product);
|
||||||
|
|
||||||
|
return $product;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Repositories;
|
||||||
|
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DataFlowProfile Repository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class DataFlowProfileRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Bulkupload\Contracts\DataFlowProfile';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Repositories;
|
||||||
|
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import Products Reposotory
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ImportProductRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Bulkupload\Contracts\ImportProduct';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Repositories;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Product Image Repository
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ProductImageRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Product\Contracts\ProductImage';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @param mixed $product
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function uploadImages($data, $product)
|
||||||
|
{
|
||||||
|
$previousImageIds = $product->images()->pluck('id');
|
||||||
|
|
||||||
|
if (isset($data['images'])) {
|
||||||
|
foreach ($data['images'] as $imageId => $image) {
|
||||||
|
$file = 'images.' . $imageId;
|
||||||
|
$dir = 'product/' . $product->id;
|
||||||
|
|
||||||
|
if (str_contains($imageId, 'image_')) {
|
||||||
|
if (request()->hasFile($file)) {
|
||||||
|
$this->create([
|
||||||
|
'path' => request()->file($file)->store($dir),
|
||||||
|
'product_id' => $product->id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (is_numeric($index = $previousImageIds->search($imageId))) {
|
||||||
|
$previousImageIds->forget($index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request()->hasFile($file)) {
|
||||||
|
if ($imageModel = $this->find($imageId)) {
|
||||||
|
Storage::delete($imageModel->path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->update([
|
||||||
|
'path' => request()->file($file)->store($dir)
|
||||||
|
], $imageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($previousImageIds as $imageId) {
|
||||||
|
if ($imageModel = $this->find($imageId)) {
|
||||||
|
Storage::delete($imageModel->path);
|
||||||
|
|
||||||
|
$this->delete($imageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @param mixed $product
|
||||||
|
* @param array $imageZipName
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function bulkuploadImages($data, $product, $imageZipName)
|
||||||
|
{
|
||||||
|
if (isset($data['images'])) {
|
||||||
|
foreach($data['images'] as $key => $value) {
|
||||||
|
if ( ! is_null($imageZipName)) {
|
||||||
|
$files = "imported-products/extracted-images/admin/".$data['dataFlowProfileRecordId'].'/'. $imageZipName['dirname'].'/'.basename($value);
|
||||||
|
} else {
|
||||||
|
$files = "imported-products/extracted-images/admin/".$data['dataFlowProfileRecordId'].'/'.basename($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$destination = "product/".$product->id.'/'.basename($value);
|
||||||
|
|
||||||
|
Storage::copy($files, $destination);
|
||||||
|
|
||||||
|
$this->create([
|
||||||
|
'path' => 'product/' . $product->id .'/'. basename($value),
|
||||||
|
'product_id' => $product->id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,404 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Repositories\Products;
|
||||||
|
|
||||||
|
use Storage;
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
use Webkul\Admin\Imports\DataGridImport;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Webkul\Category\Repositories\CategoryRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ImportProductRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductFlatRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeFamilyRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\HelperRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ProductImageRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeOptionRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductCustomerGroupPriceRepository;
|
||||||
|
|
||||||
|
class BundledProductRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ImportProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ImportProductRepository
|
||||||
|
*/
|
||||||
|
protected $importProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CategoryRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Category\Repositories\CategoryRepository
|
||||||
|
*/
|
||||||
|
protected $categoryRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductFlatRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductFlatRepository
|
||||||
|
*/
|
||||||
|
protected $productFlatRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductRepository
|
||||||
|
*/
|
||||||
|
protected $productRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeFamilyRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeFamilyRepository
|
||||||
|
*/
|
||||||
|
protected $attributeFamilyRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HelperRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\HelperRepository
|
||||||
|
*/
|
||||||
|
protected $helperRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductImageRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ProductImageRepository
|
||||||
|
*/
|
||||||
|
protected $productImageRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeOptionRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeOptionRepository
|
||||||
|
*/
|
||||||
|
protected $attributeOptionRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new repository instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ImportProductRepository $importProductRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeOptionRepository $attributeOptionRepository
|
||||||
|
* @param \Webkul\Category\Repositories\CategoryRepository $categoryRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductFlatRepository $productFlatRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\HelperRepository $helperRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ProductImageRepository $productImageRepository
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ImportProductRepository $importProductRepository,
|
||||||
|
CategoryRepository $categoryRepository,
|
||||||
|
ProductFlatRepository $productFlatRepository,
|
||||||
|
ProductRepository $productRepository,
|
||||||
|
AttributeFamilyRepository $attributeFamilyRepository,
|
||||||
|
HelperRepository $helperRepository,
|
||||||
|
ProductImageRepository $productImageRepository,
|
||||||
|
AttributeOptionRepository $attributeOptionRepository
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->importProductRepository = $importProductRepository;
|
||||||
|
|
||||||
|
$this->categoryRepository = $categoryRepository;
|
||||||
|
|
||||||
|
$this->productFlatRepository = $productFlatRepository;
|
||||||
|
|
||||||
|
$this->productRepository = $productRepository;
|
||||||
|
|
||||||
|
$this->productImageRepository = $productImageRepository;
|
||||||
|
|
||||||
|
$this->attributeFamilyRepository = $attributeFamilyRepository;
|
||||||
|
|
||||||
|
$this->helperRepository = $helperRepository;
|
||||||
|
|
||||||
|
$this->attributeOptionRepository = $attributeOptionRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Product\Contracts\Product';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create & update bundled-type product
|
||||||
|
*
|
||||||
|
* @param array $requestData
|
||||||
|
* @param array $imageZipName
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function createProduct($requestData, $imageZipName)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$dataFlowProfileRecord = $this->importProductRepository->findOneByField
|
||||||
|
('data_flow_profile_id', $requestData['data_flow_profile_id']);
|
||||||
|
|
||||||
|
$csvData = (new DataGridImport)->toArray($dataFlowProfileRecord->file_path)[0];
|
||||||
|
|
||||||
|
if ($requestData['totalNumberOfCSVRecord'] < 1000) {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/10);
|
||||||
|
} else {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/100);
|
||||||
|
}
|
||||||
|
|
||||||
|
$uptoProcessCSVRecords = (int)$requestData['countOfStartedProfiles'] + 10;
|
||||||
|
$processRecords = (int)$requestData['countOfStartedProfiles'] + (int)$requestData['numberOfCSVRecord'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] > $processCSVRecords) {
|
||||||
|
for ($i = $requestData['countOfStartedProfiles']; $i < $uptoProcessCSVRecords; $i++) {
|
||||||
|
$invalidateProducts = $this->store($csvData[$i], $i, $dataFlowProfileRecord, $requestData, $imageZipName);
|
||||||
|
|
||||||
|
if (isset($invalidateProducts) && !empty($invalidateProducts)) {
|
||||||
|
return $invalidateProducts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ($requestData['numberOfCSVRecord'] <= 10) {
|
||||||
|
for ($i = $requestData['countOfStartedProfiles']; $i < $processRecords; $i++) {
|
||||||
|
$invalidateProducts = $this->store($csvData[$i], $i, $dataFlowProfileRecord, $requestData, $imageZipName);
|
||||||
|
|
||||||
|
if (isset($invalidateProducts) && !empty($invalidateProducts)) {
|
||||||
|
return $invalidateProducts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] > 10) {
|
||||||
|
$remainDataInCSV = (int)$requestData['numberOfCSVRecord'] - (int)$processCSVRecords;
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
|
||||||
|
if($requestData['errorCount'] > 0) {
|
||||||
|
$uptoProcessCSVRecords = $requestData['totalNumberOfCSVRecord'] - $requestData['errorCount'];
|
||||||
|
} else {
|
||||||
|
$uptoProcessCSVRecords = $processRecords;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $i;
|
||||||
|
|
||||||
|
$dataToBeReturn = [
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $uptoProcessCSVRecords,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
];
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
$categoryError = explode('[' ,$e->getMessage());
|
||||||
|
$categorySlugError = explode(']' ,$e->getMessage());
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
$productsUploaded = $i - $requestData['errorCount'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] != 0) {
|
||||||
|
$remainDataInCSV = (int)$requestData['totalNumberOfCSVRecord'] - (int)$requestData['countOfStartedProfiles'];
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($categoryError[0] == "No query results for model ") {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => "Invalid Category Slug: " . $categorySlugError[1],
|
||||||
|
);
|
||||||
|
$categoryError[0] = null;
|
||||||
|
} else if (isset($e->errorInfo)) {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->errorInfo[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function to store product
|
||||||
|
*
|
||||||
|
* @param array $csvData
|
||||||
|
* @param integer $i
|
||||||
|
* @param \Webkul\Bulkupload\Contracts\ImportProduct $dataFlowProfileRecord
|
||||||
|
* @param array $requestData
|
||||||
|
* @param array $imageZipName
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function store($csvData, $i, $dataFlowProfileRecord, $requestData, $imageZipName)
|
||||||
|
{
|
||||||
|
$createValidation = $this->helperRepository->createProductValidation($csvData, $i);
|
||||||
|
|
||||||
|
if (isset($createValidation)) {
|
||||||
|
return $createValidation;
|
||||||
|
}
|
||||||
|
|
||||||
|
$productFlatData = $this->productFlatRepository->findWhere(['sku' => $csvData['sku'], 'url_key' => $csvData['url_key']])->first();
|
||||||
|
|
||||||
|
$productData = $this->productRepository->findWhere(['sku' => $csvData['sku']])->first();
|
||||||
|
|
||||||
|
$attributeFamilyData = $this->attributeFamilyRepository->findOneByfield(['name' => $csvData['attribute_family_name']]);
|
||||||
|
|
||||||
|
if (! isset($productFlatData) && empty($productFlatData)) {
|
||||||
|
$data['type'] = $csvData['type'];
|
||||||
|
$data['attribute_family_id'] = $attributeFamilyData->id;
|
||||||
|
$data['sku'] = $csvData['sku'];
|
||||||
|
|
||||||
|
$bundledProduct = $this->productRepository->create($data);
|
||||||
|
} else {
|
||||||
|
$bundledProduct = $productData;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data);
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
$attributeCode = [];
|
||||||
|
$attributeValue = [];
|
||||||
|
|
||||||
|
//default attributes
|
||||||
|
foreach ($bundledProduct->getTypeInstance()->getEditableAttributes()->toArray() as $key => $value) {
|
||||||
|
$searchIndex = $value['code'];
|
||||||
|
|
||||||
|
if (array_key_exists($searchIndex, $csvData)) {
|
||||||
|
if (is_null($csvData[$searchIndex])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($attributeCode, $searchIndex);
|
||||||
|
|
||||||
|
if ($searchIndex == "color" || $searchIndex == "size" || $searchIndex == "brand") {
|
||||||
|
$attributeOption = $this->attributeOptionRepository->findOneByField(['admin_name' => ucwords($csvData[$searchIndex])]);
|
||||||
|
|
||||||
|
array_push($attributeValue, $attributeOption['id']);
|
||||||
|
} else {
|
||||||
|
array_push($attributeValue, $csvData[$searchIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array_combine($attributeCode, $attributeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['dataFlowProfileRecordId'] = $dataFlowProfileRecord->id;
|
||||||
|
|
||||||
|
$categoryData = explode(',', $csvData['categories_slug']);
|
||||||
|
|
||||||
|
if (is_null($csvData['categories_slug']) || empty($csvData['categories_slug'])) {
|
||||||
|
$categoryID = $this->categoryRepository->findBySlugOrFail('root')->id;
|
||||||
|
} else {
|
||||||
|
foreach ($categoryData as $key => $value) {
|
||||||
|
$categoryID[$key] = $this->categoryRepository->findBySlugOrFail($categoryData[$key])->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['categories'] = $categoryID;
|
||||||
|
$data['channel'] = core()->getCurrentChannel()->code;
|
||||||
|
|
||||||
|
$dataProfile = app('Webkul\Bulkupload\Repositories\DataFlowProfileRepository')->findOneByfield(['id' => $data['dataFlowProfileRecordId']]);
|
||||||
|
$data['locale'] = $dataProfile->locale_code;
|
||||||
|
|
||||||
|
//customerGroupPricing
|
||||||
|
if (isset($csvData['customer_group_prices']) && ! empty($csvData['customer_group_prices'])) {
|
||||||
|
$data['customer_group_prices'] = json_decode($csvData['customer_group_prices'], true);
|
||||||
|
app(ProductCustomerGroupPriceRepository::class)->saveCustomerGroupPrices($data, $simpleproductData);
|
||||||
|
}
|
||||||
|
|
||||||
|
//prepare bundle options
|
||||||
|
$bundleOptions = json_decode($csvData['bundle_options'], true);
|
||||||
|
|
||||||
|
$data['bundle_options'] = $bundleOptions;
|
||||||
|
|
||||||
|
//Product Images
|
||||||
|
$individualProductimages = explode(',', $csvData['images']);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$images = Storage::disk('local')->files('public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id.'/'.$imageZipName['dirname'].'/');
|
||||||
|
|
||||||
|
foreach ($images as $imageArraykey => $imagePath) {
|
||||||
|
$imageName = explode('/', $imagePath);
|
||||||
|
|
||||||
|
if (in_array(last($imageName), preg_replace('/[\'"]/', '',$individualProductimages))) {
|
||||||
|
$data['images'][$imageArraykey] = $imagePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
foreach ($individualProductimages as $imageArraykey => $imageURL)
|
||||||
|
{
|
||||||
|
if (filter_var(trim($imageURL), FILTER_VALIDATE_URL)) {
|
||||||
|
$imagePath = storage_path('app/public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id);
|
||||||
|
|
||||||
|
if (!file_exists($imagePath)) {
|
||||||
|
mkdir($imagePath, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageFile = $imagePath.'/'.basename($imageURL);
|
||||||
|
|
||||||
|
file_put_contents($imageFile, file_get_contents(trim($imageURL)));
|
||||||
|
|
||||||
|
$data['images'][$imageArraykey] = $imageFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$validationRules = $this->helperRepository->validateCSV($requestData['data_flow_profile_id'], $data, $dataFlowProfileRecord, $bundledProduct);
|
||||||
|
|
||||||
|
$csvValidator = Validator::make($data, $validationRules);
|
||||||
|
|
||||||
|
if ($csvValidator->fails()) {
|
||||||
|
$errors = $csvValidator->errors()->getMessages();
|
||||||
|
|
||||||
|
$this->helperRepository->deleteProductIfNotValidated($bundledProduct->id);
|
||||||
|
|
||||||
|
foreach($errors as $key => $error) {
|
||||||
|
if ($error[0] == "The url key has already been taken.") {
|
||||||
|
$errorToBeReturn[] = "The url key " . $data['url_key'] . " has already been taken";
|
||||||
|
} else {
|
||||||
|
$errorToBeReturn[] = str_replace(".", "", $error[0]). " for sku " . $data['sku'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
|
||||||
|
$productsUploaded = $i - $requestData['errorCount'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] != 0) {
|
||||||
|
$remainDataInCSV = (int)$requestData['totalNumberOfCSVRecord'] - (int)$requestData['countOfStartedProfiles'];
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $errorToBeReturn,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->productRepository->update($data, $bundledProduct->id);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $bundledProduct, $imageZipName);
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $bundledProduct, $imageZipName = null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,742 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Repositories\Products;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
use Webkul\Admin\Imports\DataGridImport;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Webkul\Category\Repositories\CategoryRepository;
|
||||||
|
use Webkul\Product\Models\ProductAttributeValue;
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ImportProductRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductFlatRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeFamilyRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\HelperRepository;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ProductImageRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeOptionRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\BulkProductRepository;
|
||||||
|
|
||||||
|
class ConfigurableProductRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ImportProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ImportProductRepository
|
||||||
|
*/
|
||||||
|
protected $importProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CategoryRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Category\Repositories\CategoryRepository
|
||||||
|
*/
|
||||||
|
protected $categoryRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductFlatRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductFlatRepository
|
||||||
|
*/
|
||||||
|
protected $productFlatRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductRepository
|
||||||
|
*/
|
||||||
|
protected $productRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductInventoryRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductInventoryRepository
|
||||||
|
*/
|
||||||
|
protected $productInventoryRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeFamilyRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeFamilyRepository
|
||||||
|
*/
|
||||||
|
protected $attributeFamilyRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HelperRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\HelperRepository
|
||||||
|
*/
|
||||||
|
protected $helperRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductImageRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ProductImageRepository
|
||||||
|
*/
|
||||||
|
protected $productImageRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BulkProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\BulkProductRepository
|
||||||
|
*/
|
||||||
|
protected $bulkProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeOptionRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeOptionRepository
|
||||||
|
*/
|
||||||
|
protected $attributeOptionRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new repository instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ImportProductRepository $importProductRepository
|
||||||
|
* @param \Webkul\Category\Repositories\CategoryRepository $categoryRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductFlatRepository $productFlatRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\HelperRepository $helperRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ProductImageRepository $productImageRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\BulkProductRepository $bulkProductRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeOptionRepository $attributeOptionRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ImportProductRepository $importProductRepository,
|
||||||
|
CategoryRepository $categoryRepository,
|
||||||
|
ProductFlatRepository $productFlatRepository,
|
||||||
|
ProductRepository $productRepository,
|
||||||
|
AttributeFamilyRepository $attributeFamilyRepository,
|
||||||
|
AttributeRepository $attributeRepository,
|
||||||
|
HelperRepository $helperRepository,
|
||||||
|
ProductImageRepository $productImageRepository,
|
||||||
|
BulkProductRepository $bulkProductRepository,
|
||||||
|
AttributeOptionRepository $attributeOptionRepository,
|
||||||
|
ProductInventoryRepository $productInventoryRepository
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->importProductRepository = $importProductRepository;
|
||||||
|
|
||||||
|
$this->categoryRepository = $categoryRepository;
|
||||||
|
|
||||||
|
$this->productFlatRepository = $productFlatRepository;
|
||||||
|
|
||||||
|
$this->productRepository = $productRepository;
|
||||||
|
|
||||||
|
$this->productImageRepository = $productImageRepository;
|
||||||
|
|
||||||
|
$this->attributeFamilyRepository = $attributeFamilyRepository;
|
||||||
|
|
||||||
|
$this->attributeRepository = $attributeRepository;
|
||||||
|
|
||||||
|
$this->productInventoryRepository = $productInventoryRepository;
|
||||||
|
|
||||||
|
$this->helperRepository = $helperRepository;
|
||||||
|
|
||||||
|
$this->bulkProductRepository = $bulkProductRepository;
|
||||||
|
|
||||||
|
$this->attributeOptionRepository = $attributeOptionRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Product\Contracts\Product';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create & update configurable-type product
|
||||||
|
*
|
||||||
|
* @param array $requestData
|
||||||
|
* @param array $imageZipName
|
||||||
|
* @param array $product
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function createProduct($requestData, $imageZipName, $product)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if ($requestData['totalNumberOfCSVRecord'] < 1000) {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/10);
|
||||||
|
} else {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/100);
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataFlowProfileRecord = $this->importProductRepository->findOneByField
|
||||||
|
('data_flow_profile_id', $requestData['data_flow_profile_id']);
|
||||||
|
|
||||||
|
if ($dataFlowProfileRecord) {
|
||||||
|
$csvData = (new DataGridImport)->toArray($dataFlowProfileRecord->file_path)[0];
|
||||||
|
|
||||||
|
foreach ($csvData as $key => $value) {
|
||||||
|
if ($requestData['numberOfCSVRecord'] >= 0) {
|
||||||
|
for ($i = $requestData['countOfStartedProfiles']; $i < count($csvData); $i++) {
|
||||||
|
$product['loopCount'] = $i;
|
||||||
|
|
||||||
|
if ($csvData[$i]['type'] == 'configurable') {
|
||||||
|
try {
|
||||||
|
$createValidation = $this->helperRepository->createProductValidation($csvData[$i], $i);
|
||||||
|
|
||||||
|
if ( isset($createValidation)) {
|
||||||
|
return $createValidation;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data);
|
||||||
|
|
||||||
|
$productFlatData = $this->productFlatRepository->findOneWhere([
|
||||||
|
'sku' => $csvData[$i]['sku'],
|
||||||
|
'url_key' => $csvData[$i]['url_key']
|
||||||
|
]);
|
||||||
|
|
||||||
|
$productData = $this->productRepository->findOneWhere([
|
||||||
|
'sku' => $csvData[$i]['sku']
|
||||||
|
]);
|
||||||
|
|
||||||
|
$attributeFamilyData = $this->attributeFamilyRepository->findOneByfield('name', $csvData[$i]['attribute_family_name']);
|
||||||
|
|
||||||
|
if (! isset($productFlatData) && empty($productData)) {
|
||||||
|
$data['type'] = $csvData[$i]['type'];
|
||||||
|
$data['attribute_family_id'] = $attributeFamilyData->id;
|
||||||
|
$data['sku'] = $csvData[$i]['sku'];
|
||||||
|
|
||||||
|
$product = $this->bulkProductRepository->create($data);
|
||||||
|
} else {
|
||||||
|
$product = $productData;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data);
|
||||||
|
$data = [];
|
||||||
|
$attributeCode = [];
|
||||||
|
$attributeValue = [];
|
||||||
|
|
||||||
|
foreach ($product->getTypeInstance()->getEditableAttributes()->toArray() as $key => $value) {
|
||||||
|
$attributeOptionArray = [];
|
||||||
|
$searchIndex = strtolower($value['code']);
|
||||||
|
|
||||||
|
if (array_key_exists($searchIndex, $csvData[$i])) {
|
||||||
|
if ($searchIndex == 'tax_category_id') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($attributeCode, $searchIndex);
|
||||||
|
|
||||||
|
if ($value['type'] == "select") {
|
||||||
|
$attributeOption = $this->attributeOptionRepository->findOneByField('admin_name', $csvData[$i][$searchIndex]);
|
||||||
|
|
||||||
|
array_push($attributeValue, (isset($attributeOption['id']) ? $attributeOption['id'] : null));
|
||||||
|
|
||||||
|
} else if ($value['type'] == "checkbox") {
|
||||||
|
$attributeOption = $this->attributeOptionRepository->findOneWhere([
|
||||||
|
'attribute_id' => $value['id'],
|
||||||
|
'admin_name' => $csvData[$i][$searchIndex]
|
||||||
|
]);
|
||||||
|
|
||||||
|
array_push($attributeOptionArray, (isset($attributeOption['id']) ? $attributeOption['id'] : null));
|
||||||
|
|
||||||
|
array_push($attributeValue, $attributeOptionArray);
|
||||||
|
|
||||||
|
unset($attributeOptionArray);
|
||||||
|
} else {
|
||||||
|
array_push($attributeValue, $csvData[$i][$searchIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array_combine($attributeCode, $attributeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['dataFlowProfileRecordId'] = $dataFlowProfileRecord->id;
|
||||||
|
$data['channel'] = core()->getCurrentChannel()->code;
|
||||||
|
|
||||||
|
$dataProfile = app('Webkul\Bulkupload\Repositories\DataFlowProfileRepository')->findOneByfield(['id' => $data['dataFlowProfileRecordId']]);
|
||||||
|
$data['locale'] = $dataProfile->locale_code;
|
||||||
|
|
||||||
|
$data['tax_category_id'] = (isset($csvData[$i]['tax_category_id']) && $csvData[$i]['tax_category_id']) ? $csvData[$i]['tax_category_id'] : null;
|
||||||
|
|
||||||
|
$categoryData = explode(',', $csvData[$i]['categories_slug']);
|
||||||
|
|
||||||
|
if (is_null($csvData[$i]['categories_slug']) || empty($csvData[$i]['categories_slug'])) {
|
||||||
|
$categoryID = $this->categoryRepository->findBySlugOrFail('root')->id;
|
||||||
|
} else {
|
||||||
|
foreach ($categoryData as $key => $value) {
|
||||||
|
$categoryID[$key] = $this->categoryRepository->findBySlugOrFail($categoryData[$key])->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['categories'] = $categoryID;
|
||||||
|
|
||||||
|
$individualProductimages = explode(',', $csvData[$i]['images']);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$images = Storage::disk('local')->files('public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id.'/'.$imageZipName['dirname'].'/');
|
||||||
|
|
||||||
|
foreach ($images as $imageArraykey => $imagePath) {
|
||||||
|
$imageName = explode('/', $imagePath);
|
||||||
|
|
||||||
|
if (in_array(last($imageName), preg_replace('/[\'"]/', '',$individualProductimages))) {
|
||||||
|
$data['images'][$imageArraykey] = $imagePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
foreach ($individualProductimages as $imageArraykey => $imageURL)
|
||||||
|
{
|
||||||
|
if (filter_var(trim($imageURL), FILTER_VALIDATE_URL)) {
|
||||||
|
$imagePath = storage_path('app/public/ imported-products/extracted-images/admin/'. $dataFlowProfileRecord->id);
|
||||||
|
|
||||||
|
if (!file_exists($imagePath)) {
|
||||||
|
mkdir($imagePath, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageFile = $imagePath.'/'.basename($imageURL) ;
|
||||||
|
|
||||||
|
file_put_contents($imageFile, file_get_contents (trim($imageURL)));
|
||||||
|
|
||||||
|
$data['images'][$imageArraykey] = $imageFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$productAttributeStore = $this->bulkProductRepository->productRepositoryUpdateForVariants($data, $product->id);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $product, $imageZipName);
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $product, $imageZipName = null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! isset($productFlatData) && empty($productFlatData)) {
|
||||||
|
$productFlatData = DB::table('product_flat')->select('id')->orderBy('id', 'desc')->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
$product['productFlatId'] = $productFlatData->id;
|
||||||
|
|
||||||
|
$arr[] = $productFlatData->id;
|
||||||
|
|
||||||
|
unset($categoryID);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$categoryError = explode('[' ,$e->getMessage());
|
||||||
|
$categorySlugError = explode(']' ,$e->getMessage());
|
||||||
|
|
||||||
|
$error = $e;
|
||||||
|
|
||||||
|
$productUploadedWithError = $requestData['productUploaded'] + 1;
|
||||||
|
$remainDataInCSV = $requestData['totalNumberOfCSVRecord'] - $productUploadedWithError;
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
|
||||||
|
if ($categoryError[0] == "No query results for model ") {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $requestData['productUploaded'],
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => "Invalid Category Slug: " . $categorySlugError[1],
|
||||||
|
);
|
||||||
|
$categoryError[0] = null;
|
||||||
|
} else if (isset($e->errorInfo)) {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $requestData['productUploaded'],
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->errorInfo[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $requestData['productUploaded'],
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
} else if (isset($product['productFlatId'])) {
|
||||||
|
try {
|
||||||
|
$current = $product['loopCount'];
|
||||||
|
$num = 0;
|
||||||
|
$inventory = [];
|
||||||
|
|
||||||
|
$csvData = (new DataGridImport)->toArray($dataFlowProfileRecord->file_path)[0];
|
||||||
|
|
||||||
|
for ($i = $current; $i < count($csvData); $i++) {
|
||||||
|
$product['loopCount'] = $i;
|
||||||
|
|
||||||
|
if ($csvData[$i]['type'] != 'configurable') {
|
||||||
|
$productFlatData = $this->productFlatRepository->findOneWhere([
|
||||||
|
'sku' => $csvData[$i]['sku'],
|
||||||
|
'url_key' => null
|
||||||
|
]);
|
||||||
|
|
||||||
|
$productData = $this->productRepository->findOneWhere([
|
||||||
|
'sku' => $csvData[$i]['sku']
|
||||||
|
]);
|
||||||
|
|
||||||
|
$attributeFamilyData = $this->attributeFamilyRepository->findOneWhere([
|
||||||
|
'name' => $csvData[$i]['attribute_family_name']
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (! isset($productFlatData) && empty($productData)) {
|
||||||
|
$data['parent_id'] = $product->id;
|
||||||
|
$data['type'] = "simple";
|
||||||
|
$data['attribute_family_id'] = $attributeFamilyData->id;
|
||||||
|
$data['sku'] = $csvData[$i]['sku'];
|
||||||
|
|
||||||
|
$configSimpleproduct = $this->productRepository->create($data);
|
||||||
|
} else {
|
||||||
|
$configSimpleproduct = $productData;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data);
|
||||||
|
|
||||||
|
$validateVariant = Validator::make($csvData[$i], [
|
||||||
|
'sku' => ['required', 'unique:products,sku,' . $configSimpleproduct->id, new \Webkul\Core\Contracts\Validations\Slug],
|
||||||
|
'name' => 'required',
|
||||||
|
'super_attribute_price' => 'required',
|
||||||
|
'super_attribute_weight' => 'required',
|
||||||
|
'super_attribute_option' => 'required',
|
||||||
|
'super_attributes' => 'required'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validateVariant->fails()) {
|
||||||
|
$errors = $validateVariant->errors()->getMessages();
|
||||||
|
|
||||||
|
$this->helperRepository->deleteProductIfNotValidated($product->id);
|
||||||
|
|
||||||
|
foreach($errors as $key => $error) {
|
||||||
|
$errorToBeReturn[] = str_replace(".", "", $error[0]). " for sku " .$csvData[$i]['sku'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$productUploadedWithError = $requestData['productUploaded'] + 1;
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] != 0) {
|
||||||
|
$remainDataInCSV = $requestData['totalNumberOfCSVRecord'] - $productUploadedWithError;
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $requestData['productUploaded'],
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $errorToBeReturn,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
$inventory_data = core()->getCurrentChannel()->inventory_sources;
|
||||||
|
|
||||||
|
foreach($inventory_data as $key => $datas) {
|
||||||
|
$inventoryId = $datas->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$inventoryData[] = (string)$csvData[$i]['super_attribute_qty'];
|
||||||
|
|
||||||
|
foreach ($inventoryData as $key => $d) {
|
||||||
|
$inventory[$inventoryId] = $d;
|
||||||
|
}
|
||||||
|
|
||||||
|
$productInventory = $this->productInventoryRepository->findOneByField('product_id', $configSimpleproduct->id);
|
||||||
|
|
||||||
|
if (! isset($productInventory) && empty($productInventory) || $productInventory->count() < 1) {
|
||||||
|
$data['inventories'] = $inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
$superAttributes = explode(',', $csvData[$i]['super_attributes']);
|
||||||
|
$superAttributesOption = explode(',', $csvData[$i]['super_attribute_option']);
|
||||||
|
|
||||||
|
$data['super_attributes'] = array_combine($superAttributes, $superAttributesOption);
|
||||||
|
|
||||||
|
if (isset($data['super_attributes']) && $i == $current) {
|
||||||
|
$super_attributes = [];
|
||||||
|
|
||||||
|
foreach ($data['super_attributes'] as $attributeCode => $attributeOptions) {
|
||||||
|
$attribute = $this->attributeRepository->findOneByField('code', $attributeCode);
|
||||||
|
|
||||||
|
$super_attributes[$attribute->id] = $attributeOptions;
|
||||||
|
|
||||||
|
$users = $product->super_attributes()->where('id', $attribute->id)->exists();
|
||||||
|
|
||||||
|
if (! $users) {
|
||||||
|
$product->super_attributes()->attach($attribute->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['dataFlowProfileRecordId'] = $dataFlowProfileRecord->id;
|
||||||
|
$data['channel'] = core()->getCurrentChannel()->code;
|
||||||
|
|
||||||
|
$dataProfile = app('Webkul\Bulkupload\Repositories\DataFlowProfileRepository')->findOneByfield(['id' => $data['dataFlowProfileRecordId']]);
|
||||||
|
$data['locale'] = $dataProfile->locale_code;
|
||||||
|
|
||||||
|
$data['price'] = (string)$csvData[$i]['super_attribute_price'];
|
||||||
|
$data['special_price'] = (string)$csvData[$i]['special_price'];
|
||||||
|
$data['special_price_from'] = (string)$csvData[$i]['special_price_from'];
|
||||||
|
$data['special_price_to'] = (string)$csvData[$i]['special_price_to'];
|
||||||
|
$data['new'] = (string)$csvData[$i]['new'];
|
||||||
|
$data['featured'] = (string)$csvData[$i]['featured'];
|
||||||
|
$data['visible_individually'] = (string)$csvData[$i]['visible_individually'];
|
||||||
|
$data['tax_category_id'] = (string)$csvData[$i]['tax_category_id'];
|
||||||
|
$data['cost'] = (string)$csvData[$i]['cost'];
|
||||||
|
$data['width'] = (string)$csvData[$i]['width'];
|
||||||
|
$data['height'] = (string)$csvData[$i]['height'];
|
||||||
|
$data['depth'] = (string)$csvData[$i]['depth'];
|
||||||
|
$data['status'] = (string)$csvData[$i]['status'];
|
||||||
|
$data['attribute_family_id'] = $attributeFamilyData->id;
|
||||||
|
$data['short_description'] = (string)$csvData[$i]['short_description'];
|
||||||
|
$data['sku'] = (string)$csvData[$i]['sku'];
|
||||||
|
$data['name'] = (string)$csvData[$i]['name'];
|
||||||
|
$data['weight'] = (string)$csvData[$i]['super_attribute_weight'];
|
||||||
|
$data['status'] = (string)$csvData[$i]['status'];
|
||||||
|
|
||||||
|
if ( isset($data['super_attributes'])) {
|
||||||
|
foreach ($data['super_attributes'] as $attributeCode => $attributeOptions) {
|
||||||
|
$attribute = $this->attributeRepository->findOneByField('code', $attributeCode);
|
||||||
|
|
||||||
|
if ( $attribute ) {
|
||||||
|
$attributeOptionColor = $this->attributeOptionRepository->findOneWhere([
|
||||||
|
'attribute_id' => $attribute->id,
|
||||||
|
'admin_name' => $attributeOptions,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$data[$attributeCode] = $attributeOptionColor->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$individualProductimages = explode(',', $csvData[$i]['images']);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$images = Storage::disk('local')->files('public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id.'/'.$imageZipName['dirname'].'/');
|
||||||
|
|
||||||
|
foreach ($images as $imageArraykey => $imagePath) {
|
||||||
|
$imageName = explode('/', $imagePath);
|
||||||
|
|
||||||
|
if (in_array(last($imageName), preg_replace('/[\'"]/', '',$individualProductimages))) {
|
||||||
|
$data['images'][$imageArraykey] = $imagePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
foreach ($individualProductimages as $imageArraykey => $imageURL)
|
||||||
|
{
|
||||||
|
if (filter_var(trim($imageURL), FILTER_VALIDATE_URL)) {
|
||||||
|
$imagePath = storage_path('app/public/ imported-products/extracted-images/admin/'. $dataFlowProfileRecord->id);
|
||||||
|
|
||||||
|
if (!file_exists($imagePath)) {
|
||||||
|
mkdir($imagePath, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageFile = $imagePath.'/'.basename($imageURL) ;
|
||||||
|
|
||||||
|
file_put_contents($imageFile, file_get_contents (trim($imageURL)));
|
||||||
|
|
||||||
|
$data['images'][$imageArraykey] = $imageFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$configSimpleProductAttributeStore = $this->bulkProductRepository->productRepositoryUpdateForVariants($data, $configSimpleproduct->id);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $configSimpleproduct, $imageZipName);
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $configSimpleproduct, $imageZipName = null);
|
||||||
|
}
|
||||||
|
|
||||||
|
$configSimpleProductAttributeStore['parent_id'] = $product['productFlatId'];
|
||||||
|
|
||||||
|
$this->createFlat($configSimpleProductAttributeStore);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$savedProduct = $requestData['productUploaded'] + 1;
|
||||||
|
$remainDataInCSV = $requestData['totalNumberOfCSVRecord'] - $savedProduct;
|
||||||
|
$productsUploaded = $savedProduct;
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $product['loopCount'];
|
||||||
|
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles']
|
||||||
|
);
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($requestData['errorCount'] == 0) {
|
||||||
|
$dataToBeReturn = [
|
||||||
|
'remainDataInCSV' => 0,
|
||||||
|
'productsUploaded' => $requestData['totalNumberOfCSVRecord'],
|
||||||
|
'countOfStartedProfiles' => count($csvData),
|
||||||
|
];
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
} else {
|
||||||
|
$dataToBeReturn = [
|
||||||
|
'remainDataInCSV' => 0,
|
||||||
|
'productsUploaded' => $requestData['totalNumberOfCSVRecord'] - $requestData['errorCount'],
|
||||||
|
'countOfStartedProfiles' => count($csvData),
|
||||||
|
];
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
$product['productFlatId'] = null;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$error = $e;
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
$remainDataInCSV = $requestData['totalNumberOfCSVRecord'] - $requestData['productUploaded'];
|
||||||
|
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $requestData['productUploaded'],
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $error->errorInfo[2] ?? $error->getMessage(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
\Log::error('configurable create product log: '. $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create product flat for variants
|
||||||
|
*
|
||||||
|
* @param \Webkul\Product\Contracts\Product $product
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function createFlat($product, $parentProduct = null)
|
||||||
|
{
|
||||||
|
static $familyAttributes = [];
|
||||||
|
|
||||||
|
static $superAttributes = [];
|
||||||
|
|
||||||
|
if (! array_key_exists($product->attribute_family->id, $familyAttributes))
|
||||||
|
$familyAttributes[$product->attribute_family->id] = $product->attribute_family->custom_attributes;
|
||||||
|
|
||||||
|
if ($parentProduct && ! array_key_exists($parentProduct->id, $superAttributes))
|
||||||
|
$superAttributes[$parentProduct->id] = $parentProduct->super_attributes()->pluck('code')->toArray();
|
||||||
|
|
||||||
|
foreach (core()->getAllChannels() as $channel) {
|
||||||
|
foreach ($channel->locales as $locale) {
|
||||||
|
$productFlat = $this->productFlatRepository->findOneWhere([
|
||||||
|
'product_id' => $product->id,
|
||||||
|
'channel' => $channel->code,
|
||||||
|
'locale' => $locale->code
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (! $productFlat) {
|
||||||
|
$productFlat = $this->productFlatRepository->create([
|
||||||
|
'product_id' => $product->id,
|
||||||
|
'channel' => $channel->code,
|
||||||
|
'locale' => $locale->code
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
foreach ($familyAttributes[$product->attribute_family->id] as $attribute) {
|
||||||
|
if ($parentProduct && ! in_array($attribute->code, array_merge($superAttributes[$parentProduct->id], ['sku', 'name', 'price', 'weight', 'status'])))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (in_array($attribute->code, ['tax_category_id']))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (! Schema::hasColumn('product_flat', $attribute->code))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ($attribute->value_per_channel) {
|
||||||
|
if ($attribute->value_per_locale) {
|
||||||
|
$productAttributeValue = $product->attribute_values()->where('channel', $channel->code)->where('locale', $locale->code)->where('attribute_id', $attribute->id)->first();
|
||||||
|
} else {
|
||||||
|
$productAttributeValue = $product->attribute_values()->where('channel', $channel->code)->where('attribute_id', $attribute->id)->first();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($attribute->value_per_locale) {
|
||||||
|
$productAttributeValue = $product->attribute_values()->where('locale', $locale->code)->where('attribute_id', $attribute->id)->first();
|
||||||
|
} else {
|
||||||
|
$productAttributeValue = $product->attribute_values()->where('attribute_id', $attribute->id)->first();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($product->type == 'configurable' && $attribute->code == 'price') {
|
||||||
|
try {
|
||||||
|
$productFlat->{$attribute->code} = app('Webkul\Bulkupload\Helpers\Price')->getVariantMinPrice($product);
|
||||||
|
} catch(\Exception $e) {}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
$productFlat->{$attribute->code} = $productAttributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]];
|
||||||
|
} catch(\Exception $e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($attribute->type == 'select') {
|
||||||
|
$attributeOption = $this->attributeOptionRepository->find($product->{$attribute->code});
|
||||||
|
|
||||||
|
if ($attributeOption) {
|
||||||
|
if ($attributeOptionTranslation = $attributeOption->translate($locale->code)) {
|
||||||
|
$productFlat->{$attribute->code . '_label'} = $attributeOptionTranslation->label;
|
||||||
|
} else {
|
||||||
|
$productFlat->{$attribute->code . '_label'} = $attributeOption->admin_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ($attribute->type == 'multiselect') {
|
||||||
|
$attributeOptionIds = explode(',', $product->{$attribute->code});
|
||||||
|
|
||||||
|
if (count($attributeOptionIds)) {
|
||||||
|
$attributeOptions = $this->attributeOptionRepository->findWhereIn('id', $attributeOptionIds);
|
||||||
|
|
||||||
|
$optionLabels = [];
|
||||||
|
|
||||||
|
foreach ($attributeOptions as $attributeOption) {
|
||||||
|
if ($attributeOptionTranslation = $attributeOption->translate($locale->code)) {
|
||||||
|
$optionLabels[] = $attributeOptionTranslation->label;
|
||||||
|
} else {
|
||||||
|
$optionLabels[] = $attributeOption->admin_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$productFlat->{$attribute->code . '_label'} = implode(', ', $optionLabels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$productFlat->created_at = $product->created_at;
|
||||||
|
|
||||||
|
$productFlat->updated_at = $product->updated_at;
|
||||||
|
|
||||||
|
if ($parentProduct) {
|
||||||
|
$parentProductFlat = $this->productFlatRepository->findOneWhere([
|
||||||
|
'product_id' => $parentProduct->id,
|
||||||
|
'channel' => $channel->code,
|
||||||
|
'locale' => $locale->code
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$productFlat->parent_id = $product->parent_id;
|
||||||
|
|
||||||
|
$productFlat->save();
|
||||||
|
|
||||||
|
$product->parent_id--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,789 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Repositories\Products;
|
||||||
|
|
||||||
|
use Storage;
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Webkul\Admin\Imports\DataGridImport;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Webkul\Category\Repositories\CategoryRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ImportProductRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductFlatRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeFamilyRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\HelperRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ProductImageRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeOptionRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductDownloadableLinkRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductCustomerGroupPriceRepository;
|
||||||
|
|
||||||
|
class DownloadableProductRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ImportProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ImportProductRepository
|
||||||
|
*/
|
||||||
|
protected $importProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CategoryRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Category\Repositories\CategoryRepository
|
||||||
|
*/
|
||||||
|
protected $categoryRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductFlatRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductFlatRepository
|
||||||
|
*/
|
||||||
|
protected $productFlatRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductRepository
|
||||||
|
*/
|
||||||
|
protected $productRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeFamilyRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeFamilyRepository
|
||||||
|
*/
|
||||||
|
protected $attributeFamilyRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HelperRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\HelperRepository
|
||||||
|
*/
|
||||||
|
protected $helperRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductImageRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ProductImageRepository
|
||||||
|
*/
|
||||||
|
protected $productImageRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductDownloadableLinkRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductDownloadableLinkRepository
|
||||||
|
*/
|
||||||
|
protected $productDownloadableLinkRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeOptionRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeOptionRepository
|
||||||
|
*/
|
||||||
|
protected $attributeOptionRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new repository instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ImportProductRepository $importProductRepository
|
||||||
|
* @param \Webkul\Category\Repositories\CategoryRepository $categoryRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductFlatRepository $productFlatRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\HelperRepository $helperRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ProductImageRepository $productImageRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductDownloadableLinkRepository $productDownloadableLinkRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeOptionRepository $attributeOptionRepository
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ImportProductRepository $importProductRepository,
|
||||||
|
CategoryRepository $categoryRepository,
|
||||||
|
ProductFlatRepository $productFlatRepository,
|
||||||
|
ProductRepository $productRepository,
|
||||||
|
AttributeFamilyRepository $attributeFamilyRepository,
|
||||||
|
HelperRepository $helperRepository,
|
||||||
|
ProductImageRepository $productImageRepository,
|
||||||
|
ProductDownloadableLinkRepository $productDownloadableLinkRepository,
|
||||||
|
AttributeOptionRepository $attributeOptionRepository
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->importProductRepository = $importProductRepository;
|
||||||
|
|
||||||
|
$this->productDownloadableLinkRepository = $productDownloadableLinkRepository;
|
||||||
|
|
||||||
|
$this->categoryRepository = $categoryRepository;
|
||||||
|
|
||||||
|
$this->productFlatRepository = $productFlatRepository;
|
||||||
|
|
||||||
|
$this->productRepository = $productRepository;
|
||||||
|
|
||||||
|
$this->productImageRepository = $productImageRepository;
|
||||||
|
|
||||||
|
$this->attributeFamilyRepository = $attributeFamilyRepository;
|
||||||
|
|
||||||
|
$this->helperRepository = $helperRepository;
|
||||||
|
|
||||||
|
$this->attributeOptionRepository = $attributeOptionRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Product\Contracts\Product';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create & update downloadable-type product
|
||||||
|
*
|
||||||
|
* @param array $requestData
|
||||||
|
* @param array $imageZipName
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function createProduct($requestData, $imageZipName)
|
||||||
|
{
|
||||||
|
$uploadLinkFilesZipName = null;
|
||||||
|
$uploadSampleFilesZipName = null;
|
||||||
|
$uploadLinkSampleFilesZipName = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$dataFlowProfileRecord = $this->importProductRepository->findOneByField
|
||||||
|
('data_flow_profile_id', $requestData['data_flow_profile_id']);
|
||||||
|
|
||||||
|
$csvData = (new DataGridImport)->toArray($dataFlowProfileRecord->file_path)[0];
|
||||||
|
|
||||||
|
$downloadableLinks = $this->extractDownloadableFiles($dataFlowProfileRecord);
|
||||||
|
|
||||||
|
if ($requestData['totalNumberOfCSVRecord'] < 1000) {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/10);
|
||||||
|
} else {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/100);
|
||||||
|
}
|
||||||
|
|
||||||
|
$uptoProcessCSVRecords = (int)$requestData['countOfStartedProfiles'] + 10;
|
||||||
|
$processRecords = (int)$requestData['countOfStartedProfiles'] + (int)$requestData['numberOfCSVRecord'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] > $processCSVRecords) {
|
||||||
|
for ($i = $requestData['countOfStartedProfiles']; $i < $uptoProcessCSVRecords; $i++) {
|
||||||
|
$invalidateProducts = $this->store($csvData[$i], $i, $dataFlowProfileRecord, $requestData, $imageZipName, $downloadableLinks);
|
||||||
|
|
||||||
|
if (isset($invalidateProducts) && !empty($invalidateProducts)) {
|
||||||
|
return $invalidateProducts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ($requestData['numberOfCSVRecord'] <= 10) {
|
||||||
|
for ($i = $requestData['countOfStartedProfiles']; $i < $processRecords; $i++) {
|
||||||
|
$invalidateProducts = $this->store($csvData[$i], $i, $dataFlowProfileRecord, $requestData, $imageZipName, $downloadableLinks);
|
||||||
|
|
||||||
|
if (isset($invalidateProducts) && !empty($invalidateProducts)) {
|
||||||
|
return $invalidateProducts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] > 10) {
|
||||||
|
$remainDataInCSV = (int)$requestData['numberOfCSVRecord'] - (int)$processCSVRecords;
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
|
||||||
|
if ($requestData['errorCount'] > 0) {
|
||||||
|
$uptoProcessCSVRecords = $requestData['totalNumberOfCSVRecord'] - $requestData['errorCount'];
|
||||||
|
} else {
|
||||||
|
$uptoProcessCSVRecords = $processRecords;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $i;
|
||||||
|
|
||||||
|
$dataToBeReturn = [
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $uptoProcessCSVRecords,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
];
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
Log::error('downloadable create product log: '. $e->getMessage());
|
||||||
|
|
||||||
|
$categoryError = explode('[' ,$e->getMessage());
|
||||||
|
$categorySlugError = explode(']' ,$e->getMessage());
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
$productsUploaded = $i - $requestData['errorCount'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] != 0) {
|
||||||
|
$remainDataInCSV = (int)$requestData['totalNumberOfCSVRecord'] - (int)$requestData['countOfStartedProfiles'];
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($categoryError[0] == "No query results for model ") {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => "Invalid Category Slug: " . $categorySlugError[1],
|
||||||
|
);
|
||||||
|
$categoryError[0] = null;
|
||||||
|
} else if (isset($e->errorInfo)) {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->errorInfo[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function to store product
|
||||||
|
*
|
||||||
|
* @param array $csvData
|
||||||
|
* @param integer $i
|
||||||
|
* @param \Webkul\Bulkupload\Contracts\ImportProduct $dataFlowProfileRecord
|
||||||
|
* @param array $requestData
|
||||||
|
* @param array $imageZipName
|
||||||
|
* @param array $downloadableLinks
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function store($csvData, $i, $dataFlowProfileRecord, $requestData, $imageZipName, $downloadableLinks)
|
||||||
|
{
|
||||||
|
$createValidation = $this->helperRepository->createProductValidation($csvData, $i);
|
||||||
|
|
||||||
|
if (isset($createValidation)) {
|
||||||
|
return $createValidation;
|
||||||
|
}
|
||||||
|
|
||||||
|
$d_samples = [];
|
||||||
|
$sampleNameKey = [];
|
||||||
|
$linkNameKey = [];
|
||||||
|
$d_links = [];
|
||||||
|
|
||||||
|
if (isset($csvData['samples_title'])) {
|
||||||
|
$csvData['sample_sort_order'] = "";
|
||||||
|
$sampleTitles = explode(',', $csvData['samples_title']) ;
|
||||||
|
$sampleType = explode(',', $csvData['sample_type']) ;
|
||||||
|
$sampleFiles = explode(',', $csvData['sample_files']) ;
|
||||||
|
$urlFiles = explode(',', $csvData['sample_url']) ;
|
||||||
|
$sampleSortOrder = !empty($csvData['sample_sort_order']) ? explode(',', $csvData['sample_sort_order']) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//for downloadable link explode
|
||||||
|
if (isset($csvData['link_titles'])) {
|
||||||
|
$linkTitles = explode(',', $csvData['link_titles']);
|
||||||
|
$linkTypes = explode(',', $csvData['link_types']);
|
||||||
|
|
||||||
|
$linkFileNames = explode(',', $csvData['link_file_names']);
|
||||||
|
|
||||||
|
$linkPrices = !empty($csvData['link_prices']) ? explode(',', $csvData['link_prices']) : "";
|
||||||
|
|
||||||
|
$linkSampleTypes = !empty($csvData['link_sample_types']) ? explode(',', $csvData['link_sample_types']) : "file";
|
||||||
|
|
||||||
|
$linkSampleFileNames = !empty($csvData['link_sample_file_names']) ? explode(',', $csvData['link_sample_file_names']) : "";
|
||||||
|
|
||||||
|
$linkDownloads = !empty($csvData['link_downloads']) ? explode(',', $csvData['link_downloads']) : 0;
|
||||||
|
|
||||||
|
$linkSortOrders = !empty($csvData['link_sort_orders']) ? explode(',', $csvData['link_sort_orders']) : 0;
|
||||||
|
|
||||||
|
$linkSampleUrlNames = explode(',', $csvData['link_sample_url']);
|
||||||
|
$linkUrlNames = explode(',', $csvData['link_url']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$productFlatData = $this->productFlatRepository->findWhere(['sku' => $csvData['sku'], 'url_key' => $csvData['url_key']])->first();
|
||||||
|
|
||||||
|
$productData = $this->productRepository->findWhere(['sku' => $csvData['sku']])->first();
|
||||||
|
|
||||||
|
$attributeFamilyData = $this->attributeFamilyRepository->findOneByfield(['name' => $csvData['attribute_family_name']]);
|
||||||
|
|
||||||
|
if (! isset($productFlatData) && empty($productFlatData)) {
|
||||||
|
$data['type'] = $csvData['type'];
|
||||||
|
$data['attribute_family_id'] = $attributeFamilyData->id;
|
||||||
|
$data['sku'] = $csvData['sku'];
|
||||||
|
|
||||||
|
$downloadableProduct = $this->productRepository->create($data);
|
||||||
|
} else {
|
||||||
|
$downloadableProduct = $productData;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data);
|
||||||
|
$data = [];
|
||||||
|
$attributeCode = [];
|
||||||
|
$attributeValue = [];
|
||||||
|
|
||||||
|
//default attributes
|
||||||
|
foreach ($downloadableProduct->getTypeInstance()->getEditableAttributes()->toArray() as $key => $value) {
|
||||||
|
$searchIndex = $value['code'];
|
||||||
|
if (array_key_exists($searchIndex, $csvData)) {
|
||||||
|
if (is_null($csvData[$searchIndex])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($attributeCode, $searchIndex);
|
||||||
|
|
||||||
|
if ($searchIndex == "color" || $searchIndex == "size" || $searchIndex == "brand") {
|
||||||
|
$attributeOption = $this->attributeOptionRepository->findOneByField(['admin_name' => ucwords($csvData[$searchIndex])]);
|
||||||
|
|
||||||
|
array_push($attributeValue, $attributeOption['id']);
|
||||||
|
} else {
|
||||||
|
array_push($attributeValue, $csvData[$searchIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array_combine($attributeCode, $attributeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['dataFlowProfileRecordId'] = $dataFlowProfileRecord->id;
|
||||||
|
|
||||||
|
$categoryData = explode(',', $csvData['categories_slug']);
|
||||||
|
|
||||||
|
if (is_null($csvData['categories_slug']) || empty($csvData['categories_slug'])) {
|
||||||
|
$categoryID = $this->categoryRepository->findBySlugOrFail('root')->id;
|
||||||
|
} else {
|
||||||
|
foreach ($categoryData as $key => $value) {
|
||||||
|
$categoryID[$key] = $this->categoryRepository->findBySlugOrFail($categoryData[$key])->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['categories'] = $categoryID;
|
||||||
|
$data['channel'] = core()->getCurrentChannel()->code;
|
||||||
|
|
||||||
|
$dataProfile = app('Webkul\Bulkupload\Repositories\DataFlowProfileRepository')->findOneByfield(['id' => $data['dataFlowProfileRecordId']]);
|
||||||
|
$data['locale'] = $dataProfile->locale_code;
|
||||||
|
|
||||||
|
//customerGroupPricing
|
||||||
|
if (isset($csvData['customer_group_prices']) && ! empty($csvData['customer_group_prices'])) {
|
||||||
|
$data['customer_group_prices'] = json_decode($csvData['customer_group_prices'], true);
|
||||||
|
app(ProductCustomerGroupPriceRepository::class)->saveCustomerGroupPrices($data, $simpleproductData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//prepare downloadable sample data
|
||||||
|
for ($j = 0; $j < count($sampleTitles); $j++) {
|
||||||
|
if (trim(strtolower($sampleType[$j])) == "file") {
|
||||||
|
if (isset($downloadableLinks['uploadSampleFilesZipName'])) {
|
||||||
|
if (trim(strtolower($sampleType[$j-1])) == "url") {
|
||||||
|
$sampleFileName = $sampleFiles[$j-1];
|
||||||
|
} else {
|
||||||
|
$sampleFileName = $sampleFiles[$j];
|
||||||
|
}
|
||||||
|
|
||||||
|
$files = $this->fileOrUrlUpload($dataFlowProfileRecord, $sampleType[$j], $sampleFileName, $downloadableProduct->id, $downloadableLinks, $sampleFile = true);
|
||||||
|
|
||||||
|
if (isset($files)) {
|
||||||
|
$sample['sample_'.$j] = [
|
||||||
|
core()->getCurrentLocale()->code => [
|
||||||
|
"title" => $sampleTitles[$j],
|
||||||
|
],
|
||||||
|
"type" => trim($sampleType[$j]),
|
||||||
|
"file" => trim($files),
|
||||||
|
"file_name" => $sampleFileName,
|
||||||
|
"sort_order" => $sampleSortOrder[$j] ?? 0,
|
||||||
|
];
|
||||||
|
|
||||||
|
array_push($sampleNameKey, 'sample_'.$j);
|
||||||
|
array_push($d_samples, $sample['sample_'.$j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (trim(strtolower($sampleType[$j])) == "url") {
|
||||||
|
$files = $this->fileOrUrlUpload($dataFlowProfileRecord, $sampleType[$j], $urlFiles[$j], $downloadableProduct->id, $downloadableLinks, $sampleFile = true);
|
||||||
|
|
||||||
|
if (isset($files)) {
|
||||||
|
$sample['sample_'.$j] = [
|
||||||
|
core()->getCurrentLocale()->code => [
|
||||||
|
"title" => $sampleTitles[$j],
|
||||||
|
],
|
||||||
|
"type" => trim($sampleType[$j]),
|
||||||
|
"url" => trim($urlFiles[$j]),
|
||||||
|
"sort_order" => $sampleSortOrder[$j] ?? 0,
|
||||||
|
];
|
||||||
|
|
||||||
|
array_push($sampleNameKey, 'sample_'.$j);
|
||||||
|
array_push($d_samples, $sample['sample_'.$j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$combinedArray = array_combine($sampleNameKey, $d_samples);
|
||||||
|
|
||||||
|
$data['downloadable_samples'] = $combinedArray;
|
||||||
|
|
||||||
|
//for downloadable links
|
||||||
|
for ($j = 0; $j < count($linkTitles); $j++) {
|
||||||
|
if (trim(strtolower($linkTypes[$j])) == "file") {
|
||||||
|
if (trim(strtolower($linkSampleTypes[$j])) == "file") {
|
||||||
|
if (isset($downloadableLinks['uploadLinkSampleFilesZipName'])) {
|
||||||
|
if (trim(strtolower($linkSampleTypes[$j-1])) == "url") {
|
||||||
|
$linkSampleFile = $linkSampleFileNames[$j-1];
|
||||||
|
} else {
|
||||||
|
$linkSampleFile = $linkSampleFileNames[$j];
|
||||||
|
}
|
||||||
|
|
||||||
|
$sampleFileLink = $this->fileOrUrlUpload($dataFlowProfileRecord, $linkSampleTypes[$j], $linkSampleFile, $downloadableProduct->id, $downloadableLinks, $sampleLinkfile = false);
|
||||||
|
}
|
||||||
|
} else if (trim(strtolower($linkSampleTypes[$j])) == "url") {
|
||||||
|
$sampleFileLink = $this->fileOrUrlUpload($dataFlowProfileRecord, $linkSampleTypes[$j], $linkSampleUrlNames[$j], $downloadableProduct->id, $downloadableLinks, $sampleLinkfile = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($downloadableLinks['uploadLinkFilesZipName'])) {
|
||||||
|
if (trim(strtolower($linkSampleTypes[$j-1])) == "url") {
|
||||||
|
$linkFileName = $linkFileNames[$j-1];
|
||||||
|
} else {
|
||||||
|
$linkFileName = $linkFileNames[$j];
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileLink = $this->linkFileOrUrlUpload($dataFlowProfileRecord, $linkTypes[$j], $linkFileName, $downloadableProduct->id, $downloadableLinks);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($fileLink)) {
|
||||||
|
$link['link_'.$j] = [
|
||||||
|
core()->getCurrentLocale()->code => [
|
||||||
|
"title" => $linkTitles[$j],
|
||||||
|
],
|
||||||
|
"price" => $linkPrices[$j],
|
||||||
|
"type" => trim($linkTypes[$j]),
|
||||||
|
"file" => trim($fileLink),
|
||||||
|
"file_name" => $linkFileName,
|
||||||
|
"sample_type" => trim($linkSampleTypes[$j]),
|
||||||
|
"downloads" => $linkDownloads[$j] ?? 0,
|
||||||
|
"sort_order" => $linkSortOrders[$j] ?? 0,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (trim($linkSampleTypes[$j]) == "url") {
|
||||||
|
$link['link_'.$j]['sample_url'] = trim($linkSampleUrlNames[$j]);
|
||||||
|
} else if (trim($linkSampleTypes[$j]) == "file") {
|
||||||
|
$link['link_'.$j]['sample_file'] = trim($sampleFileLink);
|
||||||
|
|
||||||
|
$link['link_'.$j]['sample_file_name'] = trim($linkSampleFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($linkNameKey, 'link_'.$j);
|
||||||
|
array_push($d_links, $link['link_'.$j]);
|
||||||
|
}
|
||||||
|
} else if (trim(strtolower($linkTypes[$j])) == "url") {
|
||||||
|
if (trim(strtolower($linkSampleTypes[$j])) == "file") {
|
||||||
|
if (isset($downloadableLinks['uploadLinkSampleFilesZipName'])) {
|
||||||
|
$sampleFileLink = $this->fileOrUrlUpload($dataFlowProfileRecord, $linkSampleTypes[$j], $linkSampleFileNames[$j], $downloadableProduct->id, $downloadableLinks, $sampleLinkfile = false);
|
||||||
|
}
|
||||||
|
} else if (trim(strtolower($linkSampleTypes[$j])) == "url") {
|
||||||
|
$sampleFileLink = $this->fileOrUrlUpload($dataFlowProfileRecord, $linkSampleTypes[$j], $linkSampleUrlNames[$j], $downloadableProduct->id, $downloadableLinks, $sampleLinkfile = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileLink = $this->linkFileOrUrlUpload($dataFlowProfileRecord, $linkTypes[$j], $linkUrlNames[$j], $downloadableProduct->id, $downloadableLinks);
|
||||||
|
|
||||||
|
if (isset($fileLink)) {
|
||||||
|
$link['link_'.$j] = [
|
||||||
|
core()->getCurrentLocale()->code => [
|
||||||
|
"title" => $linkTitles[$j],
|
||||||
|
],
|
||||||
|
"price" => $linkPrices[$j],
|
||||||
|
"type" => trim($linkTypes[$j]),
|
||||||
|
"url" => trim($linkUrlNames[$j]) ?? "",
|
||||||
|
"sample_type" => trim($linkSampleTypes[$j]),
|
||||||
|
"downloads" => $linkDownloads[$j] ?? 0,
|
||||||
|
"sort_order" => $linkSortOrders[$j] ?? 0,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (trim($linkSampleTypes[$j]) == "url") {
|
||||||
|
$link['link_'.$j]['sample_url'] = trim($linkSampleUrlNames[$j]);
|
||||||
|
} else if (trim($linkSampleTypes[$j]) == "file") {
|
||||||
|
$link['link_'.$j]['sample_file'] = trim($sampleFileLink);
|
||||||
|
$link['link_'.$j]['sample_file_name'] = trim($linkSampleFileNames[$j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($linkNameKey, 'link_'.$j);
|
||||||
|
array_push($d_links, $link['link_'.$j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$combinedLinksArray = array_combine($linkNameKey, $d_links);
|
||||||
|
|
||||||
|
$data['downloadable_links'] = $combinedLinksArray;
|
||||||
|
|
||||||
|
//Product Images
|
||||||
|
$individualProductimages = explode(',', $csvData['images']);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$images = Storage::disk('local')->files('public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id.'/'.$imageZipName['dirname'].'/');
|
||||||
|
|
||||||
|
foreach ($images as $imageArraykey => $imagePath) {
|
||||||
|
$imageName = explode('/', $imagePath);
|
||||||
|
|
||||||
|
if (in_array(last($imageName), preg_replace('/[\'"]/', '',$individualProductimages))) {
|
||||||
|
$data['images'][$imageArraykey] = $imagePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
foreach ($individualProductimages as $imageArraykey => $imageURL)
|
||||||
|
{
|
||||||
|
if (filter_var(trim($imageURL), FILTER_VALIDATE_URL)) {
|
||||||
|
$imagePath = storage_path('app/public/imported-products/extracted-images/ admin/'.$dataFlowProfileRecord->id);
|
||||||
|
|
||||||
|
if (!file_exists($imagePath)) {
|
||||||
|
mkdir($imagePath, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageFile = $imagePath.'/'.basename($imageURL);
|
||||||
|
|
||||||
|
file_put_contents($imageFile, file_get_contents(trim($imageURL)));
|
||||||
|
|
||||||
|
$data['images'][$imageArraykey] = $imageFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$validationRules = $this->helperRepository->validateCSV($requestData['data_flow_profile_id'], $data, $dataFlowProfileRecord, $downloadableProduct);
|
||||||
|
|
||||||
|
$csvValidator = Validator::make($data, $validationRules);
|
||||||
|
|
||||||
|
if ($csvValidator->fails()) {
|
||||||
|
$errors = $csvValidator->errors()->getMessages();
|
||||||
|
|
||||||
|
$this->helperRepository->deleteProductIfNotValidated($downloadableProduct->id);
|
||||||
|
|
||||||
|
foreach($errors as $key => $error){
|
||||||
|
if ($error[0] == "The url key has already been taken.") {
|
||||||
|
$errorToBeReturn[] = "The url key " . $data['url_key'] . " has already been taken";
|
||||||
|
} else {
|
||||||
|
$errorToBeReturn[] = str_replace(".", "", $error[0]). " for sku " . $data['sku'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
|
||||||
|
$productsUploaded = $i - $requestData['errorCount'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] != 0) {
|
||||||
|
$remainDataInCSV = (int)$requestData['totalNumberOfCSVRecord'] - (int)$requestData['countOfStartedProfiles'];
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $errorToBeReturn,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->productRepository->update($data, $downloadableProduct->id);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $downloadableProduct, $imageZipName);
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $downloadableProduct, $imageZipName = null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* upload sample file link or url
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Contracts\ImportProduct $dataFlowProfileRecord
|
||||||
|
* @param string $type
|
||||||
|
* @param string|array $file
|
||||||
|
* @param integer $id
|
||||||
|
* @param array $downloadableLinks
|
||||||
|
* @param string $flag
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function fileOrUrlUpload($dataFlowProfileRecord, $type, $file, $id, $downloadableLinks, $flag)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (trim($type) == "file") {
|
||||||
|
if ($flag) {
|
||||||
|
$files = "imported-products/extracted-images/admin/sample-files/".$dataFlowProfileRecord->id.'/'. $downloadableLinks['uploadSampleFilesZipName']['dirname'].'/'.trim(basename($file));
|
||||||
|
|
||||||
|
$destination = "product/".$id.'/'.trim(basename($file));
|
||||||
|
|
||||||
|
Storage::copy($files, $destination);
|
||||||
|
|
||||||
|
return $destination;
|
||||||
|
} else {
|
||||||
|
$files = "imported-products/extracted-images/admin/link-sample-files/".$dataFlowProfileRecord->id.'/'. $downloadableLinks['uploadLinkSampleFilesZipName']['dirname'].'/'.trim(basename($file));
|
||||||
|
|
||||||
|
$destination = "product/".$id.'/'.trim(basename($file));
|
||||||
|
|
||||||
|
Storage::copy($files, $destination);
|
||||||
|
|
||||||
|
return $destination;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($flag) {
|
||||||
|
$imagePath = storage_path('app/public/imported-products/extracted-images/admin/sample-files/'.$dataFlowProfileRecord->id);
|
||||||
|
|
||||||
|
if (!file_exists($imagePath)) {
|
||||||
|
mkdir($imagePath, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageFile = $imagePath.'/'.basename($file);
|
||||||
|
|
||||||
|
file_put_contents($imageFile, file_get_contents(trim($file)));
|
||||||
|
|
||||||
|
$files = "imported-products/extracted-images/admin/sample-files/".$dataFlowProfileRecord->id.'/'.basename($file);
|
||||||
|
|
||||||
|
$destination = "product/".$id.'/'.basename($file);
|
||||||
|
Storage::copy($files, $destination);
|
||||||
|
|
||||||
|
return $destination;
|
||||||
|
} else {
|
||||||
|
$imagePath = storage_path('app/public/imported-products/extracted-images/admin/link-sample-files/'.$dataFlowProfileRecord->id);
|
||||||
|
|
||||||
|
if (!file_exists($imagePath)) {
|
||||||
|
mkdir($imagePath, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageFile = $imagePath.'/'.basename($file);
|
||||||
|
|
||||||
|
file_put_contents($imageFile, file_get_contents(trim($file)));
|
||||||
|
|
||||||
|
$files = "imported-products/extracted-images/admin/link-sample-files/".$dataFlowProfileRecord->id.'/'.basename($file);
|
||||||
|
|
||||||
|
$destination = "product/".$id.'/'.basename($file);
|
||||||
|
Storage::copy($files, $destination);
|
||||||
|
|
||||||
|
return $destination;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
Log::error('downloadable fileOrUrlUpload log: '. $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* upload link file or url
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Contracts\ImportProduct $dataFlowProfileRecord
|
||||||
|
* @param string $type
|
||||||
|
* @param string|array $file
|
||||||
|
* @param integer $id
|
||||||
|
* @param array $downloadableLinks
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function linkFileOrUrlUpload($dataFlowProfileRecord, $type, $file, $id, $downloadableLinks)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (trim($type) == "file") {
|
||||||
|
$files = "imported-products/extracted-images/admin/link-files/".$dataFlowProfileRecord->id.'/'. $downloadableLinks['uploadLinkFilesZipName']['dirname'].'/'.trim(basename($file));
|
||||||
|
|
||||||
|
$destination = "product_downloadable_links/".$id.'/'.basename($file);
|
||||||
|
|
||||||
|
Storage::copy($files, $destination);
|
||||||
|
|
||||||
|
return $destination;
|
||||||
|
} else {
|
||||||
|
$imagePath = storage_path('app/public/imported-products/extracted-images/admin/link-files/'.$dataFlowProfileRecord->id);
|
||||||
|
|
||||||
|
if (!file_exists($imagePath)) {
|
||||||
|
mkdir($imagePath, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageFile = $imagePath.'/'.basename($file);
|
||||||
|
|
||||||
|
file_put_contents($imageFile, file_get_contents(trim($file)));
|
||||||
|
|
||||||
|
$files = "imported-products/extracted-images/admin/link-files/".$dataFlowProfileRecord->id.'/'.basename($file);
|
||||||
|
|
||||||
|
$destination = "product_downloadable_links/".$id.'/'.basename($file);
|
||||||
|
|
||||||
|
Storage::copy($files, $destination);
|
||||||
|
|
||||||
|
return $destination;
|
||||||
|
}
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
Log::error('downloadable linkFileOrUrlUpload log: '. $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unzip zip files and store in storage folder
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Contracts\ImportProduct $record
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function extractDownloadableFiles($record)
|
||||||
|
{
|
||||||
|
if (isset($record->upload_link_files) && ($record->upload_link_files != "") ) {
|
||||||
|
$uploadLinkFilesZip = new \ZipArchive();
|
||||||
|
|
||||||
|
$extractedPath = storage_path('app/public/imported-products/extracted-images/admin/link-files/'.$record->id.'/');
|
||||||
|
|
||||||
|
if ($uploadLinkFilesZip->open(storage_path('app/public/'.$record->upload_link_files))) {
|
||||||
|
for ($i = 0; $i < $uploadLinkFilesZip->numFiles; $i++) {
|
||||||
|
$filename = $uploadLinkFilesZip->getNameIndex($i);
|
||||||
|
$uploadLinkFilesZipName = pathinfo($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
$uploadLinkFilesZip->extractTo($extractedPath);
|
||||||
|
$uploadLinkFilesZip->close();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$uploadLinkFilesZipName = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($record->upload_sample_files) && ($record->upload_sample_files != "") ) {
|
||||||
|
$uploadSampleFilesZip = new \ZipArchive();
|
||||||
|
|
||||||
|
$extractedPath = storage_path('app/public/imported-products/extracted-images/admin/sample-files/'.$record->id.'/');
|
||||||
|
|
||||||
|
if ($uploadSampleFilesZip->open(storage_path('app/public/'.$record->upload_sample_files))) {
|
||||||
|
for ($i = 0; $i < $uploadSampleFilesZip->numFiles; $i++) {
|
||||||
|
$filename = $uploadSampleFilesZip->getNameIndex($i);
|
||||||
|
$uploadSampleFilesZipName = pathinfo($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
$uploadSampleFilesZip->extractTo($extractedPath);
|
||||||
|
$uploadSampleFilesZip->close();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$uploadSampleFilesZipName = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($record->upload_link_sample_files) && ($record->upload_link_sample_files != "") ) {
|
||||||
|
$uploadLinkSampleFilesZip = new \ZipArchive();
|
||||||
|
|
||||||
|
$extractedPath = storage_path('app/public/imported-products/extracted-images/admin/link-sample-files/'.$record->id.'/');
|
||||||
|
|
||||||
|
if ($uploadLinkSampleFilesZip->open(storage_path('app/public/'.$record->upload_link_sample_files))) {
|
||||||
|
for ($i = 0; $i < $uploadLinkSampleFilesZip->numFiles; $i++) {
|
||||||
|
$filename = $uploadLinkSampleFilesZip->getNameIndex($i);
|
||||||
|
$uploadLinkSampleFilesZipName = pathinfo($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
$uploadLinkSampleFilesZip->extractTo($extractedPath);
|
||||||
|
$uploadLinkSampleFilesZip->close();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$uploadLinkSampleFilesZipName = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'uploadLinkSampleFilesZipName' => $uploadLinkSampleFilesZipName, 'uploadSampleFilesZipName' => $uploadSampleFilesZipName,
|
||||||
|
'uploadLinkFilesZipName' => $uploadLinkFilesZipName
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,440 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Repositories\Products;
|
||||||
|
|
||||||
|
use Storage;
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
use Webkul\Admin\Imports\DataGridImport;
|
||||||
|
use Webkul\Category\Repositories\CategoryRepository;
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ImportProductRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductFlatRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeFamilyRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\HelperRepository;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Webkul\Bulkupload\Repositories\ProductImageRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeOptionRepository;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Webkul\Product\Repositories\ProductCustomerGroupPriceRepository;
|
||||||
|
|
||||||
|
class GroupedProductRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ImportProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ImportProductRepository
|
||||||
|
*/
|
||||||
|
protected $importProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CategoryRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Category\Repositories\CategoryRepository
|
||||||
|
*/
|
||||||
|
protected $categoryRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductFlatRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductFlatRepository
|
||||||
|
*/
|
||||||
|
protected $productFlatRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductRepository
|
||||||
|
*/
|
||||||
|
protected $productRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeFamilyRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeFamilyRepository
|
||||||
|
*/
|
||||||
|
protected $attributeFamilyRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HelperRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\HelperRepository
|
||||||
|
*/
|
||||||
|
protected $helperRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductImageRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ProductImageRepository
|
||||||
|
*/
|
||||||
|
protected $productImageRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeOptionRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeOptionRepository
|
||||||
|
*/
|
||||||
|
protected $attributeOptionRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new repository instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ImportProductRepository $importProductRepository
|
||||||
|
* @param \Webkul\Category\Repositories\CategoryRepository $categoryRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductFlatRepository $productFlatRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\HelperRepository $helperRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ProductImageRepository $productImageRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeOptionRepository $attributeOptionRepository
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ImportProductRepository $importProductRepository,
|
||||||
|
CategoryRepository $categoryRepository,
|
||||||
|
ProductFlatRepository $productFlatRepository,
|
||||||
|
ProductRepository $productRepository,
|
||||||
|
AttributeFamilyRepository $attributeFamilyRepository,
|
||||||
|
HelperRepository $helperRepository,
|
||||||
|
ProductImageRepository $productImageRepository,
|
||||||
|
AttributeOptionRepository $attributeOptionRepository
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->importProductRepository = $importProductRepository;
|
||||||
|
|
||||||
|
$this->categoryRepository = $categoryRepository;
|
||||||
|
|
||||||
|
$this->productFlatRepository = $productFlatRepository;
|
||||||
|
|
||||||
|
$this->attributeOptionRepository = $attributeOptionRepository;
|
||||||
|
|
||||||
|
$this->productRepository = $productRepository;
|
||||||
|
|
||||||
|
$this->productImageRepository = $productImageRepository;
|
||||||
|
|
||||||
|
$this->attributeFamilyRepository = $attributeFamilyRepository;
|
||||||
|
|
||||||
|
$this->helperRepository = $helperRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Product\Contracts\Product';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create & update grouped-type product
|
||||||
|
*
|
||||||
|
* @param array $requestData
|
||||||
|
* @param array $imageZipName
|
||||||
|
* @param array $product
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function createProduct($requestData, $imageZipName)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$dataFlowProfileRecord = $this->importProductRepository->findOneByField
|
||||||
|
('data_flow_profile_id', $requestData['data_flow_profile_id']);
|
||||||
|
|
||||||
|
$csvData = (new DataGridImport)->toArray($dataFlowProfileRecord->file_path)[0];
|
||||||
|
|
||||||
|
if ($requestData['totalNumberOfCSVRecord'] < 1000) {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/10);
|
||||||
|
} else {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/100);
|
||||||
|
}
|
||||||
|
|
||||||
|
$uptoProcessCSVRecords = (int)$requestData['countOfStartedProfiles'] + 10;
|
||||||
|
$processRecords = (int)$requestData['countOfStartedProfiles'] + (int)$requestData['numberOfCSVRecord'];
|
||||||
|
|
||||||
|
$inventory = [];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] > $processCSVRecords) {
|
||||||
|
for ($i = $requestData['countOfStartedProfiles']; $i < $uptoProcessCSVRecords; $i++) {
|
||||||
|
$invalidateProducts = $this->store($csvData[$i], $i, $dataFlowProfileRecord, $requestData, $imageZipName);
|
||||||
|
|
||||||
|
if (isset($invalidateProducts) && !empty($invalidateProducts)) {
|
||||||
|
return $invalidateProducts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ($requestData['numberOfCSVRecord'] <= 10) {
|
||||||
|
for ($i = $requestData['countOfStartedProfiles']; $i < $processRecords; $i++) {
|
||||||
|
$invalidateProducts = $this->store($csvData[$i], $i, $dataFlowProfileRecord, $requestData, $imageZipName);
|
||||||
|
|
||||||
|
if (isset($invalidateProducts) && !empty($invalidateProducts)) {
|
||||||
|
return $invalidateProducts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] > 10) {
|
||||||
|
$remainDataInCSV = (int)$requestData['numberOfCSVRecord'] - (int)$processCSVRecords;
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
|
||||||
|
if($requestData['errorCount'] > 0) {
|
||||||
|
$uptoProcessCSVRecords = $requestData['totalNumberOfCSVRecord'] - $requestData['errorCount'];
|
||||||
|
} else {
|
||||||
|
$uptoProcessCSVRecords = $processRecords;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $i;
|
||||||
|
|
||||||
|
$dataToBeReturn = [
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $uptoProcessCSVRecords,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
];
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
Log::error('grouped create product log: '. $e->getMessage());
|
||||||
|
|
||||||
|
$categoryError = explode('[' ,$e->getMessage());
|
||||||
|
$categorySlugError = explode(']' ,$e->getMessage());
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
$productsUploaded = $i - $requestData['errorCount'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] != 0) {
|
||||||
|
$remainDataInCSV = (int)$requestData['totalNumberOfCSVRecord'] - (int)$requestData['countOfStartedProfiles'];
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($categoryError[0] == "No query results for model ") {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => "Invalid Category Slug: " . $categorySlugError[1],
|
||||||
|
);
|
||||||
|
$categoryError[0] = null;
|
||||||
|
} else if (isset($e->errorInfo)) {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->errorInfo[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function to store product
|
||||||
|
*
|
||||||
|
* @param array $csvData
|
||||||
|
* @param integer $i
|
||||||
|
* @param \Webkul\Bulkupload\Contracts\ImportProduct $dataFlowProfileRecord
|
||||||
|
* @param array $requestData
|
||||||
|
* @param array $imageZipName
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function store($csvData, $i, $dataFlowProfileRecord, $requestData, $imageZipName)
|
||||||
|
{
|
||||||
|
$createValidation = $this->helperRepository->createProductValidation($csvData, $i);
|
||||||
|
|
||||||
|
if (isset($createValidation)) {
|
||||||
|
return $createValidation;
|
||||||
|
}
|
||||||
|
|
||||||
|
$productFlatData = $this->productFlatRepository->findWhere(['sku' => $csvData['sku'], 'url_key' => $csvData['url_key']])->first();
|
||||||
|
|
||||||
|
$productData = $this->productRepository->findWhere(['sku' => $csvData['sku']])->first();
|
||||||
|
|
||||||
|
$attributeFamilyData = $this->attributeFamilyRepository->findOneByfield(['name' => $csvData['attribute_family_name']]);
|
||||||
|
|
||||||
|
if (! isset($productFlatData) && empty($productFlatData)) {
|
||||||
|
$data['type'] = $csvData['type'];
|
||||||
|
$data['attribute_family_id'] = $attributeFamilyData->id;
|
||||||
|
$data['sku'] = $csvData['sku'];
|
||||||
|
|
||||||
|
$groupedProduct = $this->productRepository->create($data);
|
||||||
|
} else {
|
||||||
|
$groupedProduct = $productData;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data);
|
||||||
|
$data = [];
|
||||||
|
$attributeCode = [];
|
||||||
|
$attributeValue = [];
|
||||||
|
|
||||||
|
//default attributes
|
||||||
|
foreach ($groupedProduct->getTypeInstance()->getEditableAttributes()->toArray() as $key => $value) {
|
||||||
|
$searchIndex = $value['code'];
|
||||||
|
|
||||||
|
if (array_key_exists($searchIndex, $csvData)) {
|
||||||
|
if (is_null($csvData[$searchIndex])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($attributeCode, $searchIndex);
|
||||||
|
|
||||||
|
if ($searchIndex == "color" || $searchIndex == "size" || $searchIndex == "brand") {
|
||||||
|
$attributeOption = $this->attributeOptionRepository->findOneByField(['admin_name' => ucwords($csvData[$searchIndex])]);
|
||||||
|
|
||||||
|
array_push($attributeValue, $attributeOption['id']);
|
||||||
|
} else {
|
||||||
|
array_push($attributeValue, $csvData[$searchIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array_combine($attributeCode, $attributeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['dataFlowProfileRecordId'] = $dataFlowProfileRecord->id;
|
||||||
|
|
||||||
|
$categoryData = explode(',', $csvData['categories_slug']);
|
||||||
|
|
||||||
|
if (is_null($csvData['categories_slug']) || empty($csvData['categories_slug'])) {
|
||||||
|
$categoryID = $this->categoryRepository->findBySlugOrFail('root')->id;
|
||||||
|
} else {
|
||||||
|
foreach ($categoryData as $key => $value) {
|
||||||
|
$categoryID[$key] = $this->categoryRepository->findBySlugOrFail($categoryData[$key])->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['categories'] = $categoryID;
|
||||||
|
$data['channel'] = core()->getCurrentChannel()->code;
|
||||||
|
|
||||||
|
$dataProfile = app('Webkul\Bulkupload\Repositories\DataFlowProfileRepository')->findOneByfield(['id' => $data['dataFlowProfileRecordId']]);
|
||||||
|
$data['locale'] = $dataProfile->locale_code;
|
||||||
|
|
||||||
|
//customerGroupPricing
|
||||||
|
if (isset($csvData['customer_group_prices']) && ! empty($csvData['customer_group_prices'])) {
|
||||||
|
$data['customer_group_prices'] = json_decode($csvData['customer_group_prices'], true);
|
||||||
|
app(ProductCustomerGroupPriceRepository::class)->saveCustomerGroupPrices($data, $simpleproductData);
|
||||||
|
}
|
||||||
|
|
||||||
|
//grouped product links
|
||||||
|
if (isset($csvData['grouped_product_sku'])) {
|
||||||
|
$groupedProductSku = explode(",", strtolower($csvData['grouped_product_sku']));
|
||||||
|
$groupedQuantity = explode(",", $csvData['grouped_quantity']);
|
||||||
|
$groupedSortOrder = explode(",", $csvData['grouped_sort_order']);
|
||||||
|
|
||||||
|
for ($j = 0; $j < count($groupedProductSku); $j++) {
|
||||||
|
$link = $j+1;
|
||||||
|
|
||||||
|
$variants = true;
|
||||||
|
|
||||||
|
$associatedProducts = $this->productRepository->findOneByField(['sku' => strtolower(trim($groupedProductSku[$j]))]);
|
||||||
|
|
||||||
|
if (isset($associatedProducts) && !empty($associatedProducts)) {
|
||||||
|
if (isset($associatedProducts->parent_id)) {
|
||||||
|
$groupedLink['link_'.$link] = [
|
||||||
|
"associated_product_id" => $associatedProducts->id,
|
||||||
|
"qty" => $groupedQuantity[$j],
|
||||||
|
"sort_order" => $groupedSortOrder[$j],
|
||||||
|
];
|
||||||
|
} else if ($associatedProducts->type == "simple") {
|
||||||
|
$groupedLink['link_'.$link] = [
|
||||||
|
"associated_product_id" => $associatedProducts->id,
|
||||||
|
"qty" => $groupedQuantity[$j],
|
||||||
|
"sort_order" => $groupedSortOrder[$j],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($groupedLink) && !empty($groupedLink)) {
|
||||||
|
$data['links'] = $groupedLink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Product Images
|
||||||
|
$individualProductimages = explode(',', $csvData['images']);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$images = Storage::disk('local')->files('public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id.'/'.$imageZipName['dirname'].'/');
|
||||||
|
|
||||||
|
foreach ($images as $imageArraykey => $imagePath) {
|
||||||
|
$imageName = explode('/', $imagePath);
|
||||||
|
|
||||||
|
if (in_array(last($imageName), preg_replace('/[\'"]/', '',$individualProductimages))) {
|
||||||
|
$data['images'][$imageArraykey] = $imagePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
foreach ($individualProductimages as $imageArraykey => $imageURL)
|
||||||
|
{
|
||||||
|
if (filter_var(trim($imageURL), FILTER_VALIDATE_URL)) {
|
||||||
|
$imagePath = storage_path('app/public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id);
|
||||||
|
|
||||||
|
if (!file_exists($imagePath)) {
|
||||||
|
mkdir($imagePath, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageFile = $imagePath.'/'.basename($imageURL);
|
||||||
|
|
||||||
|
file_put_contents($imageFile, file_get_contents(trim($imageURL)));
|
||||||
|
|
||||||
|
$data['images'][$imageArraykey] = $imageFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$validationRules = $this->helperRepository->validateCSV($requestData['data_flow_profile_id'], $data, $dataFlowProfileRecord, $groupedProduct);
|
||||||
|
|
||||||
|
$csvValidator = Validator::make($data, $validationRules);
|
||||||
|
|
||||||
|
if ($csvValidator->fails()) {
|
||||||
|
$errors = $csvValidator->errors()->getMessages();
|
||||||
|
|
||||||
|
$this->helperRepository->deleteProductIfNotValidated($groupedProduct->id);
|
||||||
|
|
||||||
|
foreach ($errors as $key => $error) {
|
||||||
|
if ($error[0] == "The url key has already been taken.") {
|
||||||
|
$errorToBeReturn[] = "The url key " . $data['url_key'] . " has already been taken";
|
||||||
|
} else {
|
||||||
|
$errorToBeReturn[] = str_replace(".", "", $error[0]). " for sku " . $data['sku'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
|
||||||
|
$productsUploaded = $i - $requestData['errorCount'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] != 0) {
|
||||||
|
$remainDataInCSV = (int)$requestData['totalNumberOfCSVRecord'] - (int)$requestData['countOfStartedProfiles'];
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $errorToBeReturn,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->productRepository->update($data, $groupedProduct->id);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $groupedProduct, $imageZipName);
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $groupedProduct, $imageZipName = null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,217 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Repositories\Products;
|
||||||
|
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Webkul\Product\Models\ProductAttributeValue;
|
||||||
|
use Webkul\Product\Repositories\ProductRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductFlatRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\DataFlowProfileRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||||
|
|
||||||
|
class HelperRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* DataFlowProfileRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\DataFlowProfileRepository
|
||||||
|
*/
|
||||||
|
protected $dataFlowProfileRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductFlatRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductFlatRepository
|
||||||
|
*/
|
||||||
|
protected $productFlatRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductRepository
|
||||||
|
*/
|
||||||
|
protected $productRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductAttributeValueRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductAttributeValueRepository
|
||||||
|
*/
|
||||||
|
protected $productAttributeValueRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new repository instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\DataFlowProfileRepository $dataFlowProfileRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $productAttributeValueRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductFlatRepository $productFlatRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
DataFlowProfileRepository $dataFlowProfileRepository,
|
||||||
|
ProductAttributeValueRepository $productAttributeValueRepository,
|
||||||
|
ProductFlatRepository $productFlatRepository,
|
||||||
|
ProductRepository $productRepository
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->dataFlowProfileRepository = $dataFlowProfileRepository;
|
||||||
|
|
||||||
|
$this->productAttributeValueRepository = $productAttributeValueRepository;
|
||||||
|
|
||||||
|
$this->productFlatRepository = $productFlatRepository;
|
||||||
|
|
||||||
|
$this->productRepository = $productRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Product\Contracts\Product';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validation Rules for creating product
|
||||||
|
*
|
||||||
|
* @param integer $dataFlowProfileId
|
||||||
|
* @param array $records
|
||||||
|
* @param \Webkul\Bulkupload\Contracts\ImportProduct $dataFlowProfileRecord
|
||||||
|
* @param \Webkul\Product\Contracts\Product $product
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function validateCSV($dataFlowProfileId, $records, $dataFlowProfileRecord, $product)
|
||||||
|
{
|
||||||
|
$messages = [];
|
||||||
|
$rules = [];
|
||||||
|
|
||||||
|
$profiler = $this->dataFlowProfileRepository->findOneByField('id', $dataFlowProfileId);
|
||||||
|
|
||||||
|
if ($dataFlowProfileRecord) {
|
||||||
|
foreach($records as $data) {
|
||||||
|
$this->rules = array_merge($product->getTypeInstance()->getTypeValidationRules(), [
|
||||||
|
'sku' => ['required', 'unique:products,sku,' . $product->id, new \Webkul\Core\Contracts\Validations\Slug],
|
||||||
|
'special_price_from' => 'nullable|date',
|
||||||
|
'special_price_to' => 'nullable|date|after_or_equal:special_price_from',
|
||||||
|
'special_price' => ['nullable', new \Webkul\Core\Contracts\Validations\Decimal, 'lt:price'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
foreach ($product->getEditableAttributes() as $attribute) {
|
||||||
|
if ($attribute->code == 'sku' || $attribute->type == 'boolean') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$validations = [];
|
||||||
|
|
||||||
|
if (! isset($this->rules[$attribute->code])) {
|
||||||
|
array_push($validations, $attribute->is_required ? 'required' : 'nullable');
|
||||||
|
} else {
|
||||||
|
$validations = $this->rules[$attribute->code];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($attribute->type == 'text' && $attribute->validation) {
|
||||||
|
array_push($validations,
|
||||||
|
$attribute->validation == 'decimal'
|
||||||
|
? new \Webkul\Core\Contracts\Validations\Decimal
|
||||||
|
: $attribute->validation
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($attribute->type == 'price') {
|
||||||
|
array_push($validations, new \Webkul\Core\Contracts\Validations\Decimal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($attribute->is_unique) {
|
||||||
|
$this->id = $product;
|
||||||
|
|
||||||
|
array_push($validations, function ($field, $value, $fail) use ($attribute) {
|
||||||
|
$column = ProductAttributeValue::$attributeTypeFields[$attribute->type];
|
||||||
|
|
||||||
|
if (! $this->productAttributeValueRepository->isValueUnique($this->id, $attribute->id, $column, request($attribute->code))) {
|
||||||
|
$fail('The :attribute has already been taken.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->rules[$attribute->code] = $validations;
|
||||||
|
}
|
||||||
|
|
||||||
|
$validationCheckForUpdateData = $this->productFlatRepository
|
||||||
|
->findWhere(['sku' => $records['sku'], 'url_key' => $records['url_key']]);
|
||||||
|
|
||||||
|
if (is_null($validationCheckForUpdateData) || empty($validationCheckForUpdateData)) {
|
||||||
|
$urlKeyUniqueness = "unique:product_flat,url_key";
|
||||||
|
array_push($this->rules["url_key"], $urlKeyUniqueness);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->rules;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete Product if validation fails
|
||||||
|
*
|
||||||
|
* @param integer $id
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function deleteProductIfNotValidated($id)
|
||||||
|
{
|
||||||
|
$this->productRepository->findOrFail($id)->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validation check for product creation
|
||||||
|
*
|
||||||
|
* @param array $record
|
||||||
|
* @param integer $loopCount
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function createProductValidation($record, $loopCount)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$validateProduct = Validator::make($record, [
|
||||||
|
'type' => 'required',
|
||||||
|
'sku' => 'required',
|
||||||
|
'attribute_family_name' => 'required'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ( $validateProduct->fails() ) {
|
||||||
|
$errors = $validateProduct->errors()->getMessages();
|
||||||
|
|
||||||
|
foreach($errors as $key => $error) {
|
||||||
|
$recordCount = (int)$loopCount + (int)1;
|
||||||
|
|
||||||
|
$errorToBeReturn[] = str_replace(".", "", $error[0]) . " for record " . $recordCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
request()->countOfStartedProfiles = $loopCount + 1;
|
||||||
|
|
||||||
|
$productsUploaded = $loopCount - request()->errorCount;
|
||||||
|
|
||||||
|
if (request()->numberOfCSVRecord != 0) {
|
||||||
|
$remainDataInCSV = (int)request()->totalNumberOfCSVRecord - (int)request()->countOfStartedProfiles;
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => request()->countOfStartedProfiles,
|
||||||
|
'error' => $errorToBeReturn,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} catch(\EXception $e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,452 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Repositories\Products;
|
||||||
|
|
||||||
|
use Storage;
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
use Webkul\Admin\Imports\DataGridImport;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
use Webkul\Category\Repositories\CategoryRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ImportProductRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductFlatRepository;
|
||||||
|
use Webkul\Inventory\Repositories\InventorySourceRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeFamilyRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\HelperRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeOptionRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ProductImageRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductCustomerGroupPriceRepository;
|
||||||
|
|
||||||
|
class SimpleProductRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ImportProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ImportProductRepository
|
||||||
|
*/
|
||||||
|
protected $importProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CategoryRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Category\Repositories\CategoryRepository
|
||||||
|
*/
|
||||||
|
protected $categoryRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductFlatRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductFlatRepository
|
||||||
|
*/
|
||||||
|
protected $productFlatRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductRepository
|
||||||
|
*/
|
||||||
|
protected $productRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeFamilyRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeFamilyRepository
|
||||||
|
*/
|
||||||
|
protected $attributeFamilyRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HelperRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\HelperRepository
|
||||||
|
*/
|
||||||
|
protected $helperRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductImageRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ProductImageRepository
|
||||||
|
*/
|
||||||
|
protected $productImageRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeOptionRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeOptionRepository
|
||||||
|
*/
|
||||||
|
protected $attributeOptionRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InventorySourceRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Inventory\Repositories\InventorySourceRepository
|
||||||
|
*/
|
||||||
|
protected $inventorySourceRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new repository instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ImportProductRepository $importProductRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeOptionRepository $attributeOptionRepository
|
||||||
|
* @param \Webkul\Category\Repositories\CategoryRepository $categoryRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductFlatRepository $productFlatRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\HelperRepository $helperRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ProductImageRepository $productImageRepository
|
||||||
|
* @param \Webkul\Inventory\Repositories\InventorySourceRepository $inventorySourceRepository
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ImportProductRepository $importProductRepository,
|
||||||
|
AttributeOptionRepository $attributeOptionRepository,
|
||||||
|
CategoryRepository $categoryRepository,
|
||||||
|
ProductFlatRepository $productFlatRepository,
|
||||||
|
ProductRepository $productRepository,
|
||||||
|
AttributeFamilyRepository $attributeFamilyRepository,
|
||||||
|
HelperRepository $helperRepository,
|
||||||
|
ProductImageRepository $productImageRepository,
|
||||||
|
InventorySourceRepository $inventorySourceRepository
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->importProductRepository = $importProductRepository;
|
||||||
|
|
||||||
|
$this->categoryRepository = $categoryRepository;
|
||||||
|
|
||||||
|
$this->attributeOptionRepository = $attributeOptionRepository;
|
||||||
|
|
||||||
|
$this->productFlatRepository = $productFlatRepository;
|
||||||
|
|
||||||
|
$this->productRepository = $productRepository;
|
||||||
|
|
||||||
|
$this->productImageRepository = $productImageRepository;
|
||||||
|
|
||||||
|
$this->attributeFamilyRepository = $attributeFamilyRepository;
|
||||||
|
|
||||||
|
$this->helperRepository = $helperRepository;
|
||||||
|
|
||||||
|
$this->inventorySourceRepository = $inventorySourceRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Product\Contracts\Product';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create & update simple-type product
|
||||||
|
*
|
||||||
|
* @param array $requestData
|
||||||
|
* @param array $imageZipName
|
||||||
|
* @param array $product
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function createProduct($requestData, $imageZipName, $product)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$inventory = [];
|
||||||
|
|
||||||
|
$dataFlowProfileRecord = $this->importProductRepository->findOneByField
|
||||||
|
('data_flow_profile_id', $requestData['data_flow_profile_id']);
|
||||||
|
|
||||||
|
$csvData = (new DataGridImport)->toArray($dataFlowProfileRecord->file_path)[0];
|
||||||
|
|
||||||
|
if ($requestData['totalNumberOfCSVRecord'] < 1000) {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/10);
|
||||||
|
} else {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/100);
|
||||||
|
}
|
||||||
|
|
||||||
|
$uptoProcessCSVRecords = (int)$requestData['countOfStartedProfiles'] + 10;
|
||||||
|
|
||||||
|
$processRecords = (int)$requestData['countOfStartedProfiles'] + (int)$requestData['numberOfCSVRecord'];
|
||||||
|
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] > $processCSVRecords) {
|
||||||
|
for ($i = $requestData['countOfStartedProfiles']; $i < $uptoProcessCSVRecords; $i++) {
|
||||||
|
$invalidateProducts = $this->store($csvData[$i], $i, $dataFlowProfileRecord, $requestData, $imageZipName);
|
||||||
|
|
||||||
|
if (isset($invalidateProducts) && !empty($invalidateProducts)) {
|
||||||
|
return $invalidateProducts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ($requestData['numberOfCSVRecord'] <= 10) {
|
||||||
|
for ($i = $requestData['countOfStartedProfiles']; $i < $processRecords; $i++) {
|
||||||
|
$invalidateProducts = $this->store($csvData[$i], $i, $dataFlowProfileRecord, $requestData, $imageZipName);
|
||||||
|
|
||||||
|
if (isset($invalidateProducts) && !empty($invalidateProducts)) {
|
||||||
|
return $invalidateProducts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] > 10) {
|
||||||
|
$remainDataInCSV = (int)$requestData['numberOfCSVRecord'] - (int)$processCSVRecords;
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
|
||||||
|
if($requestData['errorCount'] > 0) {
|
||||||
|
$uptoProcessCSVRecords = $requestData['totalNumberOfCSVRecord'] - $requestData['errorCount'];
|
||||||
|
} else {
|
||||||
|
$uptoProcessCSVRecords = $processRecords;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $i;
|
||||||
|
|
||||||
|
$dataToBeReturn = [
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $uptoProcessCSVRecords,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
];
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('simple create product log: '. $e->getMessage());
|
||||||
|
|
||||||
|
$categoryError = explode('[' ,$e->getMessage());
|
||||||
|
$categorySlugError = explode(']' ,$e->getMessage());
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
$productsUploaded = $i - $requestData['errorCount'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] != 0) {
|
||||||
|
$remainDataInCSV = (int)$requestData['totalNumberOfCSVRecord'] - (int)$requestData['countOfStartedProfiles'];
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($categoryError[0] == "No query results for model ") {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => "Invalid Category Slug: " . $categorySlugError[1],
|
||||||
|
);
|
||||||
|
$categoryError[0] = null;
|
||||||
|
} else if (isset($e->errorInfo)) {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->errorInfo[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function to store product
|
||||||
|
*
|
||||||
|
* @param array $csvData
|
||||||
|
* @param integer $i
|
||||||
|
* @param \Webkul\Bulkupload\Contracts\ImportProduct $dataFlowProfileRecord
|
||||||
|
* @param array $requestData
|
||||||
|
* @param array $imageZipName
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function store($csvData, $i, $dataFlowProfileRecord, $requestData, $imageZipName)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$createValidation = $this->helperRepository->createProductValidation($csvData, $i);
|
||||||
|
|
||||||
|
if (isset($createValidation)) {
|
||||||
|
return $createValidation;
|
||||||
|
}
|
||||||
|
|
||||||
|
$productFlatData = $this->productFlatRepository->findWhere(['sku' => $csvData['sku'], 'url_key' => $csvData['url_key']])->first();
|
||||||
|
|
||||||
|
$productData = $this->productRepository->findWhere(['sku' => $csvData['sku']])->first();
|
||||||
|
|
||||||
|
$attributeFamilyData = $this->attributeFamilyRepository->findOneByfield(['name' => $csvData['attribute_family_name']]);
|
||||||
|
|
||||||
|
if (! isset($productFlatData) && empty($productFlatData)) {
|
||||||
|
$data['type'] = $csvData['type'];
|
||||||
|
$data['attribute_family_id'] = $attributeFamilyData->id;
|
||||||
|
$data['sku'] = $csvData['sku'];
|
||||||
|
|
||||||
|
$simpleproductData = $this->productRepository->create($data);
|
||||||
|
} else {
|
||||||
|
$simpleproductData = $productData;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data);
|
||||||
|
$data = [];
|
||||||
|
$attributeCode = [];
|
||||||
|
$attributeValue = [];
|
||||||
|
|
||||||
|
//default attributes
|
||||||
|
foreach ($simpleproductData->getTypeInstance()->getEditableAttributes()->toArray() as $key => $value) {
|
||||||
|
$attributeOptionArray = array();
|
||||||
|
$searchIndex = strtolower($value['code']);
|
||||||
|
|
||||||
|
if (array_key_exists($searchIndex, $csvData)) {
|
||||||
|
|
||||||
|
if (is_null($csvData[$searchIndex])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($attributeCode, $searchIndex);
|
||||||
|
|
||||||
|
if ($value['type'] == "select") {
|
||||||
|
$attributeOption = $this->attributeOptionRepository->findOneByField(['admin_name' => $csvData[$searchIndex]]);
|
||||||
|
|
||||||
|
array_push($attributeValue, $attributeOption['id']);
|
||||||
|
} else if ($value['type'] == "checkbox") {
|
||||||
|
$attributeOption = $this->attributeOptionRepository->findOneByField(['attribute_id' => $value['id'], 'admin_name' => $csvData[$searchIndex]]);
|
||||||
|
|
||||||
|
array_push($attributeOptionArray, $attributeOption['id']);
|
||||||
|
|
||||||
|
array_push($attributeValue, $attributeOptionArray);
|
||||||
|
unset($attributeOptionArray);
|
||||||
|
} else {
|
||||||
|
array_push($attributeValue, $csvData[$searchIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array_combine($attributeCode, $attributeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['dataFlowProfileRecordId'] = $dataFlowProfileRecord->id;
|
||||||
|
|
||||||
|
$inventorySource = $csvData['inventory_sources'];
|
||||||
|
$inventoryCode = explode(',', $inventorySource);
|
||||||
|
|
||||||
|
foreach ($inventoryCode as $key => $value) {
|
||||||
|
$inventoryId = $this->inventorySourceRepository->findOneByfield(['code' => trim($value)])->pluck('id')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
$inventoryData[] = (string)$csvData['inventories'];
|
||||||
|
|
||||||
|
foreach ($inventoryData as $key => $d) {
|
||||||
|
$inventoryQuantity = explode(',', trim($d));
|
||||||
|
|
||||||
|
if (count($inventoryId) != count($inventoryQuantity)) {
|
||||||
|
array_push($inventoryQuantity, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
$inventory = array_combine($inventoryId, $inventoryQuantity);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['inventories'] = $inventory;
|
||||||
|
|
||||||
|
$categoryData = explode(',', $csvData['categories_slug']);
|
||||||
|
|
||||||
|
if (is_null($csvData['categories_slug']) || empty($csvData['categories_slug'])) {
|
||||||
|
$categoryID = $this->categoryRepository->findBySlugOrFail('root')->id;
|
||||||
|
} else {
|
||||||
|
foreach ($categoryData as $key => $value) {
|
||||||
|
$categoryID[$key] = $this->categoryRepository->findBySlugOrFail($categoryData[$key])->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['categories'] = $categoryID;
|
||||||
|
$data['channel'] = core()->getCurrentChannel()->code;
|
||||||
|
|
||||||
|
$dataProfile = app('Webkul\Bulkupload\Repositories\DataFlowProfileRepository')->findOneByfield(['id' => $data['dataFlowProfileRecordId']]);
|
||||||
|
|
||||||
|
$data['locale'] = $dataProfile->locale_code;
|
||||||
|
|
||||||
|
//customerGroupPricing
|
||||||
|
if (isset($csvData['customer_group_prices']) && ! empty($csvData['customer_group_prices'])) {
|
||||||
|
$data['customer_group_prices'] = json_decode($csvData['customer_group_prices'], true);
|
||||||
|
app(ProductCustomerGroupPriceRepository::class)->saveCustomerGroupPrices($data, $simpleproductData);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Product Images
|
||||||
|
$individualProductimages = explode(',', $csvData['images']);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$images = Storage::disk('local')->files('public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id.'/'.$imageZipName['dirname'].'/');
|
||||||
|
|
||||||
|
foreach ($images as $imageArraykey => $imagePath) {
|
||||||
|
$imageName = explode('/', $imagePath);
|
||||||
|
|
||||||
|
if (in_array(last($imageName), preg_replace('/[\'"]/', '',$individualProductimages))) {
|
||||||
|
$data['images'][$imageArraykey] = $imagePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
foreach ($individualProductimages as $imageArraykey => $imageURL)
|
||||||
|
{
|
||||||
|
if (filter_var(trim($imageURL), FILTER_VALIDATE_URL)) {
|
||||||
|
$imagePath = storage_path('app/public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id);
|
||||||
|
|
||||||
|
if (!file_exists($imagePath)) {
|
||||||
|
mkdir($imagePath, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageFile = $imagePath.'/'.basename($imageURL);
|
||||||
|
|
||||||
|
file_put_contents($imageFile, file_get_contents(trim($imageURL)));
|
||||||
|
|
||||||
|
$data['images'][$imageArraykey] = $imageFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$returnRules = $this->helperRepository->validateCSV($requestData['data_flow_profile_id'], $data, $dataFlowProfileRecord, $simpleproductData);
|
||||||
|
|
||||||
|
$csvValidator = Validator::make($data, $returnRules);
|
||||||
|
|
||||||
|
if ($csvValidator->fails()) {
|
||||||
|
$errors = $csvValidator->errors()->getMessages();
|
||||||
|
|
||||||
|
$this->helperRepository->deleteProductIfNotValidated($simpleproductData->id);
|
||||||
|
|
||||||
|
foreach($errors as $key => $error) {
|
||||||
|
if ($error[0] == "The url key has already been taken.") {
|
||||||
|
$errorToBeReturn[] = "The url key " . $data['url_key'] . " has already been taken";
|
||||||
|
} else {
|
||||||
|
$errorToBeReturn[] = str_replace(".", "", $error[0]). " for sku " . $data['sku'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
|
||||||
|
$productsUploaded = $i - $requestData['errorCount'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] != 0) {
|
||||||
|
$remainDataInCSV = (int)$requestData['totalNumberOfCSVRecord'] - (int)$requestData['countOfStartedProfiles'];
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $errorToBeReturn,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
$configSimpleProductAttributeStore = $this->productRepository->update($data, $simpleproductData->id);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $simpleproductData, $imageZipName);
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $simpleproductData, $imageZipName = null);
|
||||||
|
}
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
\Log::error('simple product store function'. $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,440 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Bulkupload\Repositories\Products;
|
||||||
|
|
||||||
|
use Storage;
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
use Webkul\Admin\Imports\DataGridImport;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Webkul\Category\Repositories\CategoryRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ImportProductRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductFlatRepository;
|
||||||
|
use Webkul\Inventory\Repositories\InventorySourceRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeFamilyRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\Products\HelperRepository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeOptionRepository;
|
||||||
|
use Webkul\Bulkupload\Repositories\ProductImageRepository;
|
||||||
|
use Webkul\Product\Repositories\ProductCustomerGroupPriceRepository;
|
||||||
|
|
||||||
|
class VirtualProductRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ImportProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ImportProductRepository
|
||||||
|
*/
|
||||||
|
protected $importProductRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CategoryRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Category\Repositories\CategoryRepository
|
||||||
|
*/
|
||||||
|
protected $categoryRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductFlatRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductFlatRepository
|
||||||
|
*/
|
||||||
|
protected $productFlatRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Product\Repositories\ProductRepository
|
||||||
|
*/
|
||||||
|
protected $productRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeFamilyRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeFamilyRepository
|
||||||
|
*/
|
||||||
|
protected $attributeFamilyRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HelperRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\Products\HelperRepository
|
||||||
|
*/
|
||||||
|
protected $helperRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductImageRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Bulkupload\Repositories\ProductImageRepository
|
||||||
|
*/
|
||||||
|
protected $productImageRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeOptionRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Attribute\Repositories\AttributeOptionRepository
|
||||||
|
*/
|
||||||
|
protected $attributeOptionRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InventorySourceRepository object
|
||||||
|
*
|
||||||
|
* @var \Webkul\Inventory\Repositories\InventorySourceRepository
|
||||||
|
*/
|
||||||
|
protected $inventorySourceRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new repository instance.
|
||||||
|
*
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ImportProductRepository $importProductRepository
|
||||||
|
* @param \Webkul\Category\Repositories\CategoryRepository $categoryRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductFlatRepository $productFlatRepository
|
||||||
|
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\Products\HelperRepository $helperRepository
|
||||||
|
* @param \Webkul\Bulkupload\Repositories\ProductImageRepository $productImageRepository
|
||||||
|
* @param \Webkul\Attribute\Repositories\AttributeOptionRepository $attributeOptionRepository
|
||||||
|
* @param \Webkul\Inventory\Repositories\InventorySourceRepository $inventorySourceRepository
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ImportProductRepository $importProductRepository,
|
||||||
|
CategoryRepository $categoryRepository,
|
||||||
|
ProductFlatRepository $productFlatRepository,
|
||||||
|
ProductRepository $productRepository,
|
||||||
|
AttributeFamilyRepository $attributeFamilyRepository,
|
||||||
|
HelperRepository $helperRepository,
|
||||||
|
ProductImageRepository $productImageRepository,
|
||||||
|
AttributeOptionRepository $attributeOptionRepository,
|
||||||
|
InventorySourceRepository $inventorySourceRepository
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->importProductRepository = $importProductRepository;
|
||||||
|
|
||||||
|
$this->categoryRepository = $categoryRepository;
|
||||||
|
|
||||||
|
$this->productFlatRepository = $productFlatRepository;
|
||||||
|
|
||||||
|
$this->productRepository = $productRepository;
|
||||||
|
|
||||||
|
$this->productImageRepository = $productImageRepository;
|
||||||
|
|
||||||
|
$this->attributeFamilyRepository = $attributeFamilyRepository;
|
||||||
|
|
||||||
|
$this->helperRepository = $helperRepository;
|
||||||
|
|
||||||
|
$this->attributeOptionRepository = $attributeOptionRepository;
|
||||||
|
|
||||||
|
$this->inventorySourceRepository = $inventorySourceRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Product\Contracts\Product';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create & update virtual-type product
|
||||||
|
*
|
||||||
|
* @param array $requestData
|
||||||
|
* @param array $imageZipName
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function createProduct($requestData, $imageZipName)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$inventory = [];
|
||||||
|
|
||||||
|
$dataFlowProfileRecord = $this->importProductRepository->findOneByField
|
||||||
|
('data_flow_profile_id', $requestData['data_flow_profile_id']);
|
||||||
|
|
||||||
|
$csvData = (new DataGridImport)->toArray($dataFlowProfileRecord->file_path)[0];
|
||||||
|
|
||||||
|
if ($requestData['totalNumberOfCSVRecord'] < 1000) {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/10);
|
||||||
|
} else {
|
||||||
|
$processCSVRecords = $requestData['totalNumberOfCSVRecord']/($requestData['totalNumberOfCSVRecord']/100);
|
||||||
|
}
|
||||||
|
|
||||||
|
$uptoProcessCSVRecords = (int)$requestData['countOfStartedProfiles'] + 10;
|
||||||
|
$processRecords = (int)$requestData['countOfStartedProfiles'] + (int)$requestData['numberOfCSVRecord'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] > $processCSVRecords) {
|
||||||
|
for ($i = $requestData['countOfStartedProfiles']; $i < $uptoProcessCSVRecords; $i++) {
|
||||||
|
$invalidateProducts = $this->store($csvData[$i], $i, $dataFlowProfileRecord, $requestData, $imageZipName);
|
||||||
|
|
||||||
|
if (isset($invalidateProducts) && !empty($invalidateProducts)) {
|
||||||
|
return $invalidateProducts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ($requestData['numberOfCSVRecord'] <= 10) {
|
||||||
|
for ($i = $requestData['countOfStartedProfiles']; $i < $processRecords; $i++) {
|
||||||
|
$invalidateProducts = $this->store($csvData[$i], $i, $dataFlowProfileRecord, $requestData, $imageZipName);
|
||||||
|
|
||||||
|
if (isset($invalidateProducts) && !empty($invalidateProducts)) {
|
||||||
|
return $invalidateProducts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] > 10) {
|
||||||
|
$remainDataInCSV = (int)$requestData['numberOfCSVRecord'] - (int)$processCSVRecords;
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
|
||||||
|
if($requestData['errorCount'] > 0) {
|
||||||
|
$uptoProcessCSVRecords = $requestData['totalNumberOfCSVRecord'] - $requestData['errorCount'];
|
||||||
|
} else {
|
||||||
|
$uptoProcessCSVRecords = $processRecords;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $i;
|
||||||
|
|
||||||
|
$dataToBeReturn = [
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $uptoProcessCSVRecords,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
];
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
Log::error('virtual create product log: '. $e->getMessage());
|
||||||
|
|
||||||
|
$categoryError = explode('[' ,$e->getMessage());
|
||||||
|
$categorySlugError = explode(']' ,$e->getMessage());
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
$productsUploaded = $i - $requestData['errorCount'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] != 0) {
|
||||||
|
$remainDataInCSV = (int)$requestData['totalNumberOfCSVRecord'] - (int)$requestData['countOfStartedProfiles'];
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($categoryError[0] == "No query results for model ") {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => "Invalid Category Slug: " . $categorySlugError[1],
|
||||||
|
);
|
||||||
|
$categoryError[0] = null;
|
||||||
|
} else if (isset($e->errorInfo)) {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->errorInfo[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function to store product
|
||||||
|
*
|
||||||
|
* @param array $csvData
|
||||||
|
* @param integer $i
|
||||||
|
* @param \Webkul\Bulkupload\Contracts\ImportProduct $dataFlowProfileRecord
|
||||||
|
* @param array $requestData
|
||||||
|
* @param array $imageZipName
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function store($csvData, $i, $dataFlowProfileRecord, $requestData, $imageZipName)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$createValidation = $this->helperRepository->createProductValidation($csvData, $i);
|
||||||
|
|
||||||
|
if (isset($createValidation)) {
|
||||||
|
return $createValidation;
|
||||||
|
}
|
||||||
|
|
||||||
|
$productFlatData = $this->productFlatRepository->findWhere(['sku' => $csvData['sku'], 'url_key' => $csvData['url_key']])->first();
|
||||||
|
|
||||||
|
$productData = $this->productRepository->findWhere(['sku' => $csvData['sku']])->first();
|
||||||
|
|
||||||
|
$attributeFamilyData = $this->attributeFamilyRepository->findOneByfield(['name' => $csvData['attribute_family_name']]);
|
||||||
|
|
||||||
|
if (! isset($productFlatData) && empty($productFlatData)) {
|
||||||
|
$data['type'] = $csvData['type'];
|
||||||
|
$data['attribute_family_id'] = $attributeFamilyData->id;
|
||||||
|
$data['sku'] = $csvData['sku'];
|
||||||
|
|
||||||
|
$virtualProductData = $this->productRepository->create($data);
|
||||||
|
} else {
|
||||||
|
$virtualProductData = $productData;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data);
|
||||||
|
$data = [];
|
||||||
|
$attributeCode = [];
|
||||||
|
$attributeValue = [];
|
||||||
|
|
||||||
|
//default attributes
|
||||||
|
foreach ($virtualProductData->getTypeInstance()->getEditableAttributes()->toArray() as $key => $value) {
|
||||||
|
$searchIndex = $value['code'];
|
||||||
|
if (array_key_exists($searchIndex, $csvData)) {
|
||||||
|
if (is_null($csvData[$searchIndex])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($attributeCode, $searchIndex);
|
||||||
|
|
||||||
|
if ($searchIndex == "color" || $searchIndex == "size" || $searchIndex == "brand") {
|
||||||
|
$attributeOption = $this->attributeOptionRepository->findOneByField(['admin_name' => ucwords($csvData[$searchIndex])]);
|
||||||
|
|
||||||
|
array_push($attributeValue, $attributeOption['id']);
|
||||||
|
} else {
|
||||||
|
array_push($attributeValue, $csvData[$searchIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array_combine($attributeCode, $attributeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['dataFlowProfileRecordId'] = $dataFlowProfileRecord->id;
|
||||||
|
|
||||||
|
$inventorySource = $csvData['inventory_sources'];
|
||||||
|
$inventoryCode = explode(',', $inventorySource);
|
||||||
|
|
||||||
|
foreach ($inventoryCode as $key => $value) {
|
||||||
|
$inventoryId = $this->inventorySourceRepository->findOneByfield(['code' => trim($value)])->pluck('id')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
$inventoryData[] = (string)$csvData['inventories'];
|
||||||
|
|
||||||
|
foreach ($inventoryData as $key => $d) {
|
||||||
|
$inventoryQuantity = explode(',', trim($d));
|
||||||
|
|
||||||
|
if (count($inventoryId) != count($inventoryQuantity)) {
|
||||||
|
array_push($inventoryQuantity, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
$inventory = array_combine($inventoryId, $inventoryQuantity);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['inventories'] = $inventory;
|
||||||
|
|
||||||
|
$categoryData = explode(',', $csvData['categories_slug']);
|
||||||
|
|
||||||
|
if (is_null($csvData['categories_slug']) || empty($csvData['categories_slug'])) {
|
||||||
|
$categoryID = $this->categoryRepository->findBySlugOrFail('root')->id;
|
||||||
|
} else {
|
||||||
|
foreach ($categoryData as $key => $value) {
|
||||||
|
$categoryID[$key] = $this->categoryRepository->findBySlugOrFail($categoryData[$key])->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['categories'] = $categoryID;
|
||||||
|
$data['channel'] = core()->getCurrentChannel()->code;
|
||||||
|
|
||||||
|
$dataProfile = app('Webkul\Bulkupload\Repositories\DataFlowProfileRepository')->findOneByfield(['id' => $data['dataFlowProfileRecordId']]);
|
||||||
|
$data['locale'] = $dataProfile->locale_code;
|
||||||
|
|
||||||
|
//customerGroupPricing
|
||||||
|
if (isset($csvData['customer_group_prices']) && ! empty($csvData['customer_group_prices'])) {
|
||||||
|
$data['customer_group_prices'] = json_decode($csvData['customer_group_prices'], true);
|
||||||
|
app(ProductCustomerGroupPriceRepository::class)->saveCustomerGroupPrices($data, $simpleproductData);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Product Images
|
||||||
|
$individualProductimages = explode(',', $csvData['images']);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$images = Storage::disk('local')->files('public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id.'/'.$imageZipName['dirname'].'/');
|
||||||
|
|
||||||
|
foreach ($images as $imageArraykey => $imagePath) {
|
||||||
|
$imageName = explode('/', $imagePath);
|
||||||
|
|
||||||
|
if (in_array(last($imageName), preg_replace('/[\'"]/', '',$individualProductimages))) {
|
||||||
|
$data['images'][$imageArraykey] = $imagePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
foreach ($individualProductimages as $imageArraykey => $imageURL)
|
||||||
|
{
|
||||||
|
if (filter_var(trim($imageURL), FILTER_VALIDATE_URL)) {
|
||||||
|
$imagePath = storage_path('app/public/imported-products/extracted-images/admin/'.$dataFlowProfileRecord->id);
|
||||||
|
|
||||||
|
if (!file_exists($imagePath)) {
|
||||||
|
mkdir($imagePath, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageFile = $imagePath.'/'.basename($imageURL);
|
||||||
|
|
||||||
|
file_put_contents($imageFile, file_get_contents(trim($imageURL)));
|
||||||
|
|
||||||
|
$data['images'][$imageArraykey] = $imageFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//to check validation
|
||||||
|
$validationRules = $this->helperRepository->validateCSV($requestData['data_flow_profile_id'], $data, $dataFlowProfileRecord, $virtualProductData);
|
||||||
|
|
||||||
|
$csvValidator = Validator::make($data, $validationRules);
|
||||||
|
|
||||||
|
if ($csvValidator->fails()) {
|
||||||
|
$errors = $csvValidator->errors()->getMessages();
|
||||||
|
|
||||||
|
$this->helperRepository->deleteProductIfNotValidated($virtualProductData->id);
|
||||||
|
|
||||||
|
foreach($errors as $key => $error) {
|
||||||
|
if ($error[0] == "The url key has already been taken.") {
|
||||||
|
$errorToBeReturn[] = "The url key " . $data['url_key'] . " has already been taken";
|
||||||
|
} else {
|
||||||
|
$errorToBeReturn[] = str_replace(".", "", $error[0]) . " for sku " . $data['sku'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestData['countOfStartedProfiles'] = $i + 1;
|
||||||
|
|
||||||
|
$productsUploaded = $i - $requestData['errorCount'];
|
||||||
|
|
||||||
|
if ($requestData['numberOfCSVRecord'] != 0) {
|
||||||
|
$remainDataInCSV = (int)$requestData['totalNumberOfCSVRecord'] - (int)$requestData['countOfStartedProfiles'];
|
||||||
|
} else {
|
||||||
|
$remainDataInCSV = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataToBeReturn = array(
|
||||||
|
'remainDataInCSV' => $remainDataInCSV,
|
||||||
|
'productsUploaded' => $productsUploaded,
|
||||||
|
'countOfStartedProfiles' => $requestData['countOfStartedProfiles'],
|
||||||
|
'error' => $errorToBeReturn,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $dataToBeReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->productRepository->update($data, $virtualProductData->id);
|
||||||
|
|
||||||
|
if (isset($imageZipName)) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $virtualProductData, $imageZipName);
|
||||||
|
} else if (isset($csvData['images'])) {
|
||||||
|
$this->productImageRepository->bulkuploadImages($data, $virtualProductData, $imageZipName = null);
|
||||||
|
}
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
\Log::error('virtual product store function'. $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 51.1 (57501) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Icon-Bulk-Upload-Active</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Icon-Bulk-Upload-Active" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M12.9981102,12.047248 L37.9981102,12.0000018 C38.5503939,11.9989581 38.9989545,12.4458264 38.9999982,12.9981102 C38.9999994,12.9987401 39,12.9993701 39,13 L39,37.9962168 C39,38.5485015 38.5522847,38.9962168 38,38.9962168 C37.9993701,38.9962168 37.9987401,38.9962162 37.9981102,38.996215 L12.9981102,38.9489688 C12.4465643,38.9479265 12,38.5005175 12,37.9489706 L12,13.0472462 C12,12.4956993 12.4465643,12.0482903 12.9981102,12.047248 Z" id="Rectangle-15" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<path d="M9,33.9508587 L9,11.0453581 C9,9.94226441 9.89312856,9.04744638 10.9962203,9.04536171 L33.9962203,9.00189524" id="Path" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<path d="M12,17.202381 L39,17.202381" id="Path-29" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<path d="M31.25,31 L31.25,35" id="Path-30-Copy-2" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<path d="M34.25,31 L34.25,35" id="Path-30-Copy-3" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<path d="M26,22 L26,31" id="Path-30" stroke="#0041FF" stroke-width="2"></path>
|
||||||
|
<polyline id="Path-38" stroke="#0041FF" stroke-width="2" transform="translate(26.000000, 25.000000) rotate(45.000000) translate(-26.000000, -25.000000) " points="23 28 23 22 29 22"></polyline>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 51.1 (57501) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Icon-Bulk-Upload</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Icon-Bulk-Upload" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<path d="M12.9981102,12.047248 L37.9981102,12.0000018 C38.5503939,11.9989581 38.9989545,12.4458264 38.9999982,12.9981102 C38.9999994,12.9987401 39,12.9993701 39,13 L39,37.9962168 C39,38.5485015 38.5522847,38.9962168 38,38.9962168 C37.9993701,38.9962168 37.9987401,38.9962162 37.9981102,38.996215 L12.9981102,38.9489688 C12.4465643,38.9479265 12,38.5005175 12,37.9489706 L12,13.0472462 C12,12.4956993 12.4465643,12.0482903 12.9981102,12.047248 Z" id="Rectangle-15" stroke="#8E8E8E" stroke-width="2" fill-rule="nonzero"></path>
|
||||||
|
<path d="M9,33.9508587 L9,11.0453581 C9,9.94226441 9.89312856,9.04744638 10.9962203,9.04536171 L33.9962203,9.00189524" id="Path" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill-rule="nonzero"></path>
|
||||||
|
<path d="M12,17.202381 L39,17.202381" id="Path-29" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
|
<path d="M31.25,31 L31.25,35" id="Path-30-Copy-2" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
|
<path d="M34.25,31 L34.25,35" id="Path-30-Copy-3" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
|
<path d="M26,22 L26,31" id="Path-30" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
|
<polyline id="Path-38" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(26.000000, 25.000000) rotate(45.000000) translate(-26.000000, -25.000000) " points="23 28 23 22 29 22"></polyline>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Icon-Crossed</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Icon-Crossed" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<path d="M9,8.35557738 L12.2221131,5.13346429 C12.4000655,4.9555119 12.6885833,4.9555119 12.8665357,5.13346429 C13.0444881,5.31141669 13.0444881,5.59993452 12.8665357,5.77788691 L9.64442262,9 L12.8665357,12.2221131 C13.0444881,12.4000655 13.0444881,12.6885833 12.8665357,12.8665357 C12.6885833,13.0444881 12.4000655,13.0444881 12.2221131,12.8665357 L9,9.64442262 L5.77788691,12.8665357 C5.59993452,13.0444881 5.31141669,13.0444881 5.13346429,12.8665357 C4.9555119,12.6885833 4.9555119,12.4000655 5.13346429,12.2221131 L8.35557738,9 L5.13346429,5.77788691 C4.9555119,5.59993452 4.9555119,5.31141669 5.13346429,5.13346429 C5.31141669,4.9555119 5.59993452,4.9555119 5.77788691,5.13346429 L9,8.35557738 Z" id="Combined-Shape" fill="#8E8E8E"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Check-Accent</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Check-Accent" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<polyline id="Path-2" stroke="#0041FF" stroke-width="3" points="2 10 6 14 15 5"></polyline>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 606 B |
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Cross-Accent</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Cross-Accent" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M4.5,13.5 L13.5,4.5" id="Path-2" stroke="#0041FF" stroke-width="3" transform="translate(9.000000, 9.000000) scale(-1, 1) translate(-9.000000, -9.000000) "></path>
|
||||||
|
<path d="M4.5,13.5 L13.5,4.5" id="Path-2" stroke="#0041FF" stroke-width="3"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 778 B |
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 50 (54983) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>tab/heading/icon/finish</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="tab/heading/icon/finish" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="Group" transform="translate(6.000000, 8.000000)" stroke="#242424" stroke-width="3">
|
||||||
|
<rect id="Rectangle-10" x="1.5" y="1.5" width="17" height="10"></rect>
|
||||||
|
</g>
|
||||||
|
<rect id="Rectangle-2" fill="#242424" x="8" y="13" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy-2" fill="#242424" x="14" y="13" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy-5" fill="#242424" x="20" y="13" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy" fill="#242424" x="11" y="10" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy-3" fill="#242424" x="17" y="10" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy" fill="#242424" x="11" y="16" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle-2-Copy-4" fill="#242424" x="17" y="16" width="3" height="3"></rect>
|
||||||
|
<rect id="Rectangle" fill="#242424" transform="translate(7.500000, 16.500000) rotate(90.000000) translate(-7.500000, -16.500000) " x="-2" y="15" width="19" height="3"></rect>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,8 @@
|
||||||
|
window.Vue = require("vue");
|
||||||
|
window.axios = require("axios");
|
||||||
|
|
||||||
|
Vue.prototype.$http = axios;
|
||||||
|
|
||||||
|
window.eventBus = new Vue();
|
||||||
|
|
||||||
|
Vue.component("demo", require("./components/demo"));
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
.bulk-upload-icon {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
display: inline-block;
|
||||||
|
background-size: cover;
|
||||||
|
background-image: url("../images/Icon-Bulk-Upload.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
.bulk-upload-icon {
|
||||||
|
background-image: url("../images/Icon-Bulk-Upload-Active.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bulk-upload-icon {
|
||||||
|
background-image: url("../images/Icon-Bulk-Upload-Active.svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
progress {
|
||||||
|
margin: 15px 0px 15px 34px;
|
||||||
|
width: 70%;
|
||||||
|
height: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-size: cover;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
&.check-accent {
|
||||||
|
background-image: url("../images/check-accent.svg");
|
||||||
|
width: 22px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-crossed {
|
||||||
|
width: 18px;
|
||||||
|
height: 15px;
|
||||||
|
background-image: url("../images/Icon-Crossed.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.cross-accent {
|
||||||
|
width: 22px;
|
||||||
|
height: 18px;
|
||||||
|
background-image: url("../images/cross-accent.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.finish-icon {
|
||||||
|
width: 22px;
|
||||||
|
height: 18px;
|
||||||
|
background-image: url("../images/finish.svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
.bulk-upload-icon {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
display: inline-block;
|
||||||
|
background-size: cover;
|
||||||
|
background-image: url("../images/Icon-Bulk-Upload.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
.bulk-upload-icon {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
display: inline-block;
|
||||||
|
background-size: cover;
|
||||||
|
background-image: url("../images/Icon-Bulk-Upload-Active.svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
progress {
|
||||||
|
margin: 15px 0px 15px 34px;
|
||||||
|
width: 70%;
|
||||||
|
height: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-size: cover;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
&.check-accent {
|
||||||
|
width: 22px;
|
||||||
|
height: 18px;
|
||||||
|
background-image: url("../images/check-accent.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-crossed {
|
||||||
|
width: 18px;
|
||||||
|
height: 15px;
|
||||||
|
background-image: url("../images/Icon-Crossed.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.cross-accent {
|
||||||
|
width: 22px;
|
||||||
|
height: 18px;
|
||||||
|
background-image: url("../images/cross-accent.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.finish-icon {
|
||||||
|
width: 22px;
|
||||||
|
height: 18px;
|
||||||
|
background-image: url("../images/finish.svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'admin' => [
|
||||||
|
'bulk-upload' => [
|
||||||
|
'index' => 'Bulkupload',
|
||||||
|
'manage-bulk-upload' => 'Manage Bulk Upload',
|
||||||
|
|
||||||
|
'data-flow-profile' => [
|
||||||
|
'index' => 'Data Flow Profile',
|
||||||
|
'add-profile' => 'Add Profile',
|
||||||
|
'grid' => 'Profile Grid',
|
||||||
|
'name' => 'Name',
|
||||||
|
|
||||||
|
'data-grid' => [
|
||||||
|
'created-at' => 'Created At'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
'run-profile' => [
|
||||||
|
'index' => 'Run Profile',
|
||||||
|
'select-file' => 'Select File',
|
||||||
|
'please-select' => 'Please Select',
|
||||||
|
'run' => 'Run',
|
||||||
|
'profile-execution' => 'Starting profile execution, please wait...',
|
||||||
|
'error-count' => 'Number of errors while product uploading',
|
||||||
|
'error-in-product' => 'Error while product uploading',
|
||||||
|
'warning' => 'Warning: Please do not close the window during importing data',
|
||||||
|
'products-uploaded' => 'Products Uploaded',
|
||||||
|
'finish' => 'Finished Profile Execution',
|
||||||
|
],
|
||||||
|
|
||||||
|
'upload-files' => [
|
||||||
|
'index' => 'Upload Files',
|
||||||
|
'download-sample' => 'Download Samples',
|
||||||
|
'download' => 'Download',
|
||||||
|
'csv-file' => 'Sample :filetype CSV File',
|
||||||
|
'xls-file' => 'Sample :filetype XLS File',
|
||||||
|
'import-products' => 'Import Products',
|
||||||
|
'is-downloadable' => 'Is downloadable have files',
|
||||||
|
'sample-links' => 'Is Links have samples',
|
||||||
|
'sample-available' => 'Is Samples available',
|
||||||
|
'upload-link-files' => 'Upload Link Files',
|
||||||
|
'upload-link-sample-files' => 'Upload Link Sample Files',
|
||||||
|
'upload-sample-files' => 'Upload Sample Files',
|
||||||
|
'file' => 'CSV/XLS/XLSX file',
|
||||||
|
'image' => 'Image Zip file',
|
||||||
|
'save' => 'Save'
|
||||||
|
],
|
||||||
|
|
||||||
|
'messages' => [
|
||||||
|
'profile-saved' => 'Profile added successfully',
|
||||||
|
'profile-deleted' => 'Profile deleted successfully',
|
||||||
|
'file-format-error' => 'Invalid File Extension',
|
||||||
|
'update-profile' => 'Profile updated successfully',
|
||||||
|
'data-profile-not-selected' => 'Data Flow Profile not selected',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'admin' => [
|
||||||
|
'system' => [
|
||||||
|
'bulkupload' => 'Bulk-Upload Product',
|
||||||
|
'settings' => 'Settings',
|
||||||
|
'general' => 'General',
|
||||||
|
'status' => 'Status',
|
||||||
|
],
|
||||||
|
|
||||||
|
'bulk-upload' => [
|
||||||
|
'index' => 'Bulkupload',
|
||||||
|
'manage-bulk-upload' => 'Manage Bulk Upload',
|
||||||
|
|
||||||
|
'data-flow-profile' => [
|
||||||
|
'index' => 'Data Flow Profile',
|
||||||
|
'add-profile' => 'Add Profile',
|
||||||
|
'grid' => 'Profile Grid',
|
||||||
|
'name' => 'Name',
|
||||||
|
'edit-profile' => 'Edit Profile',
|
||||||
|
'update-profile' => 'Update',
|
||||||
|
|
||||||
|
'data-grid' => [
|
||||||
|
'created-at' => 'Created At',
|
||||||
|
'locale_code' => 'Locale code'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
'run-profile' => [
|
||||||
|
'index' => 'Run Profile',
|
||||||
|
'select-file' => 'Select File',
|
||||||
|
'please-select' => 'Please Select',
|
||||||
|
'run' => 'Run',
|
||||||
|
'profile-execution' => 'Starting profile execution, please wait...',
|
||||||
|
'error-count' => 'Number of errors while product uploading',
|
||||||
|
'error-in-product' => 'Error while product uploading',
|
||||||
|
'warning' => 'Warning: Please do not close the window during importing data',
|
||||||
|
'products-uploaded' => 'Products Uploaded',
|
||||||
|
'finish' => 'Finished Profile Execution',
|
||||||
|
],
|
||||||
|
|
||||||
|
'upload-files' => [
|
||||||
|
'index' => 'Upload Files',
|
||||||
|
'download-sample' => 'Download Samples',
|
||||||
|
'download' => 'Download',
|
||||||
|
'csv-file' => 'Sample :filetype CSV File',
|
||||||
|
'xls-file' => 'Sample :filetype XLS File',
|
||||||
|
'import-products' => 'Import Products',
|
||||||
|
'is-downloadable' => 'Is downloadable have files',
|
||||||
|
'sample-links' => 'Is Links have samples',
|
||||||
|
'sample-available' => 'Is Samples available',
|
||||||
|
'upload-link-files' => 'Upload Link Files',
|
||||||
|
'upload-link-sample-files' => 'Upload Link Sample Files',
|
||||||
|
'upload-sample-files' => 'Upload Sample Files',
|
||||||
|
'file' => 'CSV/XLS/XLSX file',
|
||||||
|
'image' => 'Image Zip file',
|
||||||
|
'save' => 'Save'
|
||||||
|
],
|
||||||
|
|
||||||
|
'messages' => [
|
||||||
|
'profile-saved' => 'Profile added successfully',
|
||||||
|
'profile-deleted' => 'Profile deleted successfully',
|
||||||
|
'file-format-error' => 'Invalid File Extension',
|
||||||
|
'update-profile' => 'Profile updated successfully',
|
||||||
|
'data-profile-not-selected' => 'Data Flow Profile not selected',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'admin' => [
|
||||||
|
'bulk-upload' => [
|
||||||
|
'index' => 'Bulkupload',
|
||||||
|
'manage-bulk-upload' => 'Manage Bulk Upload',
|
||||||
|
|
||||||
|
'data-flow-profile' => [
|
||||||
|
'index' => 'Data Flow Profile',
|
||||||
|
'add-profile' => 'Add Profile',
|
||||||
|
'grid' => 'Profile Grid',
|
||||||
|
'name' => 'Name',
|
||||||
|
|
||||||
|
'data-grid' => [
|
||||||
|
'created-at' => 'Created At'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
'run-profile' => [
|
||||||
|
'index' => 'Run Profile',
|
||||||
|
'select-file' => 'Select File',
|
||||||
|
'please-select' => 'Please Select',
|
||||||
|
'run' => 'Run',
|
||||||
|
'profile-execution' => 'Starting profile execution, please wait...',
|
||||||
|
'error-count' => 'Number of errors while product uploading',
|
||||||
|
'error-in-product' => 'Error while product uploading',
|
||||||
|
'warning' => 'Warning: Please do not close the window during importing data',
|
||||||
|
'products-uploaded' => 'Products Uploaded',
|
||||||
|
'finish' => 'Finished Profile Execution',
|
||||||
|
],
|
||||||
|
|
||||||
|
'upload-files' => [
|
||||||
|
'index' => 'Upload Files',
|
||||||
|
'download-sample' => 'Download Samples',
|
||||||
|
'download' => 'Download',
|
||||||
|
'csv-file' => 'Sample :filetype CSV File',
|
||||||
|
'xls-file' => 'Sample :filetype XLS File',
|
||||||
|
'import-products' => 'Import Products',
|
||||||
|
'is-downloadable' => 'Is downloadable have files',
|
||||||
|
'sample-links' => 'Is Links have samples',
|
||||||
|
'sample-available' => 'Is Samples available',
|
||||||
|
'upload-link-files' => 'Upload Link Files',
|
||||||
|
'upload-link-sample-files' => 'Upload Link Sample Files',
|
||||||
|
'upload-sample-files' => 'Upload Sample Files',
|
||||||
|
'file' => 'CSV/XLS/XLSX file',
|
||||||
|
'image' => 'Image Zip file',
|
||||||
|
'save' => 'Save'
|
||||||
|
],
|
||||||
|
|
||||||
|
'messages' => [
|
||||||
|
'profile-saved' => 'Profile added successfully',
|
||||||
|
'profile-deleted' => 'Profile deleted successfully',
|
||||||
|
'file-format-error' => 'Invalid File Extension',
|
||||||
|
'update-profile' => 'Profile updated successfully',
|
||||||
|
'data-profile-not-selected' => 'Data Flow Profile not selected',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'admin' => [
|
||||||
|
'bulk-upload' => [
|
||||||
|
'index' => 'Bulkupload',
|
||||||
|
'manage-bulk-upload' => 'Manage Bulk Upload',
|
||||||
|
|
||||||
|
'data-flow-profile' => [
|
||||||
|
'index' => 'Data Flow Profile',
|
||||||
|
'add-profile' => 'Add Profile',
|
||||||
|
'grid' => 'Profile Grid',
|
||||||
|
'name' => 'Name',
|
||||||
|
|
||||||
|
'data-grid' => [
|
||||||
|
'created-at' => 'Created At'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
'run-profile' => [
|
||||||
|
'index' => 'Run Profile',
|
||||||
|
'select-file' => 'Select File',
|
||||||
|
'please-select' => 'Please Select',
|
||||||
|
'run' => 'Run',
|
||||||
|
'profile-execution' => 'Starting profile execution, please wait...',
|
||||||
|
'error-count' => 'Number of errors while product uploading',
|
||||||
|
'error-in-product' => 'Error while product uploading',
|
||||||
|
'warning' => 'Warning: Please do not close the window during importing data',
|
||||||
|
'products-uploaded' => 'Products Uploaded',
|
||||||
|
'finish' => 'Finished Profile Execution',
|
||||||
|
],
|
||||||
|
|
||||||
|
'upload-files' => [
|
||||||
|
'index' => 'Upload Files',
|
||||||
|
'download-sample' => 'Download Samples',
|
||||||
|
'download' => 'Download',
|
||||||
|
'csv-file' => 'Sample :filetype CSV File',
|
||||||
|
'xls-file' => 'Sample :filetype XLS File',
|
||||||
|
'import-products' => 'Import Products',
|
||||||
|
'is-downloadable' => 'Is downloadable have files',
|
||||||
|
'sample-links' => 'Is Links have samples',
|
||||||
|
'sample-available' => 'Is Samples available',
|
||||||
|
'upload-link-files' => 'Upload Link Files',
|
||||||
|
'upload-link-sample-files' => 'Upload Link Sample Files',
|
||||||
|
'upload-sample-files' => 'Upload Sample Files',
|
||||||
|
'file' => 'CSV/XLS/XLSX file',
|
||||||
|
'image' => 'Image Zip file',
|
||||||
|
'save' => 'Save'
|
||||||
|
],
|
||||||
|
|
||||||
|
'messages' => [
|
||||||
|
'profile-saved' => 'Profile added successfully',
|
||||||
|
'profile-deleted' => 'Profile deleted successfully',
|
||||||
|
'file-format-error' => 'Invalid File Extension',
|
||||||
|
'update-profile' => 'Profile updated successfully',
|
||||||
|
'data-profile-not-selected' => 'Data Flow Profile not selected',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'admin' => [
|
||||||
|
'bulk-upload' => [
|
||||||
|
'index' => 'Bulkupload',
|
||||||
|
'manage-bulk-upload' => 'Manage Bulk Upload',
|
||||||
|
|
||||||
|
'data-flow-profile' => [
|
||||||
|
'index' => 'Data Flow Profile',
|
||||||
|
'add-profile' => 'Add Profile',
|
||||||
|
'grid' => 'Profile Grid',
|
||||||
|
'name' => 'Name',
|
||||||
|
|
||||||
|
'data-grid' => [
|
||||||
|
'created-at' => 'Created At'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
'run-profile' => [
|
||||||
|
'index' => 'Run Profile',
|
||||||
|
'select-file' => 'Select File',
|
||||||
|
'please-select' => 'Please Select',
|
||||||
|
'run' => 'Run',
|
||||||
|
'profile-execution' => 'Starting profile execution, please wait...',
|
||||||
|
'error-count' => 'Number of errors while product uploading',
|
||||||
|
'error-in-product' => 'Error while product uploading',
|
||||||
|
'warning' => 'Warning: Please do not close the window during importing data',
|
||||||
|
'products-uploaded' => 'Products Uploaded',
|
||||||
|
'finish' => 'Finished Profile Execution',
|
||||||
|
],
|
||||||
|
|
||||||
|
'upload-files' => [
|
||||||
|
'index' => 'Upload Files',
|
||||||
|
'download-sample' => 'Download Samples',
|
||||||
|
'download' => 'Download',
|
||||||
|
'csv-file' => 'Sample :filetype CSV File',
|
||||||
|
'xls-file' => 'Sample :filetype XLS File',
|
||||||
|
'import-products' => 'Import Products',
|
||||||
|
'is-downloadable' => 'Is downloadable have files',
|
||||||
|
'sample-links' => 'Is Links have samples',
|
||||||
|
'sample-available' => 'Is Samples available',
|
||||||
|
'upload-link-files' => 'Upload Link Files',
|
||||||
|
'upload-link-sample-files' => 'Upload Link Sample Files',
|
||||||
|
'upload-sample-files' => 'Upload Sample Files',
|
||||||
|
'file' => 'CSV/XLS/XLSX file',
|
||||||
|
'image' => 'Image Zip file',
|
||||||
|
'save' => 'Save'
|
||||||
|
],
|
||||||
|
|
||||||
|
'messages' => [
|
||||||
|
'profile-saved' => 'Profile added successfully',
|
||||||
|
'profile-deleted' => 'Profile deleted successfully',
|
||||||
|
'file-format-error' => 'Invalid File Extension',
|
||||||
|
'update-profile' => 'Profile updated successfully',
|
||||||
|
'data-profile-not-selected' => 'Data Flow Profile not selected',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
@extends('admin::layouts.content')
|
||||||
|
|
||||||
|
@section('page_title')
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.bulk-upload-dataflow-profile') }}
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="account-content">
|
||||||
|
<div class="account-layout">
|
||||||
|
<!-- Import New products -->
|
||||||
|
<div class="import-new-products mt-45">
|
||||||
|
<div class="heading">
|
||||||
|
<h1>{{ __('bulkupload::app.admin.bulk-upload.data-flow-profile.edit-profile') }}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form method="POST" action="{{ route('admin.bulk-upload.dataflow.update-profile',$profiles->id) }}">
|
||||||
|
@csrf
|
||||||
|
<?php $familyId = app('request')->input('family') ?>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="profile_name" class="required">{{ __('bulkupload::app.admin.bulk-upload.data-flow-profile.name') }}</label>
|
||||||
|
<input type="text" class="control" name="name" value="{{ $profiles->name}}"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" :class="[errors.has('attribute_family_id') ? 'has-error' : '']">
|
||||||
|
<label for="attribute_family_id" class="required">{{ __('admin::app.catalog.products.familiy') }}</label>
|
||||||
|
|
||||||
|
<select class="control" value="" id="attribute_family_id" name="attribute_family_id" {{ $familyId ? 'disabled' : '' }}>
|
||||||
|
@foreach ($families as $family)
|
||||||
|
<option value="{{ $family->id }}" {{ ($familyId == $family->id || old('attribute_family_id') == $family->id) ? 'selected' : '' }}>{{ $family->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
|
||||||
|
@if ($familyId)
|
||||||
|
<input type="hidden" name="attribute_family_id" value="{{ $familyId }}"/>
|
||||||
|
@endif
|
||||||
|
<span class="control-error" v-if="errors.has('attribute_family_id')">@{{ errors.first('attribute_family_id') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-action" style="display:flex; justify-content: space-between;">
|
||||||
|
<button type="submit" class="btn btn-lg btn-primary">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.data-flow-profile.update-profile') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
{!! app('Webkul\Bulkupload\DataGrids\Admin\ProfileDataGrid')->render() !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
@extends('admin::layouts.content')
|
||||||
|
|
||||||
|
@section('page_title')
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.data-flow-profile.index') }}
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<!-- Import New products -->
|
||||||
|
<div class="import-new-products mt-45">
|
||||||
|
<div class="heading mb-25">
|
||||||
|
<h1>{{ __('bulkupload::app.admin.bulk-upload.data-flow-profile.add-profile') }}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form method="POST" action="{{ route('bulkupload.bulk-upload.dataflow.add-profile') }}">
|
||||||
|
@csrf
|
||||||
|
<?php $familyId = app('request')->input('family') ?>
|
||||||
|
|
||||||
|
<div class="control-group {{ $errors->first('name') ? 'has-error' :'' }}">
|
||||||
|
<label for="profile_name" class="required">{{ __('bulkupload::app.admin.bulk-upload.data-flow-profile.name') }}</label>
|
||||||
|
<input type="text" class="control" name="name" value=""/>
|
||||||
|
<span class="control-error">{{ $errors->first('name') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group {{ $errors->first('attribute_family') ? 'has-error' :'' }}">
|
||||||
|
<label for="attribute_family" class="required">{{ __('admin::app.catalog.products.familiy') }}</label>
|
||||||
|
|
||||||
|
<select class="control" id="attribute_family" name="attribute_family" {{ $familyId ? 'disabled' : '' }}>
|
||||||
|
<option value="">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.run-profile.please-select') }}
|
||||||
|
</option>
|
||||||
|
|
||||||
|
@foreach ($families as $family)
|
||||||
|
<option value="{{ $family->id }}" {{ ($familyId == $family->id || old('attribute_family') == $family->id) ? 'selected' : '' }}>{{ $family->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
|
||||||
|
@if ($familyId)
|
||||||
|
<input type="hidden" name="attribute_family" value="{{ $familyId }}"/>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<span class="control-error">{{ $errors->first('attribute_family') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" :class="[errors.has('locale_code') ? 'has-error' : '']">
|
||||||
|
<label for="locale_code" class="required">{{ __('admin::app.settings.channels.default-locale') }}</label>
|
||||||
|
|
||||||
|
<select v-validate="'required'" class="control" id="locale_code" name="locale_code" data-vv-as=""{{ __('admin::app.settings.channels.default-locale') }}"">
|
||||||
|
@foreach (core()->getAllLocales() as $localeModel)
|
||||||
|
<option value="{{ $localeModel->code }}">
|
||||||
|
{{ $localeModel->name }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
<span class="control-error" v-if="errors.has('locale_code')">@{{ errors.first('locale_code') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-action" style="display:flex; justify-content: space-between;">
|
||||||
|
<button type="submit" class="btn btn-lg btn-primary">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.upload-files.save') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<accordian :title="'{{ __('bulkupload::app.admin.bulk-upload.data-flow-profile.grid') }}'" :active="true" class="mt-45">
|
||||||
|
<div slot="body">
|
||||||
|
<div class="page-content">
|
||||||
|
{!! app('Webkul\Bulkupload\DataGrids\Admin\ProfileDataGrid')->render() !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
@stop
|
||||||
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
<div class="aside-nav">
|
||||||
|
|
||||||
|
{{-- button for collapsing aside nav --}}
|
||||||
|
<nav-slide-button icon-class="accordian-left-icon"></nav-slide-button>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
@if (request()->route()->getName() != 'admin.configuration.index')
|
||||||
|
<?php $keys = explode('.', $menu->currentKey); ?>
|
||||||
|
@if(isset($keys) && strlen($keys[0]))
|
||||||
|
@foreach (\Illuminate\Support\Arr::get($menu->items, current($keys) . '.children') as $item)
|
||||||
|
|
||||||
|
@if (!core()->getConfigData('bulkupload.settings.general.status') && $item['key'] == 'catalog.bulkupload')
|
||||||
|
<?php continue; ?>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<li class="{{ $menu->getActive($item) }}">
|
||||||
|
<a href="{{ $item['url'] }}">
|
||||||
|
{{ trans($item['name']) }}
|
||||||
|
|
||||||
|
@if ($menu->getActive($item))
|
||||||
|
<i class="angle-right-icon"></i>
|
||||||
|
@endif
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
@else
|
||||||
|
@foreach ($config->items as $key => $item)
|
||||||
|
<li class="{{ $item['key'] == request()->route('slug') ? 'active' : '' }}">
|
||||||
|
<a href="{{ route('admin.configuration.index', $item['key']) }}">
|
||||||
|
{{ isset($item['name']) ? trans($item['name']) : '' }}
|
||||||
|
|
||||||
|
@if ($item['key'] == request()->route('slug'))
|
||||||
|
<i class="angle-right-icon"></i>
|
||||||
|
@endif
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,244 @@
|
||||||
|
@extends('admin::layouts.content')
|
||||||
|
|
||||||
|
@section('page_title')
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.run-profile.index') }}
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<!-- Run Profile -->
|
||||||
|
<accordian :title="'{{ __('bulkupload::app.admin.bulk-upload.run-profile.index') }}'" :active="true">
|
||||||
|
<div slot="body">
|
||||||
|
<div class="app-profiler">
|
||||||
|
<profiler></profiler>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/x-template" id="profiler-template">
|
||||||
|
<div class="run-profile">
|
||||||
|
<form action="{{ route('bulk-upload-admin.run-profile') }}" method="post">
|
||||||
|
@csrf
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="export-product-type">{{ __('bulkupload::app.admin.bulk-upload.run-profile.select-file') }}</label>
|
||||||
|
|
||||||
|
<select class="control" id="data-flow-profile" v-model="data_flow_profile" name="data_flow_profile">
|
||||||
|
<option>{{ __('bulkupload::app.admin.bulk-upload.run-profile.please-select') }}</option>
|
||||||
|
|
||||||
|
@if (isset($profiles))
|
||||||
|
@foreach ($profiles as $profile)
|
||||||
|
@foreach ($profile as $getProfileToExecute)
|
||||||
|
<option value="{{ $getProfileToExecute->id }}">
|
||||||
|
{{ $getProfileToExecute->name }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<div class="page-action">
|
||||||
|
<button type="submit" :class="{ disabled: isDisabled }" :disabled="isDisabled" @click.prevent="runProfiler" class="btn btn-lg btn-primary mt-10">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.run-profile.run') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="uploading-records" v-if="this.product.totalCSVRecords">
|
||||||
|
<uploadingrecords :percentCount="percent" :uploadedProducts="product.countOfImportedProduct" :errorProduct="product.error" :totalRecords="product.totalCSVRecords" :countOfError="product.countOfError" :remainData="product.remainDataInCSV" ></uploadingrecords>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/x-template" id="uploadingRecords-template">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<i class="icon check-accent"></i>
|
||||||
|
<span>{{ __('bulkupload::app.admin.bulk-upload.run-profile.profile-execution') }}</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li v-if="this.countOfError > '0'">
|
||||||
|
<i class="icon cross-accent"></i>
|
||||||
|
<span>{{ __('bulkupload::app.admin.bulk-upload.run-profile.error-count') }}: @{{this.countOfError}}</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li v-if="this.countOfError > '0'">
|
||||||
|
<i class="icon cross-accent"></i>
|
||||||
|
<span >
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.run-profile.error-in-product') }} :
|
||||||
|
<label v-for= "error in this.errorProduct" style="display: inline-block; width: 100%; margin-left: 50px;">
|
||||||
|
<i class="icon icon-crossed"></i>
|
||||||
|
@{{ error }}
|
||||||
|
</label>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<i class="icon check-accent"></i>
|
||||||
|
<span>{{ __('bulkupload::app.admin.bulk-upload.run-profile.warning') }}</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<progress class="progression" v-if="this.remainData > '0'" :value="percentCount" max="100">
|
||||||
|
</progress>
|
||||||
|
<progress class="progression" v-else :value="100" max="100"></progress>
|
||||||
|
|
||||||
|
<span style="vertical-align: 75%;" v-if="this.remainData > '0'"> @{{ this.percentCount}}%</span>
|
||||||
|
<span style="vertical-align: 75%;" v-else> 100% </span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<i class="icon check-accent"></i>
|
||||||
|
<span> @{{this.uploadedProducts}}/@{{this.totalRecords}} {{ __('bulkupload::app.admin.bulk-upload.run-profile.products-uploaded') }}</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li v-if="this.remainData == '0'">
|
||||||
|
<i class="icon finish-icon"></i>
|
||||||
|
<span>{{ __('bulkupload::app.admin.bulk-upload.run-profile.finish') }} </span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Vue.component('profiler', {
|
||||||
|
template:'#profiler-template',
|
||||||
|
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
data_flow_profile: '',
|
||||||
|
percent: 0,
|
||||||
|
product: {
|
||||||
|
countOfImportedProduct : 0,
|
||||||
|
countOfStartedProfiles : 0,
|
||||||
|
fetchedRecords : 10,
|
||||||
|
numberOfTimeInitiateProfilerCalled: 0,
|
||||||
|
totalCSVRecords:'',
|
||||||
|
dataArray:[],
|
||||||
|
error: [],
|
||||||
|
countOfError: 0,
|
||||||
|
remainDataInCSV: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
isDisabled () {
|
||||||
|
if (this.data_flow_profile == '' || this.data_flow_profile == 'Please Select') {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods:{
|
||||||
|
detectProfile: function() {
|
||||||
|
event.target.disabled = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
runProfiler: function(e) {
|
||||||
|
event.target.disabled = true;
|
||||||
|
|
||||||
|
this.detectProfile();
|
||||||
|
|
||||||
|
const uri = "{{ route('bulk-upload-admin.read-csv') }}"
|
||||||
|
this.$http.post(uri, {
|
||||||
|
data_flow_profile_id: this.data_flow_profile
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
totalRecords = result.data;
|
||||||
|
|
||||||
|
if (typeof(totalRecords) == 'number') {
|
||||||
|
this.product.totalCSVRecords = this.product.remainDataInCSV = totalRecords;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(totalRecords > this.product.countOfStartedProfiles) {
|
||||||
|
this.initiateProfiler(totalRecords);
|
||||||
|
} else {
|
||||||
|
window.flashMessages = [{
|
||||||
|
'type': 'alert-error',
|
||||||
|
'message': result.data.message
|
||||||
|
}];
|
||||||
|
|
||||||
|
this.$root.addFlashMessages()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
initiateProfiler: function(totalRecords) {
|
||||||
|
|
||||||
|
const url = "{{ route('bulk-upload-admin.run-profile') }}"
|
||||||
|
|
||||||
|
this.$http.post(url, {
|
||||||
|
data_flow_profile_id: this.data_flow_profile,
|
||||||
|
numberOfCSVRecord: totalRecords,
|
||||||
|
countOfStartedProfiles: this.product.countOfStartedProfiles,
|
||||||
|
totalNumberOfCSVRecord: this.product.totalCSVRecords,
|
||||||
|
productUploaded: this.product.countOfImportedProduct,
|
||||||
|
errorCount: this.product.countOfError
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
this.data = result.data;
|
||||||
|
|
||||||
|
if (this.data.error) {
|
||||||
|
if (typeof(this.data.error) == "object") {
|
||||||
|
for (const [key, value] of Object.entries(this.data.error)) {
|
||||||
|
this.product.error.push(value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.product.error.push(this.data.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.product.countOfError++;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.product.countOfImportedProduct = this.data.productsUploaded;
|
||||||
|
this.product.remainDataInCSV = this.data.remainDataInCSV;
|
||||||
|
this.product.countOfStartedProfiles = this.data.countOfStartedProfiles;
|
||||||
|
|
||||||
|
this.calculateProgress(result.data);
|
||||||
|
})
|
||||||
|
.catch(function(error) {
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
calculateProgress(result) {
|
||||||
|
finish = this.product.countOfImportedProduct;
|
||||||
|
progressPercent = parseInt((this.product.countOfImportedProduct/
|
||||||
|
this.product.totalCSVRecords)*100);
|
||||||
|
|
||||||
|
this.percent = progressPercent;
|
||||||
|
|
||||||
|
if (result.remainDataInCSV > 0) {
|
||||||
|
this.initiateProfiler(result.remainDataInCSV);
|
||||||
|
} else {
|
||||||
|
this.finishProfiler(this.percent);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
errorCount: function(count) {
|
||||||
|
return console.count(this.product.error);
|
||||||
|
},
|
||||||
|
|
||||||
|
finishProfiler(percent) {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
Vue.component('uploadingrecords', {
|
||||||
|
template:'#uploadingRecords-template',
|
||||||
|
props: ['percentCount', 'uploadedProducts','errorProduct','totalRecords', 'countOfError', 'remainData'],
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
percentage: this.percentCount,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@endpush
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<link rel="stylesheet" href="{{ asset('themes/default/assets/css/bulk-admin.css') }}">
|
||||||
|
|
@ -0,0 +1,250 @@
|
||||||
|
@extends('admin::layouts.content')
|
||||||
|
|
||||||
|
@section('page_title')
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.upload-files.index') }}
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="account-layout">
|
||||||
|
|
||||||
|
<!-- download samples -->
|
||||||
|
<accordian :title="'{{ __('bulkupload::app.admin.bulk-upload.upload-files.download-sample') }}'" :active="true">
|
||||||
|
<div slot="body">
|
||||||
|
<div class="import-product">
|
||||||
|
<form action="{{ route('download-sample-files') }}" method="post">
|
||||||
|
<div class="account-table-content">
|
||||||
|
@csrf
|
||||||
|
<div class="control-group">
|
||||||
|
<select class="control" id="download-sample" name="download_sample">
|
||||||
|
<option value="">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.run-profile.please-select') }}
|
||||||
|
</option>
|
||||||
|
|
||||||
|
@foreach($productTypes as $key => $productType)
|
||||||
|
<option value="{{ $key }}-csv">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.upload-files.csv-file', ['filetype' => ucwords($key) ]) }}
|
||||||
|
</option>
|
||||||
|
|
||||||
|
<option value="{{ $key }}-xls">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.upload-files.xls-file', ['filetype' => ucwords($key) ]) }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<div class="mt-10">
|
||||||
|
<button type="submit" class="btn btn-lg btn-primary">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.upload-files.download') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
|
||||||
|
<!-- Import New products -->
|
||||||
|
<accordian :title="'{{ __('bulkupload::app.admin.bulk-upload.upload-files.import-products') }}'" :active="true">
|
||||||
|
<div slot="body">
|
||||||
|
<div class="import-new-products">
|
||||||
|
<form method="POST" action="{{ route('import-new-products-form-submit') }}" enctype="multipart/form-data">
|
||||||
|
@csrf
|
||||||
|
<?php $familyId = app('request')->input('family') ?>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="is_downloadable">
|
||||||
|
<downloadable-input>
|
||||||
|
</downloadable-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="attribute-family">
|
||||||
|
<attributefamily></attributefamily>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group {{ $errors->first('file_path') ? 'has-error' :'' }}">
|
||||||
|
<label class="required">{{ __('bulkupload::app.admin.bulk-upload.upload-files.file') }} </label>
|
||||||
|
|
||||||
|
<input type="file" class="control" name="file_path" id="file">
|
||||||
|
|
||||||
|
<span class="control-error">{{ $errors->first('file_path') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group {{ $errors->first('image_path') ? 'has-error' :'' }}">
|
||||||
|
<label>{{ __('bulkupload::app.admin.bulk-upload.upload-files.image') }} </label>
|
||||||
|
|
||||||
|
<input type="file" class="control" name="image_path" id="image">
|
||||||
|
|
||||||
|
<span class="control-error">{{ $errors->first('image_path') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-action">
|
||||||
|
<button type="submit" class="btn btn-lg btn-primary">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.upload-files.save') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
</div>
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/x-template" id="downloadable-input-template">
|
||||||
|
<div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="is_downloadable">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.upload-files.is-downloadable') }}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input type="checkbox" @click="showOptions()" id="is_downloadable" name="is_downloadable">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" v-if="isLinkSample">
|
||||||
|
<label for="is_link_sample">{{ __('bulkupload::app.admin.bulk-upload.upload-files.sample-links') }}</label>
|
||||||
|
|
||||||
|
<input type="checkbox" id="is_link_have_sample" @click="showlinkSamples()" name="is_link_have_sample" value="is_link_have_sample" >
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" v-if="isSample">
|
||||||
|
<label for="is_sample">{{ __('bulkupload::app.admin.bulk-upload.upload-files.sample-available') }}</label>
|
||||||
|
|
||||||
|
<input type="checkbox" id="is_sample" @click="showSamples()" name="is_sample">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" v-if="linkFiles">
|
||||||
|
<label class="required">{{ __('bulkupload::app.admin.bulk-upload.upload-files.upload-link-files') }}</label>
|
||||||
|
|
||||||
|
<input type="file" class="control required" name="link_files" id="file">
|
||||||
|
|
||||||
|
<span class="control-error">{{ $errors->first('file_path') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" v-if="linkSampleFiles">
|
||||||
|
<label class="required">{{ __('bulkupload::app.admin.bulk-upload.upload-files.upload-link-sample-files') }}</label>
|
||||||
|
|
||||||
|
<input type="file" class="control required" name="link_sample_files" id="file">
|
||||||
|
|
||||||
|
<span class="control-error">{{ $errors->first('file_path') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" v-if="sampleFile">
|
||||||
|
<label class="required">{{ __('bulkupload::app.admin.bulk-upload.upload-files.upload-sample-files') }}</label>
|
||||||
|
|
||||||
|
<input type="file" class="control required" name="sample_file" id="file">
|
||||||
|
|
||||||
|
<span class="control-error">{{ $errors->first('file_path') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/x-template" id="attribute-family-template">
|
||||||
|
<div>
|
||||||
|
<div class="control-group {{ $errors->first('attribute_family') ? 'has-error' :'' }}">
|
||||||
|
<label for="attribute_family" class="required">{{ __('admin::app.catalog.products.familiy') }}</label>
|
||||||
|
|
||||||
|
<select @change="onChange()" v-model="key" class="control" id="attribute_family" name="attribute_family" {{ $familyId ? 'disabled' : '' }}>
|
||||||
|
<option value="">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.run-profile.please-select') }}
|
||||||
|
</option>
|
||||||
|
|
||||||
|
@foreach ($families as $family)
|
||||||
|
<option value="{{ $family->id }}" {{ ($familyId == $family->id || old('attribute_family') == $family->id) ? 'selected' : '' }}>{{ $family->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
|
||||||
|
@if ($familyId)
|
||||||
|
<input type="hidden" name="attribute_family" value="{{ $familyId }}"/>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<span class="control-error">{{ $errors->first('attribute_family') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group {{ $errors->first('data_flow_profile') ? 'has-error' :'' }}">
|
||||||
|
<label for="data-flow-profile" class="required">{{ __('bulkupload::app.admin.bulk-upload.data-flow-profile.index') }}</label>
|
||||||
|
|
||||||
|
<select class="control" id="data-flow-profile" name="data_flow_profile">
|
||||||
|
<option value="">
|
||||||
|
{{ __('bulkupload::app.admin.bulk-upload.run-profile.please-select') }}
|
||||||
|
</option>
|
||||||
|
<option v-for="dataflowprofile,index in dataFlowProfiles" :value="dataflowprofile.id">@{{ dataflowprofile.name }}</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<span class="control-error">{{ $errors->first('data_flow_profile') }}</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Vue.component('attributefamily', {
|
||||||
|
template: '#attribute-family-template',
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
key: "",
|
||||||
|
// seller: "",
|
||||||
|
dataFlowProfiles: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted: function() {
|
||||||
|
},
|
||||||
|
|
||||||
|
methods:{
|
||||||
|
onChange: function() {
|
||||||
|
this_this = this;
|
||||||
|
|
||||||
|
var uri = "{{ route('bulk-upload-admin.get-all-profile') }}"
|
||||||
|
|
||||||
|
this_this.$http.post(uri, {
|
||||||
|
attribute_family_id: this_this.key,
|
||||||
|
// seller_id: this_this.seller,
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
this_this.dataFlowProfiles = response.data.dataFlowProfiles;
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function(error) {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Vue.component('downloadable-input', {
|
||||||
|
template: '#downloadable-input-template',
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
key: "",
|
||||||
|
// seller: "",
|
||||||
|
dataFlowProfiles: [],
|
||||||
|
isLinkSample: false,
|
||||||
|
isSample: false,
|
||||||
|
linkFiles: false,
|
||||||
|
linkSampleFiles: false,
|
||||||
|
sampleFile: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods:{
|
||||||
|
showOptions: function() {
|
||||||
|
this.isLinkSample = !this.isLinkSample;
|
||||||
|
this.isSample = !this.isSample;
|
||||||
|
this.linkFiles = !this.linkFiles;
|
||||||
|
|
||||||
|
this.linkSampleFiles = false;
|
||||||
|
this.sampleFile = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
showlinkSamples: function() {
|
||||||
|
this.linkSampleFiles = !this.linkSampleFiles;
|
||||||
|
},
|
||||||
|
|
||||||
|
showSamples: function() {
|
||||||
|
this.sampleFile = !this.sampleFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
const { mix } = require("laravel-mix");
|
||||||
|
require("laravel-mix-merge-manifest");
|
||||||
|
|
||||||
|
if (mix.inProduction()) {
|
||||||
|
var publicPath = "publishable/assets";
|
||||||
|
} else {
|
||||||
|
var publicPath = "../../../public/vendor/webkul/admin/assets";
|
||||||
|
}
|
||||||
|
|
||||||
|
mix.setPublicPath(publicPath).mergeManifest();
|
||||||
|
mix.disableNotifications();
|
||||||
|
|
||||||
|
mix
|
||||||
|
.copyDirectory(
|
||||||
|
__dirname + "/src/Resources/assets/images",
|
||||||
|
publicPath + "/images"
|
||||||
|
)
|
||||||
|
.sass(
|
||||||
|
__dirname + "/src/Resources/assets/sass/admin.scss",
|
||||||
|
"css/bulk-admin.css"
|
||||||
|
)
|
||||||
|
.options({
|
||||||
|
processCssUrls: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (mix.inProduction()) {
|
||||||
|
mix.version();
|
||||||
|
}
|
||||||