WoocommerceWordpress

Woocommerce: inserire campi per Codice Fiscale e partita IVA

Avevo l’esigenza di aggiungere i campi per Codice Fiscale e Partita IVA su Woocommerce. Esistono decine di plugin che permettono di farlo, ma preferisco sempre evitare di installare troppi plugin e quando posso, sopratutto se si tratta di cose semplici, implementare io le funzioni che servono.

Ho trovato un ottimo articolo di Alessio Angeloro da cui ho preso i primi spunti. Ho poi aggiunto alcune funzionalità, come la validazione del codice fiscale e la memorizzazione dei dati nei metadati dell’utente.

Ma vediamo più nel dettaglio il codice. Per prima cosa creiamo i campi necessari:

//creo il campo codice fiscale
add_filter( 'woocommerce_checkout_fields' , 'codice_fiscale' );

function codice_fiscale( $fields ) {
	$fields['billing']['codice_fiscale'] = array(
	'label'     => __('Codice Fiscale', 'woocommerce'),
	'placeholder'   => _x('Codice Fiscale', 'placeholder', 'woocommerce'),
	'required'  => true,
	'class'     => array('form-row-last'),
	'clear'     => true,
	'priority'  => 180
	);

	return $fields;
}   

add_action( 'woocommerce_checkout_update_order_meta', 'codice_fiscale_order_meta' );

function codice_fiscale_order_meta( $order_id ) {
	if ( ! empty( $_POST['codice_fiscale'] ) ) {
		update_post_meta( $order_id, 'Codice Fiscale', strtoupper( sanitize_text_field( $_POST['codice_fiscale'] ) ) );
	}
}


// creo il campo partita iva
add_filter( 'woocommerce_checkout_fields' , 'partita_iva' );

function partita_iva( $fields ) {
	$fields['billing']['partita_iva'] = array(
	'label'     => __('Partita Iva', 'woocommerce'),
	'placeholder'   => _x('Partita Iva', 'placeholder', 'woocommerce'),
	'required'  => false,
	'class'     => array('form-row-last'),
	'clear'     => true,
	'priority'  => 190
	);

	return $fields;
}

add_action( 'woocommerce_checkout_update_order_meta', 'partita_iva_order_meta' );

function partita_iva_order_meta( $order_id ) {
	if ( ! empty( $_POST['partita_iva'] ) ) {
		update_post_meta( $order_id, 'Partita Iva', sanitize_text_field( $_POST['partita_iva'] ) );
	}
}

Ora dobbiamo fare in modo che questi campi vengano inseriti nel backend, in modo che siano visibili nei dettagli dell’ordine, e nelle mail di notifica:

//inserisco il codice fiscale nel back end
add_action( 'woocommerce_admin_order_data_after_billing_address', 'codice_fiscale_order_meta_admin', 10, 1 );

function codice_fiscale_order_meta_admin($order){
	echo '<p><strong>'.__('Codice Fiscale').':</strong> ' . get_post_meta( $order->id, 'Codice Fiscale', true ) . '</p>';
}

//inserisco il codice fiscale nella mail dell'ordine
add_filter('woocommerce_email_order_meta_keys', 'my_custom_fiscale_order_meta_keys');

function my_custom_fiscale_order_meta_keys( $keys ) {
	$keys[] = 'Codice Fiscale';
	return $keys;
}

//inserisco la partita iva nel back end
add_action( 'woocommerce_admin_order_data_after_billing_address', 'partita_iva_order_meta_admin', 10, 1 );

function partita_iva_order_meta_admin($order){
	echo '<p><strong>'.__('Partita Iva').':</strong> ' . get_post_meta( $order->id, 'Partita Iva', true ) . '</p>';
}

//inserisco la partita iva nella mail dell'ordine
add_filter('woocommerce_email_order_meta_keys', 'my_custom_partita_iva_order_meta_keys');

function my_custom_partita_iva_order_meta_keys( $keys ) {
	$keys[] = 'Partita Iva';
	return $keys;
}

Fatto questo possiamo aggiungere una funzione che memorizza i dati inseriti nel profilo utente, così che il nostro cliente non debba digitarli ogni volta:

