jmueller17 / Aixada

Aixada helps self-managed consumption cooperatives to organize their flow of products, money, and information.
Other
33 stars 37 forks source link

Importar productes d'un proveïdor en format excel #280

Open Monicafgz opened 3 years ago

Monicafgz commented 3 years ago

Bones, A la nostra cooperativa tenim proveïdors als que hem d'actualitzar pràcticament tots els productes per cada comanda ja que per exemple van canviant segons la temporada de collita. Hem vist que l'Aixada dóna l'opció d'importar els productes d'un proveïdor a partir d'un fitxer que podria ser un full de càlcul i aquesta opció ens aniria molt bé ja que els propis proveïdors ho podría fer i només hauriem d'importar-lo. El dubte es com ha de ser la plantilla d'aquest fitxer per tal que es pugui importar sense problemes, hem fet alguns intents però no ens acaba de funcionar....

image

Gràcies! Mònica

jorix commented 3 years ago

...hem d'actualitzar pràcticament tots els productes...

Això es el que a "La Cistella" i "Travalera" es fa cada setmana amb el pagès.

Aixada va incorporar les plantilles d'importació de productes a proposta nostra. Aquí les dues que s'usen: 'begues4' i 'valls3' (de config.php), a continuació les comento...

/**
 *  Set templates correspondences to directly import by establishing
 *  correspondences from columns with database fields.
 */
public $import_templates = array(
    // Table any db_field_name must be allowed by $allow_import_for.
    'aixada_product' => array(
        // Template name
        'begues4' => array(
            'options' => array( //optional
                'import_mode' => '2', // '0' update only (default mode)
                                      // '1' insert all
                                      // '2' insert new and update existing
                'deactivate_products' => true // option only for products
            ),
            'required_fields' => array( //optional
                // Rows without a required fields are ignored.
                'custom_product_ref', 'name', 'unit_price'
            ),                    
            'match_columns' => array( //Required
            // db_field_name => col_name or regex to match col_name.
                'custom_product_ref' => 'nom',
                'name' => 'nom',
                'unit_price' => 'preu',
                'unit_measure_order_id' => 'id_unitat',
                'unit_measure_shop_id' => 'id_unitat'
            ),
            'forced_values' => array( //optional
                'active' => '1',
                'category_id' => '1000',
                'rev_tax_type_id' => 1
            ),
            'updatable_columns' => array( //optional: default is all columns
                'name', 'unit_price', 
                // updateable columns of forced_values should be included.
                'active', 'rev_tax_type_id'
            )
        ),
        'valls3' => array(
            'options' => array( //optional
                'import_mode' => '2', // '0' update only (default mode)
                                      // '1' insert all
                                      // '2' insert new and update existing
                'deactivate_products' => true // option only for products
            ),
            'required_fields' => array( //optional
                // Rows without a required fields are ignored.
                'custom_product_ref', 'name', 'unit_price'
            ),                    
            'match_columns' => array( //Required
            // db_field_name => col_name or regex to match col_name.
                'name' => '/_name/',
                'custom_product_ref' => '/_ref_can_valls/',
                'description' => '/_ref_can_valls/',
                'unit_price' => '/_net_price_box/',
                'iva_percent_id' => '/_id_iva/',
                'category_id' => '/_id_categoria/',
                'unit_measure_order_id' => '/_id_uni/',
                'unit_measure_shop_id' => '/_id_uni/'
            ),
            'forced_values' => array( //optional
                'active' => '1',
                'rev_tax_type_id' => 4
            ),
            'updatable_columns' => array( //optional: default is all columns
                'name', 'unit_price', 'iva_percent_id',
                // updateable columns of forced_values should be included.
                'active', 'rev_tax_type_id'
            )
        )
    )
);

Les patilles permeten: afegir, actualitzar i desactivar productes si es configura adequadament:

'options' => array( //optional
    'import_mode' => '2', // '0' update only (default mode)
                          // '1' insert all
                          // '2' insert new and update existing
    'deactivate_products' => true // option only for products
),

(si el codi de producte custom_product_ref + proveïdor ja existeix a la BD s'actualitza i en cas contrari se'n crea un de nou. Tota la resta de productes del proveïdor queden desactivats)

Així si el proveïdor usa codi de producte la cosa funciona força be. En cas contrari es pot fer servir el nom com a codi dient per exemple 'custom_product_ref' => 'nom', del cas begues4. Però atenció en el mateix full no es pot repetir el codi de producte en dues files diferents.


En aquest car al importar apareixen dues plantilles: image


També cal parar compte al apartat 'forced_values', i en concret posar-hi sempre 'active' => '1' per que es reactivin el productes actualitzats.


