Help for integrating the Laravel package
Forum rules: Always add your Laravel, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
#3515 by alfredlaggner
12 Oct 2016, 03:36
I am working for the first time on a setup for importing product records with CVS. When I run
Code: Select all php artisan aimeos:jobs product/import/csv

I get an error message: [Aimeos\Controller\Jobs\Exception]
Number of apostrophes don't match

I suspect the message is misleading and I am just not reading the the right file.

My store array has this for location:
Code: Select all'controller' => array(
        'jobs' => array(
            'product' => array(
                'import' => array(
                    'csv' => array(
                        'location ' => 'C:\Users\alfre\OneDrive\Websites\digital_ocean_procects\ga_delivery\storage\public\uploads\products.csv',
                        'skip-lines' => 1,
                    ),
                ),
            ),
        ),
    ),

I know the CSV file is at this location. I export it with phpexcel for laravel.

One record looks like this:
Code: Select all"859162005091","","2","","long","Auntie Delores-Chili Lime Peanuts 50mg","strain","","","","","","","","","","","",""


I am using the default mapping. (I will fine tune it after I know I can import.

I looked at the log but I cannot make sense out of it. If you want I can send it to you.

Seperate question: where can I find the commands for the cron jobs. I found this one on this forum.

Any help is welcome!

Alfred
Last edited by alfredlaggner on 12 Oct 2016, 14:20, edited 1 time in total.
#3517 by aimeos
12 Oct 2016, 19:20
Your problem is that you configured the CSV file but it needs to be a
- directory or
- zip or
- Excel file
depending on the configured type (https://aimeos.org/docs/Developers/Controller/Import_products_from_CSV#Data_location_and_format)

Here are the available jobs:
https://aimeos.org/docs/Laravel/Configure_cronjobs#Setup
#3519 by alfredlaggner
13 Oct 2016, 04:57
Thank you for your help. But I am still stuck with setting up the location to read the import file. Can you give me an example? My file location is 'storage/public/uploads'. My import file is 'products.csv'. The file content is csv format.
How do I define this in the shop controller array?
When I ran the php artisan command I get output in my database. But the output is from reading the laravel .env file! Please help me out with a sample. I very much appreciate your help. I have already spent many hours trying to figure out this puzzle.
#3520 by aimeos
13 Oct 2016, 11:47
Either create a directory which contains only the CSV file and use this configuration:
Code: Select all'controller' => array(
        'jobs' => array(
            'product' => array(
                'import' => array(
                    'csv' => array(
                        'location ' => storage_path( 'secure' ) . '\public\uploads',
                        'container' => array(
                            'type' => 'Directory',
                            'content' => 'CSV',
                        ),
                        'skip-lines' => 1,
                    ),
                ),
            ),
        ),
    ),


As alternative, you can upload a zipped CSV file and use this config:
Code: Select all'controller' => array(
        'jobs' => array(
            'product' => array(
                'import' => array(
                    'csv' => array(
                        'location ' => storage_path( 'secure' ) . '\public\uploads\products.zip',
                        'container' => array(
                            'type' => 'Zip',
                            'content' => 'CSV',
                        ),
                        'skip-lines' => 1,
                    ),
                ),
            ),
        ),
    ),
#3523 by alfredlaggner
14 Oct 2016, 00:05
Now I modified my shop controller like this:

Code: Select all      'controller' => [
        'jobs' => [
            'product' => [
                'import' => [
                    'csv' => [
                        'location' => storage_path('secure') . '/public/uploads',
                        'container' => [
                            'type' => 'Directory',
                            'content' => 'CSV',
                        ],
                        'skip-lines' => 1,
                        'mapping' => [
                            'item' => [
                                0 => 'product.code', // e.g. unique EAN code
//                                1 => 'product.label', // UTF-8 encoded text, also used as product name
                                1 => 'product.type', // type of the product, e.g. "default" or "selection"
                                2 => 'product.status', // enabled (1) or disabled (0)
                            ],
                            'text' => [
                                3 => 'text.type', // e.g. "short" for short description
                                4 => 'text.content', // UTF-8 encoded text
//                                6 => 'text.type', // e.g. "long" for long description
//                                7 => 'text.content', // UTF-8 encoded text
                            ],
                            'media' => [
                                5 => 'media.url', // relative URL of the product image on the server
                            ],
                            'price' => [
//                                9 => 'price.quantity', // the quantity the price is valid from (for block pricing)
                                6 => 'price.value', // price with decimals separated by a dot, no thousand separator
//                                11 => 'price.taxrate', // tax rate with decimals separated by a dot
                            ],
                            'attribute' => [
                                7 => 'attribute.type', // e.g. "size", "length", "width", "color", etc.
//                                13 => 'attribute.code', // code of an existing attribute, new ones will be created automatically
                            ],
                            'product' => [
                                8 => 'product.code', // e.g. EAN code of another product
//                                15 => 'product.list.type', // e.g. "suggestion" for suggested product
//                            ],
//                            'property' => [
//                                16 => 'product.property.value', // arbitrary value for the corresponding type
//                                17 => 'product.property.type', // e.g. "package-weight"
//                            ],
//                            'catalog' => [
//                                18 => 'catalog.code', // e.g. Unique category code
//                                19 => 'catalog.list.type', // e.g. "promotion" for top seller products
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],



My import csv looks like this:
Code: Select all"product.code","product.status","text1.type","text1.content","media.url","price.value","attribute.type","product.barcode"
"82","1","long","Auntie Delores-Chili Lime Peanuts 50mg","","10.00","weight","859162005091"
"110","1","long","Badfish-Afgoo Cheese","","10.00","weight",""
"9","1","long","Mixed","","10.00","weight",""
"90","1","long","Mixed","","10.00","weight",""
"112","1","long","Badfish-Apple Jack","","10.00","weight",""
"877","1","long","Super Jack-Preroll (King)","","10.00","weight",""
"4","1","long","250 mg Sweet and Sours","","10.00","weight",""
"265","1","long","Tiva Energy-Tangerine 120mg","","10.00","weight",""
"109","1","long","Badfish-Gorilla Glue #4","","10.00","weight",""
"107","1","long","Badfish-Mango","","10.00","weight",""



When I attempt to import I get this log entry for every record:
Unable to import product with code "82": No type item for "product/long" in "product/type" found



Can you please take a look and let me know what I do wrong?

Also how canI create a clean database after testing?

Thank you again for your help.
#3524 by aimeos
15 Oct 2016, 12:17
You should first make sure that the correct file is used. For this, you should add some debug statements to the Aimeos code, e.g. at https://github.com/aimeos/ai-controller-jobs/blob/master/controller/jobs/src/Controller/Jobs/Product/Import/Csv/Standard.php#L430 and https://github.com/aimeos/ai-controller-jobs/blob/master/controller/jobs/src/Controller/Jobs/Product/Import/Csv/Standard.php#L339. You can find the files in the "./ext/ai-controller-jobs/" directory.
#3528 by alfredlaggner
17 Oct 2016, 03:40
Thank you again for your support. with your help I figured out the previous problem.
Now there is a new obstacle:

After many cycles of uploads anf tryouts I suddenly got this error that I don't understand:

[Symfony\Component\Debug\Exception\FatalThrowableError]
Call to a member function fromArray() on null

It happened after I put price.currencyid to every price. When I reversed the change the error message remained.

Code: Select all"654","default","1","NY Sour Diesel-Preroll (King)","short","NY Sour Diesel-Preroll (King)","long","NY Sour Diesel-Preroll (King)","xxx","weight","default","USD","1","14","0.00","","","","","","","","",""


Here is my shop mapping:
Code: Select all                        'mapping' => [
                            'item' => [
                                0 => 'product.code', // e.g. unique EAN code
                                1 => 'product.type', // type of the product, e.g. "default" or "selection"
                                2 => 'product.status', // enabled (1) or disabled (0)
                                3 => 'product.label', // UTF-8 encoded text, also used as product name
                            ],
                            'text' => [
                                4 => 'text.type', // e.g. "short" for short description
                                5 => 'text.content', // UTF-8 encoded text
                                6 => 'text.type', // e.g. "long" for long description
                                7 => 'text.content', // UTF-8 encoded text
                            ],
                            'media' => [
                                8 => 'media.url', // relative URL of the product image on the server
                            ],
                            'attribute' => [
                                9 => 'attribute.type', // e.g. "size", "length", "width", "color", etc.
//                                13 => 'attribute.code', // code of an existing attribute, new ones will be created automatically
                            ],
                            'price' => [
                                10 => 'price.type',
                                11 => 'price.currencyid',
                                12 => 'price.quantity', // the quantity the price is valid from (for block pricing)
                                13 => 'price.value', // price with decimals separated by a dot, no thousand separator
                                14  => 'price.taxrate', // tax rate with decimals separated by a dot

                                15 => 'price.quantity', // the quantity the price is valid from (for block pricing)
                                16 => 'price.value', // price with decimals separated by a dot, no thousand separator
                                17 => 'price.taxrate', // tax rate with decimals separated by a dot

                                18 => 'price.quantity', // the quantity the price is valid from (for block pricing)
                                19 => 'price.value', // price with decimals separated by a dot, no thousand separator
                                20 => 'price.taxrate', // tax rate with decimals separated by a dot

                                21 => 'price.quantity', // the quantity the price is valid from (for block pricing)
                                22 => 'price.value', // price with decimals separated by a dot, no thousand separator
                                23 => 'price.taxrate', // tax rate with decimals separated by a dot
                            ],
 //                           'product' => [
//                                8 => 'product.code', // e.g. EAN code of another product
//                                15 => 'product.list.type', // e.g. "suggestion" for suggested product
//                            ],
//                            'property' => [
//                                16 => 'product.property.value', // arbitrary value for the corresponding type
//                                17 => 'product.property.type', // e.g. "package-weight"
//                            ],
//                            'catalog' => [
//                                18 => 'catalog.code', // e.g. Unique category code
//                                19 => 'catalog.list.type', // e.g. "promotion" for top seller products
                           
                        ],


Thank you again for your help.

Alfred
#3529 by aimeos
17 Oct 2016, 10:12
Your price mapping only contains the currencyid once but your mapping contains several prices. You need it for every price value you want to import.
#3535 by alfredlaggner
18 Oct 2016, 17:08
I went back to the manual and created a price mapping accordingly but I seem unable to get it to work.

Here is the manual excerpt:

The value, currencyid and type (or typeid) are required as the minimum amount of data.


I know it is the prices because import runs without them.
I have up to four prices per product. If there are fewer than four prices I create prices with price 0.00.I have a type and a currency with every price.

What am I missing? :? :?:

Thank you again for your support.

This is the error:

Code: Select all [Symfony\Component\Debug\Exception\FatalThrowableError]
  Call to a member function fromArray() on null



This is the import file:

Code: Select all"product.code","product.type","product.status","product.label","text1.type","text1.content","text2.type","text2.content","media.url","price.type0","price.currencyid0","price.quantity0","price.value0","price.type1","price.currencyid1","price.quantity1","price.value1","price.type2","price.currencyid2","price.quantity2","price.value2","price.type3","price.currencyid3","price.quantity3","price.value3"
"82","default","1","Auntie Delores-Chili Lime Peanuts 50mg","short","Auntie Delores-Chili Lime Peanuts 50mg","long","Auntie Delores-Chili Lime Peanuts 50mg","nothing","default","USD","1","9.22","default","USD","1","0.00","default","USD","1","0.00","default","USD","1","0.00"


This is the shop controller mapping:
'controller' => [
'jobs' => [
'product' => [
'import' => [
'csv' => [
'location' => storage_path('secure') . '/public/uploads',
'container' => [
'type' => 'Directory',
'content' => 'CSV',
],
'skip-lines' => 1,
'mapping' => [
'item' => [
0 => 'product.code', // e.g. unique EAN code
1 => 'product.type', // type of the product, e.g. "default" or "selection"
2 => 'product.status', // enabled (1) or disabled (0)
3 => 'product.label', // UTF-8 encoded text, also used as product name
],
'text' => [
4 => 'text.type', // e.g. "short" for short description
5 => 'text.content', // UTF-8 encoded text
6 => 'text.type', // e.g. "long" for long description
7 => 'text.content', // UTF-8 encoded text
],
'media' => [
8 => 'media.url', // relative URL of the product image on the server
],
'price' => [
9 => 'price.type',
10 => 'price.currencyid',
11 => 'price.quantity', // the quantity the price is valid from (for block pricing)
12 => 'price.value', // price with decimals separated by a dot, no thousand separator

13 => 'price.type',
14 => 'price.currencyid',
15 => 'price.quantity', // the quantity the price is valid from (for block pricing)
16 => 'price.value', // price with decimals separated by a dot, no thousand separator

17 => 'price.type',
18 => 'price.currencyid',
19 => 'price.quantity', // the quantity the price is valid from (for block pricing)
20 => 'price.value', // price with decimals separated by a dot, no thousand separator

21 => 'price.type',
22 => 'price.currencyid',
23 => 'price.quantity', // the quantity the price is valid from (for block pricing)Call to a me
24 => 'price.value', // price with decimals separated by a dot, no thousand separator
],
],
],
],
],
],
],