// Imposto gli attributi in modo che vengano salvati nel profilo utente:  
function cf_checkout_update_user_meta( $customer_id, $posted ) {
	if (isset($posted['partita_iva'])) {
		$partita_iva = sanitize_text_field( $posted['partita_iva'] );
		update_user_meta( $customer_id, 'partita_iva', $partita_iva);
	}
	if (isset($posted['codice_fiscale'])) {
		$codice_fiscale = sanitize_text_field( $posted['codice_fiscale'] );
		update_user_meta( $customer_id, 'codice_fiscale', $codice_fiscale);
	}

}
add_action( 'woocommerce_checkout_update_user_meta', 'cf_checkout_update_user_meta', 10, 2 );

Per concludere possiamo aggiungere una semplice validazione del codice fiscale: usando il codice di Manuel Marangoni possiamo controllare che il Codice Fiscale non sia vuoto, abbia la giusta lunghezza (16 caratteri) e che il codice di controllo (l’ultimo carattere della stringa).

L’ideale sarebbe controllare tutto il codice fiscale, ma non avendo data e luogo di nascita non è possibile. Se il vostro checkout prevede tra i campi anche la data di nascita si può integrare la funzione per questo ulteriore controllo.

//validazione del codice fiscale
function required_cf_checkout_field_process() {
	if ( $_POST['codice_fiscale'] && ! codiceFiscale($_POST['codice_fiscale'] ))
		wc_add_notice( __( 'Devi inserire un codice fiscale valido per inoltrare l\'ordine.' ), 'error' );
}

// code by Manuel Marangoni - http://www.manuelmarangoni.it 

/** controllo del codice fiscale **/
function codiceFiscale($cf){
	
	if($cf=='')
		return false;
	
	if(strlen($cf)!= 16)
		return false;
		
	$cf=strtoupper($cf);
	if(!preg_match("/[A-Z0-9]+$/", $cf))
		return false;

	$s = 0;
	
	for($i=1; $i<=13; $i+=2){
		$c=$cf[$i];
		if('0'<=$c and $c<='9')
			$s+=ord($c)-ord('0');
		else
			$s+=ord($c)-ord('A');
	}
	
	for($i=0; $i<=14; $i+=2){
		$c=$cf[$i];
		switch($c){
			case '0':  $s += 1;  break;
			case '1':  $s += 0;  break;
			case '2':  $s += 5;  break;
			case '3':  $s += 7;  break;
			case '4':  $s += 9;  break;
			case '5':  $s += 13;  break;
			case '6':  $s += 15;  break;
			case '7':  $s += 17;  break;
			case '8':  $s += 19;  break;
			case '9':  $s += 21;  break;
			case 'A':  $s += 1;  break;
			case 'B':  $s += 0;  break;
			case 'C':  $s += 5;  break;
			case 'D':  $s += 7;  break;
			case 'E':  $s += 9;  break;
			case 'F':  $s += 13;  break;
			case 'G':  $s += 15;  break;
			case 'H':  $s += 17;  break;
			case 'I':  $s += 19;  break;
			case 'J':  $s += 21;  break;
			case 'K':  $s += 2;  break;
			case 'L':  $s += 4;  break;
			case 'M':  $s += 18;  break;
			case 'N':  $s += 20;  break;
			case 'O':  $s += 11;  break;
			case 'P':  $s += 3;  break;
			case 'Q':  $s += 6;  break;
			case 'R':  $s += 8;  break;
			case 'S':  $s += 12;  break;
			case 'T':  $s += 14;  break;
			case 'U':  $s += 16;  break;
			case 'V':  $s += 10;  break;
			case 'W':  $s += 22;  break;
			case 'X':  $s += 25;  break;
			case 'Y':  $s += 24;  break;
			case 'Z':  $s += 23;  break;
		}
	}
	
	if( chr($s%26+ord('A'))!=$cf[15] )
		return false;
		
	return true;
}

Trovate il codice completo su GitHub.

Nota importante: il codice che ho indicato va considerato sperimentale, sconsiglio di usarlo in ambienti di produzione senza averlo testato prima in ambienti staging e sopratutto fate sempre un backup prima di qualunque modifica!

L’ho testato con Woocommerce 4.2.2, versioni diverse potrebbero avere strutture dati diverse e quindi questo approccio potrebbe non essere corretto.