En el nostre cas els fulls Excel tenen formules, és difícil evitar-ho, per exemple per buscar el 'unit_measure_order_id'.
Usem un Excel on a les primeres columnes de 'Hoja1' es copien les columnes que que venen del full del proveïdor, i a continuació hi ha columnes amb formules.
En aquest Excel en full 'unitats' hi consten les equivalències de les unitats del proveïdor amb el 'unit_measure_order_id', i a la columna L que va encapçalada per id_unitat hi ha la formula =BUSCARV(L2;unitats!A:B;2;FALSO)

jorix commented 3 years ago

Ah! per no tenir problemes amb accents i caràcters especials usem public $import_from_char_encoding = 'Windows-1252';

Monicafgz commented 3 years ago

Moltes gràcies de nou per l'explicació @jorix! Tinc el dubte de com ha de ser aquest fitxer que es vol importar a la base de dades, ja que en els fitxers que l'aixada exporta (CSV, XML) apareixen tots els camps en una sola línea i entenc que aquest no és el format que poden treballar els proveïdors... Gràcies!

jorix commented 3 years ago

... en els fitxers que l'aixada exporta...

La importació és un altre cosa.

@Monicafgz El més fàcil, és importar un full de càlcul (com et comentava més amunt, segurament acabareu tenint un full amb formules vostres per adaptar per exemple les unitats...)

okcomputerik commented 2 years ago

Hola!

Abans de tot, moltes gràcies a tots i totes que manteniu aquest projecte, enhorabona!

Us escric des de Sant Pere de Ribes perquè a la nostre cooperativa volem començar a fer servir l'Aixada. Ja ho tenim tot muntat i hem estat fent algunes proves. De moment tot funciona de meravella, llevat de la importació mitjançant la plantilla. Hem configurat tot tal com explica més a dalt @jorix:

public $import_templates = array(
        // Table any db_field_name must be allowed by $allow_import_for.
        'aixada_product' => array(
            // Template name
            'can_pere' => array(
                'options' => array( //optional
                    'import_mode' => '2', // '0' update only (default mode)
                                          // '1' insert all
                                          // '2' insert new and update existing
                    'deactivate_products' => true // option only for products
                ),
                'required_fields' => array( //optional
                    // Rows without a required fields are ignored.
                    'custom_product_ref', 'name', 'unit_price', 'iva_percent_id'
                ),                    
                'match_columns' => array( //Required
                // db_field_name => col_name or regex to match col_name.
                    'custom_product_ref' => '/.*_product_ref/',
                    'name' => '/.*name/',
                    'unit_price' => '/.*unit_price/',
                    'unit_measure_order_id' => '/.*unit_measure_order_id/',
                    'unit_measure_shop_id' => '/.*unit_measure_shop_id/',
                    'description' => '/.*description/',
                    'iva_percent_id' => '/.*iva_percent_id/',
                    'category_id' => '/.*category_id/'
                ),
                'forced_values' => array( //optional
                    'active' => '1',
                    'rev_tax_type_id' => '4'
                ),
                'updatable_columns' => array( //optional: default is all columns
                    'name', 'unit_price', 'iva_percent_id', 'unit_measure_order_id', 'unit_measure_shop_id', 'description', 'iva_percent_id', 'category_id',
                    // updateable columns of forced_values should be included.
                    'active', 'rev_tax_type_id'
                )
            )
        )
    );

Però quan volem actualitzar l'oferta de productes setmanalment amb l'opció "2, insert new and update existing" ens surt un missatge d'error conforme el producte està "duplicat" a la base de dades. Per exemple: Aixada_error

Si activem l'opció "1, insert all", tot funciona correctament, però evidentment l'opció 2 és més atractiva per no haver de generar productes nous cada setmana i fer que la base de dades creixi innecessàriament.

Algú sap què estem fent malament (no es repeteix el codi de producte en dues files diferents al mateix full) o si es tracta més aviat d'un problema del programari? Jo intueixo que és més aviat un problema del programari perquè no passa amb tots els productes, només amb alguns, però no estic segur. I tampoc sé com corregir-ho...

Qualsevol ajuda serà molt benvinguda!

Gràcies!

jorix commented 2 years ago

Però quan volem actualitzar l'oferta...

Reviseu que dins del mateix full no hi hagi dues o més línies amb la mateixa referència!
(en el vostre cas 'custom_product_ref' => '/.*_product_ref/')

okcomputerik commented 2 years ago

Gràcies per la ràpida resposta @jorix !

Sí, ho hem revisat varies vegades i no és el cas. Alguna altre idea de quin pot ser el problema?

Gràcies!

jorix commented 2 years ago

Adjunteu full de càlcul, i reviso

okcomputerik commented 2 years ago

Aquí t'el deixo! 20211008.ods

Gràcies!

jorix commented 2 years ago

De la línia 250 a la 500 consta __ com a referència!

okcomputerik commented 2 years ago

Ostres, vaja tonteria... Sembla que sí és això. Com que no hi ha productes no hi havia comptat que la formula també genera un codi i es duplica amb cada línia buida.

En faré més proves a veure si realment és això!

Moltíssimes gràcies, @jorix !