• User Attivo

    @g-lanzi ciao alura premetto che non sono un woo dev quindi sono andato un pelino a tentativi ma:

    qui https://wordpress.stackexchange.com/questions/215219/how-to-display-custom-field-in-woocommerce-orders-in-admin-panel
    dice che i custom field con _ davanti sono hidden e quindi non li vedi nel backend
    ed in effetti ho fatto la prova col tuo codice e non si vede.

    poi sono andato a vedere un sito fatto tempo fa in cui ho inserito il custom field senza _ e in effetti in back end, quando fai ordine manuale si vede.

    per inserire il dato, lo fai dalla sezione "campi personalizzati" mettendo il nome dei tuoi custom field ed il valore. una volta che salvi l'ordine te lo visualizza anche sopra nel riepilogo!

    poi se per caso non vedi la sezione campi personalizzati, puo essere che stai usando anche ACF? nel caso metti questo :
    add_filter('acf/settings/remove_wp_meta_box', '__return_false');

    e dovrebbe ricomparire ( testa che non si sa mai)

    qui la spiegazione del _ che non mostra i custom field
    https://developer.wordpress.org/reference/functions/add_post_meta/


  • User Attivo

    aggiungo:
    in questo pezzo di codice:

    add_action( 'woocommerce_admin_order_data_after_billing_address', 'planb_show_new_checkout_field_order', 10, 1 );
    function planb_show_new_checkout_field_order( $order ) {    
       $order_id = $order->get_id();
       if ( get_post_meta( $order_id, '_billing_pec', true ) ) echo '<p><strong>PEC:</strong> ' . get_post_meta( $order_id, '_billing_pec', true ) . '</p>';
       if ( get_post_meta( $order_id, '_billing_piva', true ) ) echo '<p><strong>P. Iva:</strong> ' . get_post_meta( $order_id, '_billing_piva', true ) . '</p>';
    }
    

    se lasci il ciclo if, non ti spara l'echo
    togli

    if ( get_post_meta( $order_id, '_billing_pec', true ) ) 
    if ( get_post_meta( $order_id, '_billing_piva', true ) ) 
    

    e ti compariranno i due campi nel riepilogo

    per capirci, li chiedi se quei campi sono riempiti, ma siccome stai gacendo un ordine manuale sono ovviamente vuoti, quindi se lasciato cosi non passeranno mai il ciclo

    test.jpeg


    g.lanzi 1 Risposta
  • Moderatore

    @shazarak
    Grazie per la risposta.

    In effetti la metabox dei campi personalizzati era nascosta e i campi sono selezionabili.
    Tuttavia, quando li seleziono mentre faccio un ordine manuale, questi poi non si vedono tra i campi di fatturazione, ma solo tra i campi personalizzati.

    2022-02-02_07-40-19.jpeg

    Inoltre, dopo le modifiche che mi hai suggerito, se i campi sono compilati in frontend, questi non vengono visualizzati nel riepilogo ordine in backend. Rimettendo il _ davanti al nome campo, si vedono di nuovo e sono anche selezionabili da quelli personalizzati nella metabox. Ma comunque non si vedono sotto all'indirizzo una volta salvati.

    La cosa che mi interessa di più, tuttavia, è che siano disponibili tramite API, e al momento non vengono inviati.

    Continuo la ricerca di una soluzione, dunque. Per fortuna sono campi opzioni per una richiesta automatica di spedizioni con un servizio di logistica, ma se riuscissi a far passare anche questi dati, sarei ancora più soddisfatto.


    shazarak 1 Risposta
  • User Attivo

    @g-lanzi buondì !
    ti confermo che il tuo codice, adattato senza i cicli IF. funziona, lo screenshot che ti ho postato ieri arriva da una installazione vergine di woocommerce su localWP

    se ti da problemi posso supporre ci sia altro che "infastidisce" il flusso dati?

    ho fatto una prova con un webhook al volo e i dati li manda, devo supporre che quindi manda i due campi personalizzati anche con le api ( ma è oltre le mie competenze correnti quindi fai i debiti test)
    ti mando in privato l'url col video perche non so se posso postarlo pubblicamente 😛

    questo il tuo codice adattato

    add_filter( 'woocommerce_checkout_fields', 'planb_custom_checkout_fields');
    function planb_custom_checkout_fields ($fields) {
        $fields ['billing']['billing_pec'] = [
            'label' => __( 'PEC', 'planb-text' ),
    		'class' => [ 'form-row' ],
    		'type' => 'email',
    		'validate' => [ 'email' ],
    		'priority' => 35,
        ];
        $fields ['billing']['billing_piva'] = [
    		'label' => __( 'Partita IVA', 'planb-text' ),
    		'class' => [ 'form-row' ],
    		'placeholder' => __( 'IT-XXXXXXXXX', 'planb-text' ),
    		'type' => 'text',
    		'priority' => 35,
    	];
        $fields['billing_phone']['required'] = true;
        return $fields;
    }
    
    add_action( 'woocommerce_checkout_update_order_meta', 'planb_save_new_checkout_field' );
    function planb_save_new_checkout_field( $order_id ) { 
        update_post_meta( $order_id, 'billing_pec', esc_attr( $_POST['billing_pec'] ) );
        update_post_meta( $order_id, 'billing_piva', esc_attr( $_POST['billing_piva'] ) );
    }
    add_action( 'woocommerce_admin_order_data_after_billing_address', 'planb_show_new_checkout_field_order', 10, 1 );
    function planb_show_new_checkout_field_order( $order ) {    
       $order_id = $order->get_id();
       echo '<p><strong>PEC:</strong> ' . get_post_meta( $order_id, 'billing_pec', true ) . '</p>';
       echo '<p><strong>P. Iva:</strong> ' . get_post_meta( $order_id, 'billing_piva', true ) . '</p>';
    }
    add_action( 'woocommerce_email_after_order_table', 'planb_show_new_checkout_field_emails', 20, 4 );
    function planb_show_new_checkout_field_emails( $order, $sent_to_admin, $plain_text, $email ) {
        echo '<p><strong>PEC:</strong> ' . get_post_meta( $order->get_id(), 'billing_pec', true ) . '</p>';
        echo '<p><strong>P. Iva:</strong> ' . get_post_meta( $order->get_id(), 'billing_piva', true ) . '</p>';
    }
    

    g.lanzi 1 Risposta
  • Moderatore

    @shazarak
    Grazie mille, visionerò il video. Per ora ho risolto rifacendo tutto, perché ero arrivato a incasinare un sacco il codice.

    <?php
    
    // Add new custom fields in checkout form on Checkout page
    
    // ## Billing address
    // Add new custom field to billing address
    add_filter( 'woocommerce_billing_fields', 'add_custom_billing_fields', 10, 1 );
    function add_custom_billing_fields( $address_fields ) {
        $address_fields['billing_piva'] = array(
           'label'     => __('P.Iva', 'woocommerce'),
           'required'  => false,
           'class'     => array('form-row-first'),
           'clear'     => true,
           'priority'  => 67
        );
        $address_fields['billing_pec'] = array(
           'label'     => __('PEC', 'woocommerce'),
           'type' => 'email',
           'required'  => false,
           'class'     => array('form-row-last'),
           'clear'     => true,
           'priority'  => 67
        );
        return $address_fields;
    }
    
    // ## Shipping address
    // Add new custom field to shipping address
    add_filter( 'woocommerce_shipping_fields', 'add_custom_shipping_fields', 10, 1 );
    function add_custom_shipping_fields( $address_fields ) {
        $address_fields['shipping_piva'] = array(
            'label'     => __('P.Iva', 'woocommerce'),
            'placeholder' => __('IT-xxxxxxxx', 'woocommerce'),
            'required'  => false,
            'class'     => array('form-row-first'),
            'clear'     => true,
            'priority'  => 67
        );
        $address_fields['shipping_pec'] = array(
            'label'     => __('PEC', 'woocommerce'),
            'type' => 'email',
            'placeholder' => __('IT-xxxxxxxx', 'woocommerce'),
            'required'  => false,
            'class'     => array('form-row-last'),
            'clear'     => true,
            'priority'  => 67
        );
        return $address_fields;
    }
    
    // 2 - Display the custom fields on Order Received page(Thank you page), email notification, and admin order edit page.
    
    // ## Billing address
    add_filter( 'woocommerce_order_formatted_billing_address', 'woocommerce_order_formatted_billing_address' , 10, 2) ;
    function woocommerce_order_formatted_billing_address( $fields, $order ) {
        $fields['piva'] = get_post_meta($order->id, '_billing_piva', true);
        $fields['pec'] = get_post_meta($order->id, '_billing_pec', true);
        return $fields;
    }
    
    // ## Shipping address
    add_filter( 'woocommerce_order_formatted_shipping_address', 'woocommerce_order_formatted_shipping_address' , 10, 2 );
    function woocommerce_order_formatted_shipping_address($fields, $order) {
        $fields['piva'] = get_post_meta($order->id, '_shipping_piva', true);
        $fields['pec'] = get_post_meta($order->id, '_shipping_pec', true);
        return $fields;
    }
    
    // ## My Account > Addresses page 
    add_filter( 'woocommerce_my_account_my_address_formatted_address', 'woocommerce_my_account_my_address_formatted_address', 10, 3 ); 
    function woocommerce_my_account_my_address_formatted_address( $args, $customer_id, $name ) {
        $args['piva'] = get_user_meta( $customer_id, $name . '_piva', true );
        $args['pec'] = get_user_meta( $customer_id, $name . '_pec', true );
        return $args;
    }
    
    // --------------------------------------------------------------
    // 3 - update the preformatted address template from Woocommerce
    // --------------------------------------------------------------
    
    // Note that, billing_email and billing_phone don't include in the preformat address from Woocommerce.
    // On admin order edit page, those two fields will be displayed under the address section.
    
    add_filter( 'woocommerce_localisation_address_formats', 'woocommerce_localisation_address_formats_filter', 20 );
    add_filter( 'woocommerce_formatted_address_replacements', 'woocommerce_formatted_address_replacements', 20, 2 );
    function woocommerce_localisation_address_formats_filter( $address_formats ) {
    
        foreach( $address_formats as $country_code => $address_format ) {      
            // you can reorder the field placeholder from this address format.
            // below we want to display the house number above firstname and lastname fields for Japan only.
            $address_formats[$country_code] = "{company}\n{last_name} {first_name}\n{address_1}\n{address_2}\n{postcode}, {state}\n{city} {country}";                   
        }
        return $address_formats;
    }
    
    function woocommerce_formatted_address_replacements( $fields, $args ) {
        foreach ( $args as $field_name => $field_value ) {
            if ( !isset( $fields['{' . $field_name . '}'] ) ) {
                $fields['{' . $field_name . '}'] = $field_value;
            }
        }
        return $fields;
    }
    
    // --------------------------------------------------------------
    // 4 - add the editable custom field in admin order edit page
    // --------------------------------------------------------------
    
    // ## Billing address - editable fields
    add_filter( 'woocommerce_admin_billing_fields' , 'add_editable_billing_fields_in_order_edit_page' );
    function add_editable_billing_fields_in_order_edit_page( $fields ) {
        $tmp = array();
        foreach($fields as $field_name=>$attr) {
            // we want to show the house number input field after the company input field.
            if( $field_name === 'address_1' ) {
                $tmp['piva'] = array( 
                    'label' => __('Partita Iva','woocommerce'), 
                    'show' => true
                );
                $tmp['pec'] = array(
                    'label' => __('PEC', 'woocommerce'),
                    'show' => true
                );
            }
            $tmp[$field_name] = $attr;
        }
        $fields = $tmp;
        return $fields;
    }
    
    // ## Shipping address - editable fields
    add_filter('woocommerce_admin_shipping_fields', 'add_editable_shipping_fields_in_order_edit_page');
    function add_editable_shipping_fields_in_order_edit_page( $fields )
    {
        $tmp = array();
        foreach($fields as $field_name=>$attr) {
            if( $field_name === 'address_1' ) {
                $tmp['piva'] = array( 
                    'label' => __('Partita Iva','woocommerce'), 
                    'show' => true
                );
                $tmp['pec'] = array(
                    'label' => __('PEC', 'woocommerce'),
                    'show' => true
                );
            }
            $tmp[$field_name] = $attr;
        }
        $fields = $tmp;
        return $fields;
    }
    

    Ho tenuto separati tutte le fasi e le aggiunte. Ora funziona così:

    Nell front end ci sono i due campi nuovi. Quando si acquista, vengono salvati i dati nell'ordine come meta. Nel backend sono modificabili come gli altri campi di fatturazione o spedizione, ossia cliccando sulla matita/icona di modifica degli indirizzi.
    Se non sono presenti, i campi non si vedono, se sono compilati, sono mostrati tra i dati di fattirazione/invio.

    Quando si crea un nuovo ordine in backend, i campi ci sono tra quelli degli indirizzi e sono modificabili.

    Vengono inviati con le API come metadati. Purtroppo io non riesco ad usarli perché, per un motivo a me ignoto, su Integromat i dati vengono ricevuti dal modulo di recupero dati ordine, ma poi non sono disponibili per i moduli successi. Questo è però un altro problema.


    shazarak 1 Risposta
  • User Attivo

    @g-lanzi ahaha figo!

    nel frattempo mi è venuta curiosità e ho provato l'invio di un api con postman, e ti confermo che i dati arrivano
    Screenshot of https___demowoo.local_wp-json_wc_v2_orders - My Workspace.jpg

    qua il video di cui ti parlavo prima se non me lo toglie
    https://www.loom.com/share/9498387f791b4036947b5b4356fa9789


    g.lanzi 1 Risposta
  • Moderatore

    @shazarak
    Il video è muto oppure ho un problema di audio io?

    Eh, infatto ho visto che i dati sono inviati come meta dati, purtroppo non riesco a usarli, ma è un problema diverso di Integromat con cui sto sviluppando degli automatismi con una API di una ditta di logistica.

    Proverò a fare una richiesta manuale senza usare il modulo WooCommerce, che i meta dati li riceve, ma, non capisco perché, non li passo richiamare nei moduli successivi in modo corretto.


    shazarak 1 Risposta
  • User Attivo

    @g-lanzi alura Integromat

    inizi col trigger New Event INSTANT ACID
    e ti crei la connessione con la tua api woocommerce

    il secondo modulo è Get an Order
    leghi la connessione appena creata e usi Object_ID per il campo Order ID

    dal terzo modulo in avanti usi quel che ti pare, io per testare ho usato la funzione di invio email

    in pratica nel secondo modulo dall'elenco metadata troverai una serie di collection
    individui quelle che ti servono e ti segni che numeri sono

    nel modulo successivo usi quindi il valore KEY, ci clicchi sopra e gli mezzi il numero corrispondente

    e poi mandi i dati dove vuoi !

    uno.jpeg
    due.jpeg


    g.lanzi 1 Risposta
  • User Attivo

    @g-lanzi ahaah si si è muto scusa,

    per integromat ti ho appena risposto, prova dovrebbe funzionare

    ah beh io ho usato il tuo codice iniziale adattato, ora che ne usi uno diverso migliore, fai le debite comparazioni e test 🙂


  • Moderatore

    @shazarak
    Ah, questa cosa di poter scegliere la collezione dagli array non la sapevo. Gli array inviati arrivano sempre nello stesso ordine anche se vuoti, a quanto pare, e quindi direi che ho risolto il problema!

    Grazie mille!


  • Moderatore

    #woocommerce #api #integromat #metadati

    Ho trovato un modo più sicuro per selezionare il metadato corretto dalla risposta del modulo di WooCommerce. È applicabile a tutte le collezioni di array:

    Collezione array tipo:

    "metadata": [
        {
            "Meta data ID": "23456",
            "key": "_billing_piva",
            "value": "IT-09876543210"
        }
        {
            "Meta data ID": "9873687",
            "key": "_billing_pec",
            "value": "[email protected]"
        }
    ]
    

    Usare l'indicizzazione dell'array è possibile, ma è sconsigliato. Per questo, si dovrebbe cercare dove si trova il valore corretto e poi prelevarlo. Con questa formula si ottiene questo:

    {{get(map(13.metaData; "value"; "key"; "_billing_pec"); 1)}}

    Qui una spiegazione dalla documentazione di Integromat che spiega sicuramente meglio di me: https://www.integromat.com/en/help/mapping?fbclid=IwAR0kAd_75itJ_LIpBDKNF7zWGNEANKOeO4c-s0Ss13q-i20n-bwzIOZB3H4

    In questo modo è possibile recuperare il dato desiderato dall'array metadati, a prescindere alla posizione nell'indice, ma basandosi sul nome (o sulla key) della collezione.