bulkupload
|
|
@ -108,6 +108,7 @@
|
|||
"Webkul\\Notification\\": "packages/Webkul/Notification/src",
|
||||
"Webkul\\Sitemap\\": "packages/Webkul/Sitemap/src",
|
||||
"Webkul\\Marketplace\\": "packages/Webkul/Marketplace/src",
|
||||
"Webkul\\Bulkupload\\": "packages/Webkul/Bulkupload/src",
|
||||
"Sarga\\Shop\\": "packages/Sarga/Shop/src",
|
||||
"Sarga\\API\\": "packages/Sarga/API",
|
||||
"Sarga\\Admin\\": "packages/Sarga/Admin/src",
|
||||
|
|
|
|||
|
|
@ -39,6 +39,6 @@ return [
|
|||
\Webkul\User\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Velocity\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();
|
||||
}
|
||||