UNIVERSITÀ DEGLI STUDI DI PARMA FACOLTÀ DI SCIENZE MATEMATICHE FISICHE E NATURALI Corso di Laurea in Informatica Tesi di Laurea Triennale Sistema di gestione contenuti per portale e-commerce nordamericano Candidato: Andrea Gandol Relatore: Prof. Giulio Destri Anno Accademico 2011/2012 ii iii A Elisa iv v Ringraziamenti Desidero innanzitutto ringraziare i miei genitori Sergio e Renata, mia sorella Cristina ed Elisa per il loro sostegno durante questi anni di studio. Un ringraziamento particolare a Franco Folini e Cristiano Sacchi di Novedge LLC per avermi dato la possibilità di lavorare con loro sviluppando il progetto descritto in questa tesi. Ringrazio l'Ing. Cesare Chiodelli e il Prof. Giulio Destri che, n dalla scuola supe- riore, è stato per me una guida e un punto di riferimento per quanto riguarda il settore informatico. Inne un grazie a tutti gli amici del dipartimento con cui ho condiviso quest'avvenura: Leonardo Bacchi, Federico Fontana, Federico Bacchi, Andrea Disarò, Federico Ferretti, Matteo Masi, Davide Ponzo, Simone Bertocchi, Alice Pavarani, Beatrice Demaldè, Jessica Groppi, Ilaria Fulcini, Martina Bonanzi e tanti altri. vi INDICE 1 Introduzione 1 2 Il contesto 3 2.1 E-Commerce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.1.1 Tipologie di e-commerce . . . . . . . . . . . . . . . . . . . . . . . 4 2.1.2 Il problema della sicurezza . . . . . . . . . . . . . . . . . . . . . . 6 3 2.2 Content Management System . . . . . . . . . . . . . . . . . . . . . . . . 7 2.3 Novedge e il suo business model . . . . . . . . . . . . . . . . . . . . . . . 8 2.4 L'architettura del sistema 9 . . . . . . . . . . . . . . . . . . . . . . . . . . Obiettivi del progetto di tesi ed analisi 13 3.1 Analisi dei requisiti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.2 Le entità da gestire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.2.1 Prodotti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.2.2 Brand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.2.3 Special . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.2.4 Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.2.5 Categorie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.2.6 Documenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.2.7 Aree 17 3.2.8 Clusters 3.2.9 Ordini . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 viii INDICE 3.2.10 Free Download 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.2.11 Webinar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.3 Elenco degli attori e use case . . . . . . . . . . . . . . . . . . . . . . . . . 20 3.4 Coordinamento del progetto 22 Progettazione 23 4.1 La situazione prima del progetto . . . . . . . . . . . . . . . . . . . . . . . 24 4.2 Speciche software 24 4.3 Struttura del progetto 4.4 Struttura delle singole applicazioni . . . . . . . . . . . . . . . . . . . . . 26 4.5 Le interfacce utente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.6 La base di dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 4.7 I web service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.8 Le tecnologie utilizzate . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4.8.1 HTML, CSS e JavaScript . . . . . . . . . . . . . . . . . . . . . . 31 4.8.2 ASP.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.8.3 jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.8.4 AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.8.5 JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.8.6 Amazon Web Services 4.9 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 . . . . . . . . . . . . . . . . . . . . . . . . 33 Gli strumenti utilizzati . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 Implementazione 37 5.1 La libreria Novedge Base . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 5.2 La barra di navigazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 5.3 L'applicazione Products . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 5.3.1 L'autocompletamento dei prodotti . . . . . . . . . . . . . . . . . . 51 5.3.2 Sistema dei messaggi . . . . . . . . . . . . . . . . . . . . . . . . . 54 5.3.3 Il plugin Wikipedia . . . . . . . . . . . . . . . . . . . . . . . . . . 55 5.4 L'applicazione Books . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 5.5 L'applicazione Specials . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 5.6 L'applicazione Documents . . . . . . . . . . . . . . . . . . . . . . . . . . 66 5.7 L'applicazione Orders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 5.8 L'applicazione Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 INDICE ix 5.9 Altre applicazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5.10 Web services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5.11 Validazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 5.12 Liste per la consultazione delle entità . . . . . . . . . . . . . . . . . . . . 77 5.13 Funzioni di Wall e Log 79 Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 CAPITOLO 1 INTRODUZIONE Il lavoro della presente tesi nasce entro la collaborazione tra il Professor Giulio Destri e la sua azienda AREA Professional e l'azienda statunitense Novedge, fondata nel 2003 a San Francisco da due italiani, Franco Folini e Cristiano Sacchi, che è diventata oggi il più grande rivenditore online al mondo di software per il CAD. Novedge opera on-line attraverso un grande portale di vendita dei prodotti, aancato da numerosi servizi che provvedono contenuti utili per gli utenti e da alcune vere e proprie community di utenti, integrate con i principali social network. Attraverso una ottimizzazione spinta dei propri processi aziendali, Novedge riesce a garantire ai suoi clienti (principalmente progettisti meccanici, architetti, artisti 3D e game developer) prezzi scontati rispetto a quelli di listino eettuati da altri rivenditori, fornendo spedizioni veloci e un supporto di base no all'installazione del software. L'ottimizzazione dei processi è basata anche su una ampia automazione dei processi stessi, attraverso software scritto ad hoc ed integrato con servizi presenti in rete come quelli di Amazon. Dopo 10 anni di operatività coronata da successo, a causa della sua stessa espansione negli anni, Novedge si è trovata nella necessità di una revisione ed ammodernamento del proprio software interno. Tale operazione è stata compiuta sia da un punto di vista funzionale, sia adottando una nuova piattaforma tecnologica: ASP.NET 4 ed il linguaggio C#. La denizione delle nuove necessità funzionali è stata compiuta dai fondatori stessi di 2 Introduzione Novedge e l'architettura tecnica delle nuove applicazioni è stata denita dal Dr. Franco Folini col contributo del Professor Destri. Il lavoro della tesi si è inserito in questo contesto ed è consistito nella realizzazione dei moduli del nuovo sistema di gestione dei contenuti (CMS) del portale, attraverso cui gli addetti di Novedge caricano i prodotti, seguendo le speciche di analisi formalizzate dal Dr. Folini. La libreria Novedge.Base, estesa ed integrata nel sistema in seguito da me, è stata scritta dal Dr. Folini stesso. Durante le fasi di analisi, progettazione e realizzazione dell'applicazione CMS si è utilizzata una metodologia agile di sviluppo in modo di coinvolgere il più possibile il committente ed avere quindi un feedback continuo riguardo allo stato del progetto e alle sue richieste. Per far ciò è stato fondamentale l'utilizzo di strumenti di comunicazione e coordinamento in quanto, data la distanza dagli uci Novedge, è stato impossibile un contatto diretto per tutta la durata del progetto. Solo alla ne, con un viaggio negli USA, ho potuto lavorare di persona alcune settimane entro la sede di Novedge. Durante la progettazione e la realizzazione del CMS si sono rivelate fondamentali le nozioni apprese durante il mio percorso di studi in informatica presso l'università degli studi di Parma. Partendo dai corsi di fondamenti di programmazione, algoritmi e strutture dati e fondamenti dell'informatica che coprono gli aspetti basilari dell'informatica e della programmazione, arrivando ai corsi più specici come metodologie di programmazione, basi di dati, ingegneria del software e linguaggi di programmazione che arontano tematiche e argomenti fondamentali per un informatico in quanto insegnano nozioni, metodologie e procedure che, ad oggi, sono ampiamente utilizzate in ogni ambiente complesso in cui si fa uso di calcolatori. Man mano che prendevo conoscenza del sistema e della sua struttura, ho potuto contribuire non solo con la stesura del codice ma anche con evoluzioni rispetto all'architettura di dettaglio inizialmente denita. La tesi è organizzata in capitoli: il capitolo 2 presenta una visione del commercio elettronico e dell'azienda Novedge, provvedendo il contesto in cui il lavoro della tesi è nato; i capitoli successivi mostrano il lavoro secondo le modalità canoniche apprese nel corso di ingegneria del software: obiettivi ed analisi, progettazione, implementazione. conclusioni completano il progetto con le future prospettive ed estensioni. Le CAPITOLO 2 IL CONTESTO 2.1 E-Commerce Con il termine e-commerce o commercio elettronico ci si riferisce a quell'insieme di attività d'impresa, per lo scambio di beni o servizi, in cui la transazione tra le parti avviene attraverso reti di telecomunicazione. Il signicato del termine è mutato nel tempo. In principio indicava semplicemente l'uso del calcolatore come strumento di supporto per lo scambio di documenti al ne di velocizzare una transazione commerciale, mentre oggi, grazie al continuo sviluppo di Internet e delle tecnologie basate sul Web, si dispone di tecnologie più avanzate che permettono di gestire in modo completo l'acquisto di beni e servizi attraverso il Wold Wide Web ricorrendo ad esempio a connessioni sicure e metodi di pagamento elettronici come le carte di credito. Il fattore che più di tutti ha spinto la crescita di questo modo di fare business è sicuramente l'abbattimento dei costi ssi dato che, non essendo necessario un negozio sico, diventa possibile anche per piccole aziende o persino per privati aprire il proprio negozio online e potenzialmente attirare clienti da ogni parte del mondo. 4 Il contesto 2.1.1 Tipologie di e-commerce Il commercio elettronico si divide in diverse tipologie in base all'attività commerciale in cui si svolge l'attività e ai soggetti coinvolti che possono avere esigenze diverse. Tale suddivisione inuenza anche la scelta degli strumenti tecnologici che un'azienda adotta. Possiamo identicare quindi tre principali tipologie: • Commercio elettronico tra aziende (B2B): Con questo termine si indica un'attività a supporto delle transazioni commerciali tra aziende e non coinvolge direttamente gli utilizzatori nali dei beni e servizi prodotti. I soggetti coinvolti sono aziende che si servono dei prodotti di altre aziende per realizzare i propri. Un esempio classico è la gestione della catena di distribuzione. • Commercio elettronico tra aziende e consumatori (B2C): Questa è la forma più nota di e-commerce e rigurda la fornitura di beni e servizi tra un'azienda e il consumatore nale. In questo caso il consumatore si reca sulla pagina web dell'azienda e può visualizzare ed eventualmente acquistare i prodotti mostrati eettuando pagamenti online. La maggior parte dei siti di e-commerce che fanno parte di questa categoria comprendono almeno i seguenti elementi: 1. Un catalogo elettronico dei prodotti e servizi oerti. 2. Un'area di navigazione e ricerca che permette di trovare facilmente i prodotti. 3. Un sistema di carrello virtuale dove l'utente può aggiungere gli oggetti da acquistare e procedere eventualmente al pagamento e all'evasione dell'ordine. 4. Un sistema di pagamento online sicuro. 5. Un sistema di controllo degli ordini che permette di seguire il processo di elaborazione dell'ordine e facilitarne il tracciamento. • Commercio elettronico tra consumatori (C2C): Questa forma di commercio è più recente rispetto alle altre ed è diventata popolare grazie ai siti di aste online (primo fra tutti eBay), che orono al consumatore la possibilità di vendere ad altri consumatori i propri prodotti e servizi. In questo caso è il sito che ore il servizio di asta a imporre le regole e ad amministrare l'ambiente e gli utenti si registrano utilizzando i propri dati al ne di fornire le informazioni necessarie per garantire l'identità dei soggetti coinvolti nella trattativa. 2.1 E-Commerce 5 Per realizzare e gestire un'attività di commercio elettronico di tipo B2C occorre tenere in considerazione alcuni fattori cruciali necessari per il successo: • Creazione del valore per il cliente orendo prodotti o servizi di qualità a prezzi competitivi. • Ispirare ducia e sicurezza. • Puntare sul web-marketing, ovvero pubblicità e azioni sui social network per farsi conoscere e creare un'immagine seria e adabile dell'azienda. • Creare un sito web accattivante e di facile utilizzo. • Incentivare il cliente all'acquisto e delizzarlo proponendo sconti e oerte speciali. • Cercare di conoscere il cliente senza però essere troppo invadenti. • Assistere il cliente nel suo ruolo di consumatore. Anche se un venditore seguisse le linee guida sopra citate possono comunque sorgere alcune problematiche, tra le quali: • Dicoltà nella comprensione del comportamento dei clienti ovvero capire le aspettative e le motivazioni che spingono la clientela ad acquistare un certo prodotto. • Mancanza di analisi dello scenario concorrenziale. • Incapacità di prevedere le reazioni nell'ambiente in cui opera l'impresa. Altri siti potrebbero copiare l'idea e vendere gli stessi prodotti o fornire lo stesso servizio. • Sovrastima delle competenze aziendali o dei sistemi hardware/software adottati. • Mancanza di coordinazione. • Incapacità nell'assicurarsi l'impegno dei vertici aziendali. Spesso non è possibile raggiungere un determinato obiettivo a causa delle scarse risorse allocate. • Incapacità nell'assicurarsi l'impegno dei dipendenti. Quando i progettisti non traducono in modo chiaro la loro strategia ai dipendenti. • Scarso addestramento all'utilizzo della piattaforma e-commerce realizzata da parte del committente. 6 Il contesto • Sottovalutazione dei tempi richiesti per il raggiungimento degli obiettivi aziendali. • Incapacità di rispettare la pianicazione dei tempi. • Incapacità di rispettare livelli di servizio, soprattutto i tempi, per le consegne ai clienti. 2.1.2 Il problema della sicurezza Oltre alle dicoltà elencate dovute alla gestione dell'impresa un altro problema da affrontare è quello della sicurezza sui dati. Durante l'acquisto on-line viaggiano su Internet dati sensibili come le generalità del cliente e soprattutto durante la fase di pagamento della merce è necessario utilizzare metodi e tecnologie per evitare che persone esterne all'operazione intercettino queste informazioni e le utilizzino a scopo fraudolento. Si sono adottati quindi elevati standard di sicurezza per garantire questo tipo di riservatezza. In particolare la maggior parte dei siti di e-commerce ad oggi utilizzano le seguenti tecnologie: • L'HTTPS (HyperText Transfer Protocol Secure) è il risultato dell'applicazione di un protocollo di crittograa asimmetrica, come il TLS (Transport Layer Security) e il suo predecessore SSL (Secure Sockets Layer), al protocollo HTTP. In questo modo i dati viene creato un canale di comunicazione sicuro tra il client e il server attraverso uno scambio di chiavi pubbliche tra le parti. Una volta stabilito questo canale i dati che vi transitano sono decifrabili solamente dai due partecipanti alla comunicazione e non sono quindi intercettabili da altri. • Con la procedura di autenticazione il server chiede all'utente di identicarsi, generalmente inserendo uno username e una password associata, limitando il numero di tentativi in modo da evitare attacchi con tentativi ripetuti di trovare la password sugli account (i cosiddetti attacchi a forza bruta). Per questo motivo, oggi, viene sempre più consigliato all'utente il cambio periodico della propria password scegliendola di una certa complessità evitando, ad esempio, date di nascita e nomi propri di persona. • Il venditore può avvalersi della rma digitale per evitare il ripudio da parte del cliente della merce acquistata. Questa tecnologia fa sì che un contratto rmato digitalmente non possa essere disconosciuto da coloro che l'hanno sottoscritto. 2.2 Content Management System • 7 Un altro punto fondamentale è la sicurezza interna all'azienda, ovvero gestire la sicurezza e la manutenzione dei server su cui risiede la struttura di e-commerce sia nel caso in cui esso risieda presso l'azienda stessa sia nel caso in cui sia ospitato nei server di una società di hosting. 2.2 Content Management System Un CMS (Content Management System) è un'applicazione che facilita e rende più sicuro il compito dell'amministratore di inserire o modicare i contenuti di un sito internet dinamico. Questi software creano un livello (astrazione) tra il database dove vengono memorizzati i contenuti e le persone addette all'aggiornamento del sito web, svincolando costoro da conoscenze tecniche e orendo un ulteriore controllo sui dati che vengono inseriti. Esistono CMS di ogni genere, alcuni specializzati e progettati in base al tipo di contenuti da gestire (ad esempio blog, forum, siti di e-commerce) ed altri generici che si adattano a qualsiasi tipo di sito web. Possiamo inoltre dividere questi software in base alla piattaforma su cui possono operare che dipende dal linguaggio di programmazione utilizzato e dal framework su cui si appoggiano; tra i più comuni troviamo PHP, ASP.NET e Java. Oggi, sul mercato, si possono trovare centinaia di CMS preconfezionati, molti di questi gratuiti, che necessitano solamente di installazione e consentono in pochi minuti di creare un sito web. Tuttavia questi pacchetti, cercando di andare incontro alle esigenze più comuni del pubblico, hanno uno scarso livello di personalizzazione e, a meno di interventi sul codice sorgente, non consentono all'utente di ottenere sempre la essibilità e la specializzazione desiderata in relazione al proprio specico obiettivo. Questi problemi sono in parte risolubili utilizzando software open source. Avendo accesso ai codici sorgenti si può personalizzare il CMS in base alle proprie esigenze, ma vanno tenuti in considerazione il tempo e i costi necessari per imparare a creare moduli personalizzati per la piattaforma specica e la sua struttura. Spesso, in caso di personalizzazioni estreme, i costi per realizzare tali moduli diventano superiori a quelli della costruzione di un CMS partendo da zero. 8 Il contesto 2.3 Novedge e il suo business model Novedge LLC. è un'azienda di e-commerce statunitense con sede a San Francisco (California) che si occupa della vendita online di software di progettazione e graca, perlopiù nel territorio nordamericano. Fondata nel 2003 da Franco Folini e Cristiano Sacchi è, ad oggi, il più grande rivenditore online al mondo di questo tipo di software. Novedge ha un catalogo di circa ottomila prodotti da centocinquanta produttori dierenti ed utilizza strumenti e modalità con un forte supporto tecnologico in modo da automatizzare e rendere il più eciente possibile il processo di approvvigionamento e vendita. Per questo possiamo catalogare l'azienda sia come B2B che come B2C. La parte B2B è quella che si occupa delle comunicazioni tra l'azienda, le case produttrici di software e le compagnie di trasporti. Ogni fornitore ha regole di business diverse, con metodi di interazione e gestione degli ordini d'acquisto dierenti. Per gestire al meglio questa parte sono stati deniti processi estremamente ecienti e automatizzati che eliminano o riducono al minimo indispensabile l'intervento umano nelle transazioni. Per quanto riguarda la vendita al pubblico (B2C) l'azienda si ada al proprio sito web in cui è possibile consultare il catalogo prodotti ltrandoli per marca o categoria e mostrandoli suddivisi per sottocategorie in modo da consentire all'utente una navigazione tra le pagine intuitiva e capace di indirizzarlo velocemente sul tipo di software cercato, che può essere acquistato direttamente dal sito con pagamento elettronico oppure attraverso ordine telefonico. Novedge riesce a garantire ai suoi clienti (principalmente progettisti meccanici, architetti, artisti 3D e game developer) prezzi scontati rispetto a quelli di listino eettuati da altri rivenditori, fornendo spedizioni veloci e un supporto di base no all'installazione del software. Oltre alla vendita di software Novedge fornisce altri importanti servizi di contorno come: 2.4 L'architettura del sistema • 9 Ask Novedge: un servizio di supporto email che consente all'utente di contattare l'azienda per chiarire i propri dubbi o fare domande riguardo ai prodotti. • Mailing list a cui è possibile registrarsi per ricevere le ultime notizie sui nuovi prodotti o quelli di prossima presentazione. • Materiale di supporto ai prodotti, come: suggerimenti di libri acquistabili da Amazon; video, documenti e gallerie immagini di recensioni, tutorial e case study; download di sofware trial, utility e plugin; suggerimenti di prodotti simili o di complemento. • Webinars gratuiti: dirette video in cui esperti mostrano come utilizzare al meglio i prodotti e le loro caratteristiche più avanzate. • Blog contenente interviste e news del settore. • Forte interazione con i Social Media (Twitter, Facebook, Google+, Pinterest e LinkedIn) in cui l'utente può ricevere gli aggiornamenti sulle oerte e le attività dell'azienda. • Pulse: un sistema di aggregatore di notizie che mostra notizie e aggiornamenti da oltre trecento blog e cinquecento dierenti autori del settore. • Rhino Jungle,WikiCAD e Vectorworking, che sono comunità online gestite da Novedge in cui si può discutere di un determinato argomento e dei prodotti relativi. Il Dr. Franco Folini si occupa del sistema informatico di Novedge ed è la persona con cui sono stato in contatto per tutta la durata del progetto discutendo insieme le diverse problematiche riguardanti la progettazione e l'implementazione del sistema. Laureato in scienze dell'informazione ha lavorato come ricercatore dal 1991 al 2001 presso la facoltà di ingegneria dell'università degli studi di Parma dove ha insegnato disegno CAD per il corso di ingegneria meccanica. 2.4 L'architettura del sistema Il nucleo del sistema informatico su cui si basa l'intera architettura dell'azienda è il Novedge Main Website, un'applicazione web ad hoc scritta in Visual Basic su piattaforma 10 Il contesto Figura 2.1: Architettura del sistema informatico di Novedge ASP classica gestita dal web server Microsoft IIS che si appoggia a una serie di sottosistemi per usufruire di servizi esterni all'azienda con cui ha necessità di comunicare. Sulla stessa macchina su cui opera il web server è installato anche il database Microsoft SQL Server, contenente tutte le informazioni necessarie all'applicazione per svolgere il proprio lavoro. Le tabelle del database non vengono interrogate direttamente dall'applicazione web mediante query SQL ma, come scelta architetturale, i record vengono richiesti attraverso l'invocazione di stored procedures salvate sul database stesso. Questo approccio è dettato dalla necessità di accedere ai dati contenuti nel database da applicazioni diverse (principalmente Main Website e CMS) scritte in linguaggi diversi che si appoggiano a frameworks dierenti. I le di grosse dimensioni, come download di versioni trial dei prodotti, video e documenti, vengono salvati su Amazon S3, un servizio di cloud computing per lo storage di le. In questo modo i download sono sempre disponibili a una velocità di trasferimento alta e non si rallenta il server su cui gira il sito. 2.4 L'architettura del sistema 11 Tra i servizi che Novedge utilizza per gestire il processo di vendita troviamo un sistema di validazione degli ordini che consente, dato l'indirizzo sico dell'utente, il suo indirizzo IP e il metodo di pagamento selezionato, di capire la zona di provenienza e l'adabilità, in modo da attribuire all'ordine un fattore di rischio e decidere successivamente come procedere. Una volta che l'ordine viene accettato (automaticamente dal sistema se l'indice di rischio basso o manualmente nel caso contrario) si passa alla fase di evasione dell'ordine, che può avvenire digitalmente o attraverso i servizi di spedizione tradizionali. Nel secondo caso il sistema contatta la compagnia logistica segnalando la spedizione e facendosi restituire un tracking number con cui sarà possibile tracciare il percorso del pacco. 12 Il contesto CAPITOLO 3 OBIETTIVI DEL PROGETTO DI TESI ED ANALISI 3.1 Analisi dei requisiti L'obiettivo del lavoro di tesi è la progettazione e realizzazione di un nuovo CMS per Novedge che soddis i seguenti requisiti: • sia in grado di gestire le operazioni di consultazione, inserimento, modica e cancellazione dei prodotti a catalogo e di una serie di altre entità ad essi collegate. • avere un'interfaccia graca semplice in modo da renderlo utilizzabile anche a persone con una scarsa conoscenza delle tecnologie informatiche cercando di nascondere la logica, talvolta complessa, delle operazioni. • essere accessibile attraverso Internet in modo da permettere il telelavoro dei dipendenti. Il sistema deve essere aancato al sito web attuale e accessibile al solo personale dell'azienda, adottando quindi protocolli e standard di sicurezza necessari per garantire la riservatezza delle informazioni. 14 Obiettivi del progetto di tesi ed analisi Figura 3.1: Rappresentazione della collocazione del sistema 3.2 Le entità da gestire 3.2.1 Prodotti I prodotti sono le entità principali dell'applicazione a cui tutte le altre fanno riferimento. Il sistema deve consentire l'inserimento e la modica di nuovi prodotti con la possibilità di creare collegamenti tra di loro in modo da poter raggruppare prodotti simili che verranno poi mostrati sul sito web. Le informazioni base che devono essere editabili sono: SKU (Stock-Keeping Unit, ossia un identicativo univoco della categoria di prodotto), nome, versione, breve descrizione, disponibilità, produttore, tipo di prodotto, tipo di licenza, formato (digitale o sico), immagine della scatola. I prezzi sono divisi in tre campi: prezzo del fornitore (costo), prezzo di listino e prezzo Novedge. Ricoprendo un ruolo fondamentale è necessario adottare riscontri visivi per capire immediatamente durante l'inserimento lo sconto eettuato rispetto al prezzo di listino (discount) e quanto è il margine sulla vendita. Oltre a queste informazioni deve essere possibile: • Inserire una descrizione completa in formato HTML che può contenere collegamenti ad altri prodotti, brand, documenti e a pagine Wikipedia. 3.2 Le entità da gestire 15 • Inserire informazioni di supporto sul prodotto. • Inserire collegamenti a versioni di prova (trial) del prodotto con una breve descrizione che ne specica i limiti. • Inserire in una sezione denominata facts le capacità e compatibilità del prodotto. • Associare tag e parole chiave che semplichino la ricerca. • Specicare i formati di input e di output supportati dal software. Come detto in precedenza l'applicazione deve essere in grado di creare collegamenti logici tra i prodotti in modo da creare una sorta di gerarchia che semplichi la ricerca e la navigazione nel sito web da parte del visitatore. Le connessioni che devono essere possibili tra i prodotti sono: • Per i software di tipo plugin specicare i prodotti su cui possono venire installati. • Creare collegamenti a pacchetti dello stesso software ma per sistemi operativi differenti. • Creare prodotti di tipo bundle, ovvero prodotti che in realtà sono raggruppamenti di altri prodotti. • Raggruppare prodotti in categorie. • Raggruppare prodotti in aree. Le aree sono entità composte da prodotti, categorie e download. • Collegamento tra un prodotto e i suoi master, ovvero prodotti da cui esso è strettamente legato. 3.2.2 Brand I brand rappresentano i marchi, ovvero le case produttrici dei software, che vengono associate ai prodotti, documenti e ai download gratuiti. I campi contenuti in questa entità sono: • I campi elementari come nome, descrizione e logo dell'azienda 16 Obiettivi del progetto di tesi ed analisi • Alcuni ag per indicare la visibilità dei prezzi per i prodotti associati; se il brand è visibile dal sito; se Novedge è un rivenditore autorizzato e se la casa produttrice accetta i resi. • Una serie di indirizzi (sia sici che elettronici) per contattare i vari reparti dell'azienda in base alla necessità, ad esempio supporto tecnico e accounting. • Altre informazioni necessarie per lo scambio di informazioni tra Novedge e l'azienda. 3.2.3 Special Gli special vengono utilizzati per creare promozioni ed oerte a cui è possibile associare uno o più prodotti. Ogni promozione è caratterizzata da: • Una data di inizio e ne. • I campi necessari per la composizione del messaggio da mostrare nel prodotto in promozione. Questi sono titolo, label (testo mostrato con caratteri grandi), testo e footer (testo piccolo mostrato ai piedi del messaggio). • Possibilità di attivare e disattivare lo special. • Un'area in cui associare i prodotti allo special. Per ognuno di questi deve essere possibile cambiare i prezzi, cambiare gli SKU (identicativi) che fanno riferimento al pacchetto del produttore e associare un prodotto target ovvero un prodotto a cui il prodotto in promozione fa riferimento. Un vincolo importante da tenere in considerazione è che ogni prodotto può appartenere ad un solo special attivo. Occorrerà quindi implementare sistemi di controllo adeguati che avvisino l'utente quando questo cerca di associare un prodotto già in promozione ad un altro special. Altre funzionalità richieste per gli special sono la possibilità di vedere un'anteprima di come apparirà il messaggio che verrà mostrato nella pagina del prodotto in promozione e una pagina contenente un calendario con il riassunto delle scadenze delle promozioni attualmente attive. 3.2.4 Book I book sono entità che permettono di associare un libro a una o più categorie di prodotti. Ogni libro è composto da un identicativo, l'anno di pubblicazione, il titolo e l'autore. 3.2 Le entità da gestire 17 Il sistema deve implementare un modulo per raccogliere le informazioni sui libri dal catalogo on-line di Amazon, in modo dal sollevare l'utente dal compito di inserire i dati manualmente. 3.2.5 Categorie Le categorie consentono di raggruppare i prodotti e sono composte da due campi testuali: nome e descrizione. Oltre a questi sono necessari alcuni ag per poter attivare o disattivare la categoria e specicare se questa è una categoria ad alta priorità e se deve essere mostrata nei menù del sito web. 3.2.6 Documenti I documenti sono entità che consentono di associare pdf, video o altri le a un prodotto o a un brand. Ognuno di questi oggetti contiene: • I campi per settare il titolo, l'URL, la descrizione ed eventualmente la data e l'autore del documento. • Una regione per specicare il tipo di documento e con che icona deve essere visualizzato sul sito web. • La possibilità di disattivare il documento • Le associazioni a un brand e a uno o più prodotti. Nel campo URL si può specicare l'indirizzo di un le o di una pagina già presente sul web, tuttavia deve essere possibile, attraverso un sistema integrato, scegliere un le locale dal computer per farne l'upload su Amazon S3. In questo caso il sistema dovrà preoccuparsi di inserire negli appositi campi l'URL e la dimensione del le appena caricato. 3.2.7 Aree Le aree sono raggruppamenti di uno o più prodotti, categorie e download gratuiti. Oltre alle sezioni per poter associare queste entità le aree dovranno specicare un nome, una breve descrizione, l'URL relativo sul sito Novedge, un logo e opzionalmente il prodotto principale. Anche questo tipo di entità dev'essere disattivabile. 18 Obiettivi del progetto di tesi ed analisi 3.2.8 Clusters I cluster sono un altro tipo di raggruppamento di prodotti. Questi hanno il solo campo nome e vengono utilizzati dal sito web per mostrare i prodotti associati all'interno di menù a tendina in contesti specici. Il sistema deve prevedere per i prodotti contenuti in un cluster la possibilità di cambiare ad essi il nome (di solito per sintetizzarlo), di inserire un separatore tra un prodotto e l'altro e un metodo per cambiarne velocemente l'ordine. 3.2.9 Ordini Le entità degli ordini contenute nel database vengono generate automaticamente quando il visitatore del sito web aggiunge dei prodotti al proprio carrello virtuale e conferma l'acquisto della merce pagando con uno dei metodi disponibili. Il CMS opera solamente su ordini già esistenti e deve permettere agli operatori di: • Modicare le informazioni degli indirizzi di spedizione e fatturazione. • Modicare i dati dei prodotti che compongono l'ordine (come prezzo e quantità). • Inserire o cancellare prodotti. • Esplodere i bundle, ovvero sostituire il prodotto nell'ordine con i prodotti contenuti nel bundle. Questa operazione dev'essere eettuata non modicando l'importo totale. • Modicare i dati dell'intero ordine come totale, tasse e costi di spedizione. 3.2.10 Free Download I free download rappresentano software scaricabile direttamente dal sito. Queste entità hanno le stesse funzionalità dei documenti ma vengono associate solamente ai brand e alle aree, quindi non direttamente ai prodotti. Le dierenze con i documenti riguardano: • I free download non devono specicare un'icona o un tipo di documento in quanto la maggior parte delle volte sono le eseguibili. • I free download contengono tre campi booleani che deniscono se il software funziona su Windows, su Linux e su Mac. 3.2 Le entità da gestire 19 3.2.11 Webinar Le entità webinar consentono di gestire i collegamenti ai webinar realizzati da Novedge. Le informazioni da specicare sono: • L'identicativo del video su Vimeo (la piattaforma, simile alla più nota YouTube, dove sono salvati i video). • La data del webinar. • Il prodotto trattato nel webinar. • Titolo, descrizione e a chi si rivolge il webinar. • Informazioni sulla persona che tiene il webinar ovvero nome, sito web, immagine e biograa. • Informazioni su eventuali oerte collegate e possibilità di specicare un prodotto. • Durata del video. Per tutte le entità sopra descritte occorre implementare un sistema per la navigazione e la ricerca veloce degli oggetti già presenti nel database. Alcune di queste entità (quelle che modicano dati importanti come i prezzi) dovranno contenere le funzionalità di wall e log. Il wall è una sorta di bacheca che consente all'operatore di inserire dei commenti o dei memo per motivare l'operazione eseguita o ricordare qualcosa che andrà fatto in futuro. Il log invece è un diario che tiene traccia di tutte le modiche eettuate a un'entità. Il CMS oltre ad orire le funzionalità sopra descritte dovrà contenere una sezione Reports, accessibile all'amministratore, che permetta di interrogare il database su determinate regole (ad esempio il prezzo di un prodotto deve avere un valore compreso tra il costo e il prezzo di listino del fornitore) in modo da avere un riscontro sulla conformità dei dati e poter procedere alla correzione di eventuali incongruenze. 20 Obiettivi del progetto di tesi ed analisi 3.3 Elenco degli attori e use case Gli attori, secondo la terminologia di UML (Unied Modeling Language), sono le categorie di entità esterne, tipicamente persone, che dovranno interagire con il sistema. Per il progetto attuale abbiamo tre attori in quanto, essendo un'area riservata del sito, i visitatori non hanno accesso a questa parte. Verranno illustrati anche gli Use Case Diagram di UML, che consentono di associare a un attore le operazioni che esso può eseguire. • Products Operator: sono gli impiegati che hanno accesso all'applicazione e possono modicare i dati relativi ai prodotti e alle altre entità ad essi associate. E' il tipo di attore con meno permessi per il sistema, mentre gli altri due hanno autorizzazioni maggiori. Figura 3.2: Products Operator use case diagram • Orders Operator: questa categoria di operatori, oltre ad avere gli stessi permessi dei products operator, ha accesso alla modica degli ordini dei clienti. 3.3 Elenco degli attori e use case 21 Figura 3.3: Orders Operator use case diagram • Amministratore: è colui che gestisce il sistema e deve avere accesso ad ogni parte dell'applicazione compresa la possibilità di monitoring, ovvero vedere quali utenti sono loggati e cosa stanno facendo. E' inoltre l'unico a poter accedere all'area di report che permette di eseguire operazioni delicate sul database. Figura 3.4: Administrator use case diagram Tutti gli attori che utilizzano il portale non necessitano di competenze particolari nel settore web o informatico in generale in quanto uno degli obbiettivi è la semplicità del sistema. Tuttavia il ruolo di amministratore è limitato a un numero ristretto di persone. 22 Obiettivi del progetto di tesi ed analisi 3.4 Coordinamento del progetto Durante le fasi di analisi, progettazione e realizzazione dell'applicazione CMS si è utilizzata una metodologia agile di sviluppo in modo di coinvolgere il più possibile il committente ed avere quindi un feedback continuo riguardo allo stato del progetto e alle sue richieste. Per far ciò è stato fondamentale l'utilizzo di strumenti di comunicazione e coordinamento in quanto, data la distanza dagli uci Novedge, è stato impossibile un contatto diretto per tutta la durata del progetto. Oltre all'email, strumento indispensabile per la co- municazione testuale, si è fatto ampio uso del software Skype che consente di eettuare videochiamate a livello globale completamente gratuite orendo funzionalità, come la condivisione dello schermo, che si sono dimostrate irrinunciabili per illustrare le caratteristiche e le problematiche che emergevano dal progetto. Un altro strumento utilizzato ampiamente per il coordinamento del progetto è stato BitBucket, un'applicazione web che fornisce strumenti di supporto agli sviluppatori per il lavoro congiunto su progetti software. In particolare BitBucket consente di salvare online il codice sorgente del progetto permettendo agli sviluppatori di accedervi mediante strumenti di controllo di revisione come Mercurial e Git e, grazie a un sistema di issues tracking, segnalare eventuali malfunzionamenti del codice o richiedere l'implementazione di nuove caratteristiche. CAPITOLO 4 PROGETTAZIONE La fase di progettazione si occupa di denire come il sistema dovrà rendere possibili le operazioni discusse nel processo di analisi. Per questo durante la progettazione bisogna tenere in considerazione i fattori, le potenzialità e i limiti relativi alle tecnologie che verranno adoperate per la realizzazione. L'obbiettivo di questo processo è quindi ottenere una descrizione accurata di tutte le parti del sistema, dall'architettura software e del database no all'interfaccia graca con cui l'utente dovrà interagire. Ciò che contraddistingue il progetto rispetto ad altri CMS che si possono trovare sul mercato è la possibilità di dare ai prodotti e alle entità collegate a loro una gerarchia in modo da poter creare collegamenti tra di essi nalizzati a rendere l'esperienza di navigazione del visitatore più immediata proponendo suggerimenti coerenti con ciò che l'utente sta cercando. Altri siti web creano collegamenti tra i loro prodotti in base a logiche che non sempre hanno il risultato desiderato. Ad esempio, selezionato un prodotto, viene suggerito un prodotto con un nome simile o, in base ad acquisti di utenti precedenti, viene fornita una lista di ciò che hanno acquistato gli utenti interessati al prodotto. Questa scelta di progettazione è fondamentale per la tipologia di prodotti trattati e richiede a chi si occupa dei contenuti un lavoro maggiore rispetto all'utilizzo di algoritmi automatizzati ma il risultato che ne deriva è uno dei fattori che rendono Novedge leader nel settore. 24 Progettazione 4.1 La situazione prima del progetto Prima della realizzazione del progetto i dati relativi ai contenuti del sito web venivano inseriti o modicati attraverso l'utilizzo di form create in Microsoft Access oppure, nel caso delle entità più semplici, editando direttamente le tabelle del database. Questi strumenti consentono di eettuare le stesse operazioni ed ottenere gli stessi risultati che si avrebbero utilizzando un CMS ma in un modo molto più laborioso e senza controlli di validazione che potrebbero portare l'operatore a commettere errori nell'inserimento dei dati. L'unico punto a favore di questo approccio è l'abbattimento dei costi derivanti dal dover sviluppare un'applicazione CMS ad hoc. Con la crescita della mole di informazioni presenti nella base di dati e della loro complessità si è arrivati ad un punto in cui si è reso necessario l'utilizzo di strumenti più avanzati. Per avere un'idea del volume di dati che il sito web e il CMS devono gestire basti pensare che attualmente il database contiene oltre ottomila SKU, trecentomila utenti registrati, tremila recensioni di prodotti, quattromila documenti, cinquecento download gratuiti, cento special, settanta webinar ed altre entità tutte interconnesse tra di loro. 4.2 Speciche software Data la natura, orientata al web, del progetto, si è deciso di implementarlo come applicazione web. La scelta del linguaggio di programmazione lato server e delle tecnologie con le quali è stato implementato il CMS sono state dettate in parte dall'ambiente in cui è stato installato l'applicativo, ovvero lo stesso del sito internet di Novedge. Sul server in questione, acquistato da un hosting provider esterno all'azienda, è installato il sistema operativo Microsoft Windows, con un web server IIS e un database SQL Server. Si è quindi fatta un'analisi delle funzionalità supportate dal server di hosting e si è scelta la tecnologia più recente e completa supportata dal sistema, ovvero ASP.NET 4.0 Web Forms. 4.3 Struttura del progetto 25 4.3 Struttura del progetto Data la complessità del progetto è stato necessario suddividerlo in più parti in modo da separare i concetti che stanno alla base delle classi che lo compongono e renderlo quindi manutenibile. Le due componenti principali in cui è stato ripartito l'applicativo sono Novedge.Base e Novedge.CMS. Il namespace Base contiene quelle classi adibite all'interfacciamento col database e modellano le entità rendendole accessibili agli strati di software superiori, sviluppate internamente a Novedge. Nel CMS invece sono stati collocati tutti i le relativi alle singole applicazioni che compongono il progetto, ognuna delle quali risiede in una sottocartella separata dalle altre. Figura 4.1: Struttura del progetto Novedge.CMS Oltre a queste la cartella radice del progetto CMS contiene i seguenti elementi: • Il le index.htm che rappresenta la pagina iniziale dell'applicazione. • I le di congurazione Web.cong e Global.asax presenti in tutte le applicazioni ASP.NET. • I le relativi alla barra di navigazione denominati Toolbar. • I web service, con presso Ajax, che vengono chiamati da javascript lato client attraverso la tecnologia AJAX. 26 Progettazione • La cartella CommonCode contenente Validator.cs che è la classe base di tutte le classi di validazioni. • La cartella CustomControls dove sono stati implementati controlli personalizzati utilizzati in tutto il progetto. • La cartella js contenente gli script javascript utilizzati lato client dalle applicazioni. • La cartella css con gli stili delle pagine. Tipicamente le cartelle delle applicazioni sono composte da almeno tre le principali: • Un le aspx con il nome dell'applicazione contenente il codice della form che consente di editare l'entità e di salvarle nella base di dati. • Un le aspx denominato List che permette all'utente di consultare la lista degli elementi presenti nel database. • Una classe Validator che denisce i metodi necessari per controllare che i dati inseriti dall'utente siano validi. Se tutti hanno esito positivo allora l'entità può essere inserita o aggiornata nel database. 4.4 Struttura delle singole applicazioni Nella tecnologia ASP.NET ogni le aspx rappresenta una pagina web dinamica e viene separata in due parti: una contenente il codice HTML che denisce la struttura e i contenuti visibili della pagina e una classe denominata code behind dove risiede la logica dell'applicazione. In questo modo vengono separati i due concetti e il risultato nale risulta molto più comprensibile e manutenibile. Il CMS è composto da diverse pagine aspx, ognuna delle quali rappresenta un'applicazione web relativa alla gestione di una singola entità o una funzionalità associata ad essa. Oltre a contenere il codice HTML necessario per mostrare all'utente i contenuti e i controlli della form le pagine sono classi derivate da System.Web.UI.Page che mantengono tutte la stessa struttura di base e contengono: 4.5 Le interfacce utente • 27 Attributi relativi all'oggetto che rappresentano lo stato della pagina o contengono riferimenti ad istanze di oggetti utilizzati (come ad esempio i validator). • Gli eventi legati alla pagina sono metodi speciali che vengono richiamati dal framework durante i vari stadi del ciclo di vita della pagina. Tra i più utilizzati troviamo Page_PreInit in cui vengono istanziati gli oggetti e i controlli necessari all'applicazione, Page_Load richiamato durante il caricamento della pagina e Page_PreRender utilizzato per impostare gli attributi e gli stili dei controlli prima che la pagina venga renderizzata. • Le proprietà sono una caratteristica di C# (in altri linguaggi, come Java, si utilizzerebbero i metodi get e set) e vengono utilizzate per impostare dall'esterno di una classe valori che possono corrispondere ad attributi privati oppure nascondere una logica più complessa al loro interno. • Gli eventi dei controlli sono metodi che rispondono a eventi scatenati dai controlli della pagina web (come bottoni o check box) con cui l'utente interagisce. • I metodi di validazione sono associati ai controlli della form e vengono invocati automaticamente dal sistema per controllare che i dati inseriti siano conformi al tipo di informazione richiesta. • Altri metodi, ovvero funzioni che non ricadono nelle precedenti categorie e vengono utilizzate dal programma per spezzare il usso di esecuzione rendendo i frammenti di codice riutilizzabili e più comprensibili. 4.5 Le interfacce utente L'interfaccia utente è quello strato del software che gli utenti utilizzano per interagire col sistema. Per questo il CMS, nonostante sia stato suddiviso in diverse sottoapplicazioni web, mantiene un'interfaccia graca simile e coerente per ognuna di queste. Queste applicazioni permettono, per ogni entità, di svolgere le classiche operazioni CRUD (Create, Read, Update and Delete) che si eettuano solitamente su una base di dati, oltre ad orire il controllo e validazione delle informazioni inserite nella form, automatizzando e semplicando il più possibile il lavoro dell'utente nale. Nella tecnologia ASP.NET l'interfaccia graca viene creata mediante l'utilizzo delle pagine aspx contenenti il codice HTML che 28 Progettazione verrà mostrato nel browser oltre a supportare funzioni JavaScript per le operazioni lato client e i fogli di stile CSS. Figura 4.2: Disposizione degli elementi nell'interfaccia utente Nella parte superiore della pagina è sempre presente la barra di navigazione che consente all'utente di passare da un'applicazione all'altra ed eettuare il login/logout nel CMS. A sua volta la struttura delle pagine delle applicazioni può essere suddivisa in tre parti. Quella superiore mostra il titolo o il nome dell'entità che si sta editando, l'identicativo e, quando necessario, le tab in cui questa è stata suddivisa. In basso sono presenti i bottoni che consentono di salvare, cancellare o creare un nuovo oggetto. In alcuni casi possiamo trovare anche il tasto per accedere alla lista di tutti gli elementi o un menù a tendina per la scelta veloce. Nel centro della pagina sono invece situati i controlli necessari per la modica dell'entità caricata. 4.6 La base di dati La base di dati con cui il progetto interagisce è la stessa su cui si appoggia il sito web, quindi non è stato necessario progettarla da zero ma sono state apportate solo modiche superciali alle tabelle e aggiunte le stored procedure necessarie. Il database contiene le tabelle con i record relativi alle entità gestite dal CMS e i relativi collegamenti. Questi dati vengono gestiti dallo strato software addetto all'accesso ai dati mediante chiamate a stored procedure, in questo modo la libreria Novedge.Base non contiene direttamente 4.6 La base di dati 29 codice SQL e le query sono centralizzate nel database. Per ogni entità presente abbiamo quattro stored procedure: • La sp_GetEntity ritorna tutti i campi di un'entità in base all'identicativo. • sp_GetEntities serve per avere la lista di tutte i record presenti nella tabella di un'entità. • La stored procedure sp_CreateOrUpdateEntity ha come parametri i campi dell'entità. Quando viene invocata controlla se nel database è già presente un oggetto con l'ID specicato, se questo esiste aggiorna il record, in caso contrario ne aggiunge uno nuovo. • sp_DeleteEntity cancella (se esiste) il record con l'identicativo passato come parametro. Figura 4.3: Diagramma ER della base di dati 30 Progettazione Il diagramma ER mostra le relazioni e le cardinalità tra le tabelle gestite dal CMS, da questa rappresentazione si può notare come i prodotti abbiano un ruolo centrale nella base di dati e come tutte le altre entità siano collegate ad essi direttamente o indirettamente. Per chiarezza sono state omesse le tabelle che vengono utilizzate solamente dal Novedge Web Site e quelle dei log e commenti in quanto possono contenere dati relativi a tutte le altre entità. 4.7 I web service Per rendere le pagine web ancora più dinamiche si è scelto di implementare anche alcuni web service interni all'applicazione in modo da consentire al codice lato client eseguito dal browser di accedere a informazioni presenti nel database. Questo scambio di dati avviene attraverso la tecnologia AJAX utilizzando il formato JSON, molto più leggero rispetto a XML e ugualmente supportato. Una volta ricevuta la risposta il codice JavaScript si occupa di modicare il DOM della pagina senza dover eettuare una nuova richiesta HTTP che richiederebbe il refresh della pagina. Figura 4.4: Schema di funzionamento di un web service 4.8 Le tecnologie utilizzate 31 4.8 Le tecnologie utilizzate 4.8.1 HTML, CSS e JavaScript Queste tre sono le tecnologie fondamentali che stanno alla base di tutte le web application moderne. HTML (Hyper Text Markup Language) è un linugaggio di formattazione utilizzato per creare la struttura di una pagina web e inserirne i contenuti. La formattazione consiste nell'inserire nel testo una serie di marcatori (tag) che deniscono come questo deve essere visualizzato e disposto. Ogni documento di questo tipo inizia con un tag, detto document type, che segnala al browser che versione di HTML è stata usata nella pagina. Dopo di questo, il documento HTML presenta una struttura ad albero annidato composta da sezioni delimitate da tag opportuni che al loro interno contengono a loro volta sottosezioni sempre delimitate da tag. La struttura più esterna delimita l'interno documento ed è compresa tra i tag <html> e </html>. All'intergno dei tag <html> lo standard prevede la denizione di due sezioni ben distinte e disposte in sequenza ordinata: • l'intestazione (header), delimitata dai tag <head> e </head>, contiene informazioni di controllo come titolo, metatag e collegamenti a script e fogli di stile. Queste informazioni solitamente non appaiono nella pagina. • Il corpo (body), compreso tra i tag <body> e </body>, contiene i contenuti veri e propri, ossia il testo, le immagini e i collegamenti che costituiscono la parte visualizzata dal browser. L'ultima versione disponibile è HTML5 che ore funzionalità più avanzate rispetto alle versioni precedenti ma è ancora in una fase di sviluppo e non ancora supportata da tutti i browser, quindi si è optato per l'utilizzo di HTML4. CSS (Cascading Style Sheets) è un linguaggio usato per denire la formattazione e lo stile di una pagina HTML. Questa tecnologia è stata introdotta per separare i contenuti di una pagina (descritti nell'HTML) dalla formattazione; in questo modo strutturando correttamente un documento HTML è possibile cambiarne lo stile modicando semplicemente alcune proprietà nel le CSS associato. Inne JavaScript è un linguaggio di programmazione orientato agli oggetti. A dierenza di altri linguaggi di programmazione, che permettono la scrittura di programmi stand- 32 Progettazione alone, JavaScript viene utilizzato soprattutto come linguaggio di scripting, ovvero viene integrato con altri software per programmarne alcuni aspetti. Nel caso delle web application un'interprete JavaScript viene implementato come programma ospite dai browser che si occupano di riconoscere il codice contenuto in una pagina HTML e lo eseguono. L'interfaccia che JavaScript utilizza per interagire con la struttura del documento visualizzato nel browser (lato client) è chiamata DOM (Document Object Model). Questo permette di creare applicazioni web dinamiche, modicando la struttura del documento senza richiedere al server di riprocessare la pagina per inviarne al browser una versione modicata. 4.8.2 ASP.NET ASP.NET 4.0 è un insieme di tecnologie lato server basate sul framework .NET di Microsoft per lo sviluppo di applicazioni web e web services. ASP.NET Web Forms è la tecnologia maggiormente usata nel progetto e consente allo sviluppatore di creare pagine web dinamiche utilizzando il paradigma dell'interfaccia graca (GUI) abbinato alla cosiddetta programmazione ad eventi, ovvero utilizza un approccio molto simile allo sviluppo di applicazioni per il desktop. Ogni pagina web creata consiste di due le: uno con estensione .aspx contenente il markup della pagina e uno con estensione che dipende dal linguaggio di programmazione utilizzato (.aspx.cs nel caso del progetto corrente in quanto sviluppato in C#), chiamato code behind, che contiene la logica della pagina e il codice legato agli eventi. Questa divisione consente allo sviluppatore di separare la view, ovvero la parte che si occupa di mostrare e formattare i dati, dal model e controller che deniscono rispettivamente la strutturazione dei dati e la logica che consente di modicarne lo stato. Il framework .NET denisce il ciclo di vita della pagina, ovvero una serie di operazioni che il web server esegue per generare la pagina richiesta, partendo dalla creazione dei controlli e arrivando no alla renderizzazione completa della pagina. Questo modello denisce degli eventi intermedi in cui l'utente può inserire il proprio codice da eseguire. 4.8.3 jQuery jQuery è una libreria javascript cross-browser, che fornisce metodi e funzioni per gestire gli aspetti graci e strutturali di una pagina web. Il punto di forza di jQuery, rispetto ad altre 4.8 Le tecnologie utilizzate 33 librerie concorrenti, è l'estrema compattezza dei comandi che consente, con poche righe di codice, di eettuare svariate operazioni sul DOM e aggiungere alla pagina eetti graci. Inoltre, essendo un libreria facilmente estendibile, si possono trovare online numerosi plugin che ne estendono le funzionalità. Una delle estensioni più famose (e utilizzata all'interno del progetto) è jQuery UI che comprende un'insieme di componenti graci personalizzabili con supporto ad interazioni, animazioni ed eetti avanzati. Nel progetto sono stati utilizzati ampiamente il controllo autocompleter per mostrare le scelte possibili in base al testo inserito e il calendar ossia un controllo che visualizza un piccolo calendario associato a quelle textbox che richiedono l'immisione di una data. 4.8.4 AJAX AJAX, acronimo di Asynchronous JavaScript and XML, è una tecnologia che consente al codice client side di una pagina web di richiamare servizi web server side. In questo modo le due parti possono scambiarsi informazioni senza la necessità di fare il postback dell'intera pagina. Questa tecnologia permette la creazione di applicazioni web forte- mente interattive (Rich Internet Applications) che forniscono all'utente la possibilità di interagire con l'applicazione come se si stesse usando un'interfaccia desktop. 4.8.5 JSON JSON (JavaScript Object Notation) è un formato adatto allo scambio di dati in applicazioni client-server. La sua semplicità e leggerezza rispetto a XML ne hanno decretato una rapida ascesa, specialmente nella programmazione AJAX. Il suo utilizzo tramite JavaScript è particolarmente semplice, infatti l'interprete è in grado di eseguirne il parsing attraverso la funzione eval(). 4.8.6 Amazon Web Services Gli Amazon Web Services (AWS) sono un insieme di servizi oerti da Amazon accessibili dal web attraverso un'interfaccia REST (Representational State Transfer), ovvero richiamando le risorse web mediante un URL e ricevendo come risposta un documento in formato HTML, XML o JSON contenente le informazioni richieste. Per l'accesso ai servizi sono anche disponibili librerie SDK speciche per ogni linguaggio di programmazione che facilitano lo scambio di dati svincolando l'utente dal dover comporre manualmente 34 Progettazione l'URL necessario per la richiesta e semplicando l'accesso ai dati ricevuti, che vengono organizzati in oggetti del linguaggio ospite. Nel progetto si è fatto uso di due dei nu- meosi servizi oerti: il primo è Product Advertising API che consente di interrogare il catalogo prodotti (per lo più libri) di Amazon e fare ricerche in base a determinati parametri. Il secondo servizio utilizzato è Amazon S3 (Simple Storage Service) che permette il salvataggio online di le per poi renderli accessibili al pubblico. 4.9 Gli strumenti utilizzati Per la realizzazione del progetto è stato fondamentale l'utilizzo di strumenti software adeguati. Microsoft Visual Studio 2010 è un ambiente di sviluppo integrato (IDE) che ore un supporto completo allo sviluppo di applicazioni che hanno alla base il framework .NET. Questo strumento comprende alcune funzionalità che facilitano lo sviluppatore rendendo tutto a portata di mano. Tra le caratteristiche degne di nota ci sono: • Integrazione con il compilatore • Editor di testo avanzato con IntelliSense che ore il competamento automatico dei nomi degli oggetti in base al contesto. • Modalità debug integrata con possibilità di fermarsi ai breakpoint in base a condizioni denite dall'utente e di controllare il valore corrente delle variabili. • Il proler consente di ottenere statistiche sull'utilizzo di CPU e di memori, conoscere le funzioni più chiamate e quelle in cui il usso di esecuzione passa la maggior parte del tempo. Microsoft SQL Server Management Studio consente di congurare e gestire tutti i componenti relativi a una base di dati SQL Server utilizzando editor graci e testuali. La principale caratteristica di questo strumento è l'object explorer che consente all'utente di accedere ai record relativi alle tabelle ed esequire query su di essi. Per il controllo di versione e l'accesso al codice sorgente è stato utilizzato TortoiseHg. Questa applicazione fornisce un'interfaccia graca a Mercurial che, a dierenza di software più datati come CVS e SVN, consente di lavorare creandosi un repository locale su cui apportare le modiche che verranno poi inviate al server principale per essere unite a 4.9 Gli strumenti utilizzati 35 quelle degli altri sviluppatori. Inne, trattandosi dello sviluppo di un'applicazione web, sono stati utilizzati per controllare che tutto funzionasse i principali browser disponibili sul mercato tra i quali Google Chrome, Mozilla Firefox, Internet Explorer e Opera. 36 Progettazione CAPITOLO 5 IMPLEMENTAZIONE 5.1 La libreria Novedge Base Alla base di tutte le web application che formano il CMS c'è la libreria Novedge.Base che funge da DAL (Data Access Layer) ovvero lo strato software che si interpone tra le applicazioni e il database. Le classi che compongono questa libreria deniscono il modello dei dati fornendo alle applicazioni che la utilizzano un'interfaccia per accedervi e, in alcuni casi, dei meccanismi di cache in modo da mantenere in memoria gli oggetti più utilizzati per i quali sarebbe costoso un accesso frequente al database. Novedge.Base non utilizza frameworks di terze parti per l'accesso ai dati, come ad esempio potrebbero essere Nhibernate o l'Entity Framework di Microsoft, ma vengono richiamate stored procedures memorizzate all'interno del database attraverso l'uso della libreria System.Data del framework .NET. Il pattern tipico per la maggior parte delle entità presenti nella libreria Base si suddivide in tre classi: Entity.cs, EntityList.cs e EntityDictionary.cs. Vediamo il class diagram delle classi in Base per la gestione dell'entità categoria: 38 Implementazione Figura 5.1: Class Diagram delle classi in Novedge.Base utilizzate per le categorie Entity.cs è la classe base per ogni tipo di entità e denisce al suo interno: • Le proprietà in sola lettura per ogni campo della tabella. • Un costruttore statico che inserisce in un dizionario FieldLoaders le funzioni necessarie a mappare i campi del database nelle proprietà della classe. • Un costruttore privato che setta i valori di default dei campi. • Un costruttore publico che consente di creare un nuovo oggetto passandogli i valori dei campi. • Un costruttore publico che prende come input un record del database (DbDataReader) e, attraverso le funzioni contenute in FieldLoaders inserisce i valori nell'istanza corrente della classe. • Un metodo CopyFrom per ottenere la copia di un oggetto. 5.1 La libreria Novedge Base • 39 I metodi Save e Delete necessari per l'inserimento, aggiornamento e cancellazione di un elemento. • Il metodo ToLog, implementato dall'interfaccia ILoggable, ritorna l'oggetto corrente sottoforma di stringa e viene utilizzato nei log. namespace Novedge.Base { public class Category : ILoggable { private delegate void FieldLoader(Category p_EuCategory, SqlDataReader p_Reader, int p_Position); public static class FieldsMap { public const string ID = "uid"; public const string Name = "cname"; public const string Description = "cdescription"; public const string IsVertical = "cvertical"; public const string IsOnline = "cavailable"; public const string ShowInMenus = "cshowinmenu"; } public int ID { get; private set; } public string Name { get; protected set; } public string Description { get; protected set; } public bool IsOnline { get; protected set; } public bool ShowInMenus { get; protected set; } public bool IsVertical { get; protected set; } // Dictionary (field-name,field-loader) private static Dictionary<string, FieldLoader> FieldLoaders { get; set; } public static Category Empty { get; private set; } private string ModificationsCollector { get; set; } static Category() { Empty = new Category(); // Populate the FieldLoaders Dictionary FieldLoaders = new Dictionary<string, FieldLoader>(); 40 Implementazione FieldLoaders[FieldsMap.ID] = (p_EuCategory, p_Reader, i) => p_EuCategory.ID = p_Reader.GetInt32(i); // Other fields... } private Category() { ID = IdUndefined; Name = string.Empty; Description = string.Empty; IsOnline = false; ShowInMenus = false; IsVertical = false; ModificationsCollector = string.Empty; } public Category(string p_Name, string p_Description, bool p_IsOnline, bool p_ShowInMenus, bool p_IsVertical) { ID = IdUndefined; Name = p_Name; Description = p_Description; IsOnline = p_IsOnline; ShowInMenus = p_ShowInMenus; IsVertical = p_IsVertical; ModificationsCollector = string.Empty; } // Build an End User category object out of a sql reader public Category(SqlDataReader p_Reader) :this() { for (int i = 0; i < p_Reader.FieldCount; i++) { if (p_Reader.IsDBNull(i)) continue; FieldLoader loader; if (FieldLoaders.TryGetValue(p_Reader.GetName(i).ToLower(), out loader)) loader.Invoke(this, p_Reader, i); else Debug.WriteLine("Error: key not found in loading a field into a 5.1 La libreria Novedge Base 41 data-member from a query."); } ModificationsCollector = string.Empty; } public bool Save(){ bool success; var isNew = (ID == IdUndefined || CategoriesDictionary.Dictionary[ID] == null); using (var cmd = new DbCommand()) { try { cmd.Connection.Open(); cmd.AddParameter("Name", SqlDbType.Char).Value = Name; cmd.AddParameter("Description", SqlDbType.Char).Value = Description; cmd.AddParameter("IsVertical", SqlDbType.Bit).Value = IsVertical; cmd.AddParameter("ShowInMenus", SqlDbType.Bit).Value = ShowInMenus; cmd.AddParameter("IsOnline", SqlDbType.Bit).Value = IsOnline; if (isNew) using (var reader = cmd.ExecuteSp("sp_CreateCategory")) { reader.Read(); ID = DbCommand.GetInt(reader, FieldsMap.ID, IdUndefined); reader.Close(); } else { cmd.AddParameter("UID", SqlDbType.Int).Value = ID; cmd.ExecuteNoQuery("sp_UpdateCategory"); } success = true; } catch { success = false; } finally { cmd.Connection.Close(); } } 42 Implementazione if (!success) return false; CategoriesDictionary.Dictionary.AddOrUpdate(this); if (isNew) Log.Creation(LogObject.Category, ID, ToLog()); else Log.Modification(LogObject.Category, ID, ModificationsCollector); ModificationsCollector = string.Empty; return true; } public int CopyFrom( Category p_Category) { var collector = string.Empty; Log.Changes(ref collector, "Name", Name, p_Category.Name); Name = p_Category.Name; // Other fields... ModificationsCollector += collector; return ID; } // Delete the category in the database. public bool Delete() { bool success; using (var cmd = new DbCommand()) { try { cmd.Connection.Open(); cmd.AddParameter("UID", SqlDbType.Decimal).Value = ID; cmd.ExecuteNoQuery("sp_DeleteCategory"); success = true; } catch { 5.1 La libreria Novedge Base 43 success = false; } finally { cmd.Connection.Close(); } } if (!success) return false; Log.Deletion(LogObject.Category, ID, ToLog()); CategoriesDictionary.Dictionary.Remove(ID); return true; } public string ToLog() { return "(" + ID + ": '" + Name + "')"; } } } EntityList.cs rappresenta una lista di entità di un certo tipo, implementa l'interfaccia IEnumerable<Entity> e aggiunge ai classici metodi per l'accesso alla struttura dati funzionalità speciche l'entità in questione. namespace Novedge.Base { public class CategoriesList : IEnumerable<Category>, ILoggable { private readonly List<Category> Categories; // Build an empty list of categories public CategoriesList() { Categories = new List<Category>(); } // Build a list of categories from a SQL reader public CategoriesList(SqlDataReader p_Reader) :this() { if (p_Reader == null || !p_Reader.HasRows) 44 Implementazione return; while (p_Reader.Read()) { var id = DbCommand.GetInt(p_Reader, Category.FieldsMap.ID, Catego-ry.IdUndefined); if (id == Category.IdUndefined) continue; var category = CategoriesDictionary.Dictionary[id]; if (category != null && !Categories.Contains(category)) Categories.Add(category); } } public CategoriesList( IEnumerable<string> p_IDs ) { Categories = CategoriesDictionary.Dictionary.Values .SelectMany( category => p_IDs, (category, idstr) => new {category, idstr} ) .Where( pair => { int i; return int.TryParse(pair.idstr, out i) && pair.category.ID == i;} ) .Select( pair => pair.category ) .ToList(); } IEnumerator<Category> IEnumerable<Category>.GetEnumerator() { return Categories.GetEnumerator(); } public IEnumerator GetEnumerator() { return Categories.GetEnumerator(); } public bool Contains( Category p_Category ) { return Categories.Contains(p_Category); } public bool Contains( int p_CategoryID ) { return this[p_CategoryID] != null; } 5.1 La libreria Novedge Base 45 public CategoriesList GetCopy() { return new CategoriesList(Categories.Select(cat => cat.ID.ToString())); } public CategoriesList Remove(int p_ID) { if (Contains(p_ID)) Categories.Remove(this[p_ID]); return this; } public CategoriesList RemoveAll() { foreach(var category in Categories) Categories.Remove(category); return this; } public CategoriesList Add(Category p_Category) { if (!Categories.Contains(p_Category)) Categories.Add(p_Category); return this; } private Category this [int p_ID] { get { return Categories.SingleOrDefault( category => category.ID == p_ID); } } public string CSV { get { var ids = Categories.OrderBy(category => category.ID).Select(category => cate-gory.ID.ToString()).Distinct().ToArray(); return string.Join(",", ids); } } public string ToLog() { return "(" + CSV + ")"; } 46 Implementazione public int Length { get { return Categories.Count; } } } } Per quelle entità che necessitano del meccanismo di cache viene implementata anche la classe EntityDictionary.cs. Questa struttura utilizza il pattern singleton in modo tale che ne venga creata soltanto un'istanza e si occupa di memorizzare tutti gli elementi della tabella di un'entità in un dizionario che ha come chiave l'identicativo dell'oggetto e come valore l'oggetto stesso. Questo approccio evita l'accesso frequente al database ma viene utilizzato solo per quegli oggetti di utilizzo frequente. namespace Novedge.Base { // This is a Singleton! It includes all Categories public sealed class CategoriesDictionary : IEnumerable { public static CategoriesDictionary Dictionary { get; private set; } private readonly ConcurrentDictionary<int, Category> Categories; static CategoriesDictionary() { Dictionary = new CategoriesDictionary(); } // The private constructor can be called only by a static member // It returns always the complete list of all categories private CategoriesDictionary() { Categories = new ConcurrentDictionary<int, Category>(); using (var cmd = new DbCommand()) { using (var reader = cmd.ExecuteQuery("sp_Get_EndUserCategories")) { if (reader == null || !reader.HasRows) { Debug.WriteLine("Warning: Stored Procedure returned an empty dataset."); return; } while (reader.Read()) { var id = DbCommand.GetInt(reader, Category.FieldsMap.ID, 5.1 La libreria Novedge Base Catego-ry.IdUndefined); if (id != Category.IdUndefined) Categories.TryAdd(id, new Category(reader)); } reader.Close(); } cmd.Connection.Close(); } } public IEnumerator GetEnumerator() { return Categories.Values.GetEnumerator(); } public IEnumerable<Category> Values { get { return Categories.Values; } } public bool Contains(Category p_Category) { return Categories.ContainsKey(p_Category.ID); } public bool Contains(int p_CategoryID) { return Categories.ContainsKey(p_CategoryID); } public void Add(Category p_Category) { if (p_Category.ID == Category.IdUndefined) return; Categories.TryAdd(p_Category.ID, p_Category); } public void AddOrUpdate(Category p_Category) { if (p_Category.ID == Category.IdUndefined) return; Categories.AddOrUpdate(p_Category.ID, p_Category, (id, category) => {catego-ry.CopyFrom(p_Category);return category;}); } 47 48 Implementazione public void Remove(int p_ID) { if (p_ID == Category.IdUndefined) return; Category category; Categories.TryRemove(p_ID, out category); } public Category this[int p_ID] { get { return Categories.SingleOrDefault(pair => pair.Value.ID == p_ID).Value; } } } } 5.2 La barra di navigazione La barra di navigazione è la parte del CMS sempre visibile posizionata in alto e svolge due funzioni. La prima è quella che consente all'utente di identicarsi tramite uno username e una password per accedere alle applicazioni. Figura 5.2: Barra di navigazione prima del login Quando l'operatore inserisce le proprie credenziali il sistema ne controlla l'esistenza e i permessi all'interno del database mostrando solo i collegamenti alle applicazioni accessibili in base al ruolo dell'utente. Le applicazioni implementate e disponibili vengono salvate in una lista nel codice della toolbar che ne specica l'URL in cui si trova il le aspx principale e il ruolo minimo necessario per poterla utilizzare. Nel caso in cui il login non vada a buon ne o un utente non autorizzato provi ad accedere a un'applicazione che richiede un ruolo più alto viene mostrata una pagina d'errore. Figura 5.3: Barra di navigazione dopo il login 5.3 L'applicazione Products 49 Una volta loggati viene salvato un cookie nel browser dell'utente in modo da identicarlo nei successivi accessi al CMS evitando ogni volta il processo di autenticazione. La navigation bar consente anche di vedere quanti utenti sono attualmente loggati nel sistema (nel quadrato rosso vicino al tasto logout) e, se si è amministratori, si può avere una lista dettagliata di questi utenti e che applicazioni stanno utilizzando. Figura 5.4: Finestra che mostra gli utenti connessi al sistema Per motivi di sicurezza non viene mostrato il codice relativo all'autenticazione e ai permessi degli utenti. 5.3 L'applicazione Products Products è l'applicazione più utilizzata all'interno del CMS in quanto capita spesso di dover modicare qualche caratteristica legata a un prodotto o di doverne inserire uno nuovo. La cancellazione di un prodotto, invece, non è supportata in quanto è un'operazione che avviene raramente e per essere eseguita occorre che nessun altro oggetto all'interno del database faccia riferimento in qualche modo al prodotto. Figura 5.5: Schermata dell'applicazione Products 50 Implementazione La pagina web che si presenta all'avvio è divisa in due parti. La parte superiore consente la ricerca dei prodotti in base al brand e al nome del prodotto con alcune possibilità di ltrare i risultati (in base al genere o allo stato) e di ordinarli. Un altro modo per selezionare un prodotto è mediante la textbox posizionata in basso a sinistra; qui è possibile inserire direttamente lo SKU, ovvero l'identicativo di un prodotto e premere il tasto GoTo. Una volta eettuata la selezione i dati del prodotto vengono caricati nella form presente nella parte inferiore della pagina web. A questo punto è anche possibile nascondere la barra di ricerca (attraverso il tasto a forma di triangolo vicino alla tab Main) in modo da non avere spazio occupato da questa funzione quando non è necessaria. La form contenente i controlli HTML necessari per modicare il prodotto è stata suddivisa in più tab in modo da poter disattivare quelle non necessarie in base a determinate regole (ad esempio se un prodotto non è un bundle non è necessario compilare il contenuto della tab Bundles, che di conseguenza viene disattivata); inoltre, utilizzando questo approccio, la form ha una dimensione che le consente di restare sempre completamente visibile all'interno della nestra del browser. Segue una descrizione delle tab: • La tab Main è la tab principale della applicazione Products in cui si possono settare le caratteristiche basilari. Tra le più importanti troviamo: lo stato (online o oine), il brand, il tipo di prodotto, il nome, la versione, ecc. • Prices permette di settare i prezzi del prodotto. Inserendo il prezzo di listino, il costo e il prezzo fatto da Novedge si ottiene immediatamente un risultato visivo che mostra lo sconto eettuato, il margine sulla vendita, le percentuali e un messaggio riassuntivo. • La tab Bundles viene attivata solamente se un prodotto è di tipo bundle, ossia non è un vero e proprio prodotto ma un insieme di più prodotti venduti a un prezzo inferiore rispetto all'acquisto dei singoli prodotti separatamente; quindi in questa sezione vengono selezionati i prodotti che compongono un bundle. • HTML contiene la descrizione del prodotto. Oltre a supportare i tag HTML la descrizione può contenere altri tag che consentono di inserire collegamenti ad altri prodotti, brand, documenti o a pagine di wikipedia. Durante il salvataggio del prodotto questi tag vengono riconosciuti tramite regular expression e compilati in quello che sarà il risultato nale da mostrare sulla pagina. 5.3 L'applicazione Products • 51 Support e Facts sono due tab che consentono di modicare i rispettivi campi. Il primo contiene informazioni sul supporto tecnico mentre il secondo informazioni speciche sulle proprietà e capacità del prodotto. • La tab Trials consente di inserire i link alle versioni di prova del prodotto per i vari sistemi operativi aggiungendo una descrizione dei limiti del trial. • Le tab Tags, Categories, Masters, Input e Output sono simili dal punto di vista del metodo di inserimento dei valori, esse infatti consentono di associare al prodotto più valori presi da un elenco pressato. I tags deniscono attributi sulle capacità e compatibilità del prodotto. Le categorie permettono di dividere i prodotti in determinati gruppi in base alle funzionalità oerte. La tab masters è attiva solo quando un prodotto deve fare riferimento a un altro prodotto, come nel caso di aggiornamenti di versione. Input e output, invece, permettono di settare i formati di le supportati dal programma. Il punto di forza di questa applicazione sta nel poter creare collegamenti tra i prodotti. Ad esempio se un prodotto è l'aggiornamento di un altro o una versione dierente questa relazione viene inserita nella form. Questo approccio consente agli utenti del sito web che sono alla ricerca di un prodotto di ottenere suggerimenti pertinenti alla ricerca ed arrivare con pochi click alla pagina cercata. Lo sviluppo dell'applicazione products contiene alcune funzionalità, sviluppate in javascript, che sono state utilizzate anche negli altri progetti. 5.3.1 L'autocompletamento dei prodotti Quando, in qualche parte del CMS, si ha la necessità di selezionare o far riferimento a un prodotto viene utilizzato un autocompleter. Questo plugin fa parte dei controlli contenuti nella libreria jQueryUI e viene applicato a una textbox dove, inserendo parte del nome o del codice SKU di un prodotto, viene visualizzata una lista di prodotti che contengono il testo inserito indicando con sfondo di diverso colore se il prodotto è attualmente in vendita o è disattivo. Per far questo il plugin richiama, utilizzando la tecnologia AJAX, il web service AjaxGetCompletionList presente nel progetto che prende in input la stringa di ricerca e ritorna la lista di risultati in formato JSON. A questo punto viene elaborata lato client la lista dei risultati e viene 52 Implementazione Figura 5.6: Autocompleter in funzione applicato a una textbox visualizzata sotto la textbox. Questo approccio consente alla pagina web di essere più leggera non dovendo contenere la lista intera di oltre seimila prodotti. La funzione javaScript che si occupa di collegare l'autocompleter ad un campo di testo è chiamata attachLocalAutocompleter e ha come parametri: • textboxId: identicativo del textbox target. • serviceUrl: URL in cui si trova il web service di autocompletamento. • doPostBackOnSelection: booleano che indica se è necessario fare il post della pagina per farla elaborare al server. • callerObject: specica il riferimento all'oggetto javaScript che ha invocato la funzione (opzionale). • onSelectFunction: riferimento a una funzione del callerObject da invocare quando viene selezionato un elemento dall'autocompleter (opzionale). • onCloseClearTextbox: booleano che indica se è necessario cancellare il contenuto della textbox alla chiusura dell'autocompleter (opzionale). 5.3 L'applicazione Products function attachLocalAutocompleter(textboxId, serviceUrl, doPostBackOnSelection, callerObject, onSelectFunction, onCloseClearTextbox) { jQuery("#" + textboxId).autocomplete({ minLength: 3, source: function (request, response) { jQuery.ajax({ type: "POST", url: serviceUrl + "?str=" + request.term, success: function (data) { var j = data; response(jQuery.map(j.results, function (item) { return { value: item.value, online: item.online }; })); } }); }, select: function (event, ui) { jQuery("#" + textboxId).val(ui.item.value); jQuery("#" + textboxId).attr('online', ui.item.online.toString()); if (typeof (callerObject) != 'undefined' && typeof (onSelectFunction) != 'undefined') onSelectFunction.apply(callerObject); if (doPostBackOnSelection) __doPostBack("'" + textboxId + "'", ''); }, close: function (event, ui) { if (onCloseClearTextbox == true) jQuery('#' + textboxId).val(''); } }) .data('autocomplete') ._renderItem = function (ul, item) { var listItem = jQuery('<li></li>') .data('item.autocomplete', item) 53 54 Implementazione .append('<a>' + item.label + "</a>") .appendTo(ul); if (item.online) listItem.addClass('activeOption'); else listItem.addClass('notActiveOption'); return listItem; }; } 5.3.2 Sistema dei messaggi Questo plugin ha la funzione di mostrare messaggi all'utente svolgendo in pratica lo stesso compito delle funzioni alert e conrm di javaScript ma in modo più gradevole e meno invasivo, non bloccando la pagina in attesa di risposta. Figura 5.7: Esempio di messaggio di worning mostrato all'utente I messaggi vengono visualizzati nell'angolo in basso a destra della pagina e sono stati divisi in tre categorie: • I messaggi di avviso e di warning vengono mostrati rispettivamente su sfondo verde e arancione per avvertire l'operatore se un'operazione richiesta è andata a buon ne o se si sono vericati dei problemi. Il messaggio comprende un bottone denominato `OK' che consente di chiudere il messaggio manualmente, in alternativa l'utente vedrà scomparire il messaggio dopo cinque secondi 5.3 L'applicazione Products • 55 I messaggi di errore hanno uno sfondo rosso e vengono utilizzati per informare l'utente gli errori più gravi. Questo tipo di messaggio resta visibile no alla pressione del tasto `OK'. • I messaggi di conferma sono su sfondo verde e presentano due possibili scelte `Yes' o `No' con cui l'operatore può confermare l'operazione richiesta. I messaggi vengono posizionati nella pagina attraverso i fogli di stile CSS settando i valori position:xed, right:10px e bottom:0 agli elementi con ID dialogBox. In questo modo il plugin è indipendente dal contenuto e dalla formattazione della pagina prendendo come riferimento l'area visibile del browser. Le animazioni del messaggio sono state realizzate utilizzando lo slide di jQuery. Quando infatti attraverso questa libreria si specica se un elemento del DOM deve passare dallo stato visibile a nascosto o viceversa, è possibile specicare se la transizione deve essere animata (scegliendo tra diversi eetti graci) e quanto deve durare. jQuery("#dialogBox").show('slide', { direction: 'down' }, 1000); setTimeout(function () { jQuery("#dialogBox").hide('slide', { direction: 'down' }, 1000); }, 5000); 5.3.3 Il plugin Wikipedia Questa funzione javascript consente all'utente che sta navigando sul sito Novedge di cliccare su un link a una pagina wikipedia e vedere il risultato in un riquadro senza dover lasciare il sito. Alcune parti del CMS consentono di inserire nelle descrizioni delle entità riferimenti a pagine di Wikipedia. Questi collegamenti vengono rappresentati nel testo con dei tag che verranno poi sostituiti con la chiamata alla funzione che attiva il plugin realizzato. Il contenuto del plugin viene acquisito mediante l'utilizzo dei web service di Wikipedia che consentono di ottenere, in diversi formati, le parti della pagina scegliendo poi cosa mostrare al visitatore. Mediante una funzione C# viene generato l'URL necessario per richiedere i contenuti dell'header e del body della pagina Wikipedia specicata come argomento. A questo punto viene generato il contenuto del riquadro da visualizzare 56 Implementazione Figura 5.8: Plugin wikipedia in azione sul sito Novedge togliendo le parti non necessarie (come il menù laterale, l'intestazione e i collegamenti per editare la pagina). private void GetWikipediaPage(string p_Page) { var url = "http://en.wikipedia.org/w/api.php?" + "action=parse&format=xml&prop=text%7Cheadhtml&redirects&page="; url += HttpUtility.HtmlEncode(p_Page); var request = (HttpWebRequest)WebRequest.Create(url); request.UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4"; using (var response = (HttpWebResponse)request.GetResponse()) { var xmlDoc = new XmlDocument(); xmlDoc.Load(response.GetResponseStream()); XmlNodeList header = xmlDoc.GetElementsByTagName("headhtml"); var headerDecoded = HttpUtility.HtmlDecode(header[0].InnerText); Header.Controls.AddAt(0, new Literal() { Text = headerDecoded }); 5.4 L'applicazione Books 57 XmlNodeList body = xmlDoc.GetElementsByTagName("text"); var bodyDecoded = FixLinksLocation(HttpUtility.HtmlDecode(body[0].InnerText)); h_wikipedia_content.Controls.Add(new Literal() { Text = bodyDecoded }); } } 5.4 L'applicazione Books Books è l'applicazione il cui compito è quello di associare un libro a una o più categorie di prodotti. Novedge non si occupa direttamente della vendita dei libri ma fornisce collegamenti a libri presenti su Amazon. Figura 5.9: Schermata dell'applicazione Books Quando si inserisce un ASIN (Amazon Standard Identication Number) nella form il sistema controlla se il libro è già presente nel database. In questo caso viene mostra- to il bottone Load elds from Novedge che carica i dati del libro e le associazioni dal database. Se invece il libro non è ancora stato inserito appare il bottone Load elds from Amazon che, attraverso una chiamata al web service Product Advertising API di 58 Implementazione Amazon, permette di caricare tutti i dati del libro automaticamente evitando all'utente l'inserimento manuale. Nella parte inferiore dell'applicazione troviamo tre sezioni denominate Suggested Books, Suggested Books already inserted e Last Books added. Le prime due mostrano una lista di libri, ottenuta sempre grazie ai web service AWS, che sono pertinenti all'argomento del libro attualmente caricato nella form. In questo modo l'utente riesce con pochi click del mouse ad inserire un'enorme quantità di entità all'interno della base di dati. L'ultima sezione, invece, mostra gli ultimi cinque libri inseriti in ordine cronologico inverso. Tra le funzioni che agevolano ulteriormente il lavoro dell'operatore abbiamo l'anteprima della copertina quando si passa col mouse sui collegamenti presenti nelle liste e i due bottoni in alto a destra che permettono di aprire in una nestra separata le pagine relative al libro selezionato su Amazon e sul sito Novedge. Per l'accesso ad Amazon sono state realizzate tre classi: AmazonRequest, AmazonItemLookup e AmazonSimilarityLookup. AmazonRequest è una classe astratta da cui le altre due derivano e il suo compito è quello di generare l'URL necessario per la richiesta di informazioni. Per fare ciò questa classe utilizza una coppia di chiavi (una pubblica e una privata), salvate nel le di congurazione dell'applicazione, necessarie per identicarsi e per creare la rma del messaggio che altrimenti verrebbe riutato. public abstract class AmazonRequest { // CONSTANTS protected readonly string AccessKeyId = ConfigurationManager.AppSettings["AWSAccessKey"]; protected readonly string SecretAccessKey = ConfigurationManag-er.AppSettings["AWSSecretKey"]; protected const string AssociateTag = "novedge"; protected const string Service = "AWSECommerceService"; protected const string Version = "2011-08-01"; protected const string StringToSignPrefix = "GET\necs.amazonaws.com\n/onca/xml\n"; protected const string WebServiceUrl = "http://ecs.amazonaws.com/onca/xml"; // ATTRIBUTES protected Dictionary<string, string> RequestParams; 5.4 L'applicazione Books // PROPERTIES private XmlDocument _responseXmlDocument; public XmlDocument ResponseXmlDocument { get { return _responseXmlDocument ?? (_responseXmlDocument = GetResponseXmlDocu-ment()); } protected set { _responseXmlDocument = value; } } // CONSTRUCTOR protected AmazonRequest() { RequestParams = new Dictionary<string, string>(); RequestParams["AWSAccessKeyId"] = AccessKeyId; RequestParams["AssociateTag"] = AssociateTag; RequestParams["Service"] = Service; RequestParams["Version"] = Version; } // PRIVATE METHODS private XmlDocument GetResponseXmlDocument() { var responseXmlDoc = new XmlDocument(); try { var url = GetRequestUrl(); responseXmlDoc.Load(url); } catch { return null; } return responseXmlDoc; } private string GetRequestUrl() { var requestParams = GetRequestParamsAsUrlString(); var signature = GetSignature(requestParams); return WebServiceUrl + "?" + requestParams + "&Signature=" + signature; 59 60 Implementazione } private string GetRequestParamsAsUrlString() { var timestamp = string.Format("{0:s}Z", DateTime.Now.ToUniversalTime()); RequestParams["Timestamp"] = timestamp; var paramRequestUrlString = new StringBuilder(); paramRequestUrlString.Append("AWSAccessKeyId=") .Append(RequestParams["AWSAccessKeyId"]) .Append("&"); foreach (var key in RequestParams.Select(param => param.Key).Where(key => key != "AWSAccessKeyId").OrderBy(key => key)) paramRequestUrlString.Append(key) .Append("=") .Append(RequestParams[key]) .Append("&"); return paramRequestUrlString.Remove(paramRequestUrlString.Length - 1, 1).ToString(); } private string GetSignature(string p_ParamsStringToSign) { var stringToSign = StringToSignPrefix + p_ParamsStringToSign.Replace(",", "%2C").Replace(":", "%3A"); return SignString(SecretAccessKey, stringToSign); } private string SignString(string p_SecretKey, string p_StringToSing) { var key = Encoding.UTF8.GetBytes(p_SecretKey); var myHash256 = new HMACSHA256(key); var urlBytes = Encoding.UTF8.GetBytes(p_StringToSing); var hashValue = myHash256.ComputeHash(urlBytes); var signedString = Convert.ToBase64String(hashValue); return signedString.Replace("/", "%2F").Replace("=", "%3D").Replace("+", 5.4 L'applicazione Books 61 "%2B"); } } La classe AmazonItemLookup viene richiamata alla pressione del bottone Load elds from Amazon per ricevere tutte le informazioni necessarie per riempire i campi della form relativi a un libro. public class AmazonItemLookup : AmazonRequest { // CONSTANTS private const string IdType = "ASIN"; private const string Operation = "ItemLookup"; private const string ResponseGroup = "ItemAttributes,Images,Reviews,OfferSummary"; private const string MerchantId = "Featured"; // CONSTRUCTOR public AmazonItemLookup(string p_ASIN) { RequestParams["ItemId"] = p_ASIN; RequestParams["IdType"] = IdType; RequestParams["Operation"] = Operation; RequestParams["ResponseGroup"] = ResponseGroup; RequestParams["MerchantId"] = "Featured"; } // PROPERTIES public string Title { get { if (ResponseXmlDocument == null) return ""; var xmlNode = ResponseXmlDocument.GetElementsByTagName("Title")[0]; return xmlNode != null ? xmlNode.InnerText : ""; } } public string Year { get; } // Codice omesso per compattezza public double LowestPrice { get; } 62 Implementazione public string Author { get; } public string ImageUrl { get; } } Inne AmazonSimilarityLookup serve per ottenere una lista di prodotti simili a quello specicato. In questo caso occorre ltrare i risultati in modo da mostrare all'utente solo i prodotti di tipo libro e ignorare tutti gli altri. La classe SimilarBook è una struttura dati di supporto per gli elementi ottenuti. public class SimilarBook { public string ASIN { get; private set; } public string Title { get; private set; } public string ImageUrl { get; private set; } public SimilarBook(string p_Asin, string p_Title, string p_ImageUrl) { ASIN = p_Asin; Title = p_Title; ImageUrl = p_ImageUrl; } } public class AmazonSimilarityLookup : AmazonRequest { // CONSTANTS private const string Operation = "SimilarityLookup"; private const string ResponseGroup = "Images,Small"; // CONSTRUCTOR public AmazonSimilarityLookup(string p_ASIN) { RequestParams["ItemId"] = p_ASIN; RequestParams["Operation"] = Operation; RequestParams["ResponseGroup"] = ResponseGroup; } // PROPERTIES public IEnumerable<SimilarBook> SimilarBooks { get { var similarBooks = new List<SimilarBook>(); 5.5 L'applicazione Specials 63 if (ResponseXmlDocument == null) return similarBooks; var xmlItemTags = ResponseXmlDocument.GetElementsByTagName("Item"); foreach (XmlNode xmlItemTag in xmlItemTags) { if (xmlItemTag["ItemAttributes"]["ProductGroup"].InnerText != "Book") continue; similarBooks.Add(new SimilarBook(xmlItemTag["ASIN"].InnerText, xmlI-temTag["ItemAttributes"]["Title"].InnerText, xmlItemTag["LargeImage"]["URL"].InnerText)); } return similarBooks; } } } 5.5 L'applicazione Specials Quando un prodotto del catalogo viene messo in promozione, oltre ad abbassarne il prezzo, occorre mostrare sulla pagina un messaggio con la descrizione o motivazione della promozione. L'applicazione Specials si occupa proprio di questo, dando la possibilità all'utente di creare nuove promozioni e di associare ad esse uno o più prodotti che mostreranno lo stesso messaggio promozionale. Anche in questo caso si è suddiviso il contenuto della form in diverse tab in modo da separare concettualmente le operazioni che si stanno eseguendo. La prima tab è denominata Post It e permette di settare i contenuti del messaggio da visualizzare (simile appunto a un post it) oltre alle date di inizio e ne della promozione. Il post it è composto da quattro parti: il titolo e il footer appaiono rispettivamente in cima e in fondo al messaggio, mentre nella parte centrale sono situati il testo della promozione e la label che, di solito, ha un carattere molto più grande rispetto agli altri per attirare l'attenzione. Esistono due tipi di testo per lo special, uno on target e uno o target. Quello on target è il messaggio mostrato quando il prodotto è in promozione, mentre quello o target 64 Implementazione quando il prodotto fa riferimento a un altro prodotto in promozione. Mentre vengono editati i campi della form vengono visualizzate ai piedi della pagina le anteprime di come verrà visualizzato il messaggio sul sito web, aggiornate lato client ad ogni modica utilizzando javaScript. Figura 5.10: Schermata della tab Post It dell'applicazione Specials La seconda tab, invece, consente di associare i prodotti allo special. Scrivendo lo SKU o parte del nome di un prodotto nella textbox libera della lista appare l'autocompleter che consente di selezionare il prodotto interessato, dopodiché è possibile cambiarne i prezzi, gli SKU esterni e associare un altro prodotto di riferimento. Prima di poter associare un prodotto ad uno special il sistema deve controllare che questo non sia già in promozione in un altro special attivo. In questo caso l'utente viene informato del conitto con un messaggio e l'elemento non può essere salvato a meno che non si risolva in qualche modo il conitto. La gestione di questa parte avviente completamente lato client utilizzando un oggetto javaScript denominato SpecialProductRow contenente le funzioni per gestire ogni prodotto associato. 5.5 L'applicazione Specials 65 Figura 5.11: Schermata della tab Products dell'applicazione Specials function SpecialProductRow() { this.loadFields = function () { ... } this.initializeRow = function () { ... } this.productSelected = function () { ... } this.showProductPicture = function () { ... } this.hideProductRow = function () { ... } this.checkUniqueness = function() { ... } } I metodi contenuti in questo oggetto sono: • loadFields carica nella form tutti i dati relativi al prodotto attraverso l'utilizzo del web service AjaxGetSpecialProductInfos. Tra le informazioni contenute nella risposta AJAX troviamo anche quella che specica se il prodotto è già attivo in un altro special; in questo caso l'utente viene avvisato da un messaggio su sfondo rosso. • initializeRow setta le proprietà e gli stili dei controlli durante l'inserimento di una nuova riga. • productSelected è la funzione che viene richiamata dall'autocompleter quando si sceglie un nuovo prodotto da associare allo special. Questa ha il compito di creare una nuova riga richiamando gli altri metodi per inizializzarla e riempirla con i dati del prodotto. • showProductPicture richiama il web service AjaxGetProductPicture per farsi ritornare l'immagine della scatola del prodotto che verrà poi visualizzata all'inizio della 66 Implementazione riga. • hideProductRow viene invocata quando l'utente cancella una riga. La funzione si occupa di marcarla come cancellata nascondendola all'utente. • checkUniqueness ha il compito di controllare che il prodotto di una nuova associazione non sia già presente nella lista dei prodotti dello special. Le ultime due tab sono quelle dei commenti e dei log, già illustrate in precedenza. Specials consente anche, premendo il bottone Calendar, di avere una rappresentazione tabellare stampabile del calendario delle oerte attive in un determinato mese, fornendo in questo modo una visualizzazione che consente di tenere sotto controllo le scadenze. 5.6 L'applicazione Documents L'applicazione documents consente di associare un documento a una lista di prodotti o ad un intero brand. I le che si vogliono inserire nel database possono essere collegamenti a risorse disponibili su internet oppure le presenti sul computer dell'operatore. Nel secondo caso i documenti devono essere caricati su S3, una piattaforma cloud di storage fornita da Amazon. L'upload avviene in due fasi. Come prima cosa l'utente sceglie dal proprio computer il documento da caricare premendo il bottone Upload New File. Questo viene trasferito sul server Novedge dopodichè la web application contatta i server di Amazon utilizzando le API speciche per il framework .NET, identicandosi attraverso una coppia di chiavi (una pubblica e una privata segreta), ed eetua l'upload denitivo del le. Il documento sarà quindi raggiungibile da internet attraverso un indirizzo specico. La pressione del bottone Upload richiama l'esecuzione dell'evento contenente il seguente codice: protected void UploadSelectedDocumentButtonClick(object sender, EventArgs e) { var fileName = h_document_fileupload.FileName; if ((!string.IsNullOrEmpty(fileName.Trim())) && h_document_fileupload.FileContent.Length == 0) { Html.ShowWarning(this, "The selected file is empty"); return; 5.6 L'applicazione Documents 67 } if (!h_document_fileupload.HasFile || string.IsNullOrEmpty(fileName.Trim())) { Html.ShowWarning(this, "Select a file before pushing the Upload button"); return; } if (JustUploadedS3Document != "") DeleteObjectFromAmazonS3(JustUploadedS3Document); var fileSizeInMb = h_document_fileupload.FileContent.Length/1048576f; var inputStream = new MemoryStream(); h_document_fileupload.FileContent.CopyTo(inputStream); var accessKeyId = ConfigurationManager.AppSettings["AWSAccessKey"]; var secretAccessKey = ConfigurationManager.AppSettings["AWSSecretKey"]; var bucketName = ConfigurationManager.AppSettings["DocumentsBucketName"]; try { var transferUtilityConfig = new TransferUtilityConfig {DefaultTimeout = 1200000}; var fileTransferUtility = new TransferUtility(accessKeyId, secretAccessKey, transferU-tilityConfig); fileTransferUtility.Upload(inputStream, bucketName, fileName); using (var client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKeyId, secre-tAccessKey)) { var setAclRequest = new SetACLRequest { BucketName = bucketName, Key = fileName, CannedACL = S3CannedACL.PublicRead }; var setAclResponse = client.SetACL(setAclRequest); setAclResponse.Dispose(); } h_hidden_just_uploaded_s3_document.Value = fileName; } catch { 68 Implementazione Html.ShowError(this, "An Error occurred during file upload"); return; } h_document_url.Text = "http://" + bucketName + ".s3.amazonaws.com/" + HttpUtility.UrlEncode(fileName); Html.ShowAcknowledgment(this, "File uploaded correctly"); h_upload_panel.Visible = false; h_document_size.Text = "-1"; if ((int) (fileSizeInMb*100) != 0) h_document_size.Text = string.Format("{0:0.00}", fileSizeInMb); } Dopo una serie di controlli nalizzati a capire se l'operatore abbia eettivamente selezionato un le e che questo non sia vuoto il sistema prova (nel blocco try catch) a inviare il le. Se il documento viene caricato correttamente su S3 l'applicazione si preoccupa di correggere il campo size della form con la dimensione eettiva del documento, inoltre si tiene traccia del documento in modo tale che se l'utente non salva eettivamente l'enità document all'interno del database questo viene scartato ed eliminato da S3. Nel caso in cui l'operazione non vada a buon ne viene mostrato un messaggio d'errore. Figura 5.12: Sequence diagram del caricamento dei le nell'applicazione Documents 5.7 L'applicazione Orders 69 Di default una web application ASP.NET supporta, per ovvie ragioni di sicurezza, il trasferimento in upload per le di massimo 4 megabyte di dimensione. Questo limite è stato tolto nell'applicazione corrente in quanto può capitare di dover processare le di dimensioni maggiori ed essendo utilizzata dal personale interno all'azienda non è soggetta ad attacchi dall'esterno. Figura 5.13: Schermata dell'applicazione Documents 5.7 L'applicazione Orders L'applicazione Orders è stata creata per consentire la modica degli ordini eettuati dai clienti. Da notare che per la consultazione di tali ordini l'azienda fa uso di un'altra applicazione web integrata nel sito sviluppata precedentemente alla realizzazione di questo CMS. All'avvio la pagina mostra il template di un ordine vuoto utilizzabile per eseguire test e operazioni su un ordine non esistente, in quanto non è possibile creare un nuovo ordine ma solo modicare quelli già presenti nella base di dati. Per caricare i dati di un ordine presente nel database nella form si inserisce l'identicativo nella casella in basso a sinistra premendo poi invio o il bottone GoTo. Una volta che i campi sono stati riempiti con i dati dell'ordine l'applicazione funziona per la quasi totalità lato client, utilizzando funzioni e oggetti javaScript, in modo da eseguire 70 Implementazione le operazioni richieste in modo uido e veloce evitando quindi il postback e il refresh della pagina. Le operazioni consentite su un ordine sono: • Modica degli indirizzi di spedizione e fatturazione. • Modica del prezzo unitario e quantità dei prodotti che compongono l'ordine. • Inserire e cancellare prodotti. • Modica del metodo di pagamento. • Aggiungere o modicare coupon di sconto. • Modicare i dati relativi all'ordine stesso come sconto, costo spedizione, tasse e totale. • Esplosione di un bundle, ovvero sostituire la voce del bundle nell'ordine con i prodotti in esso contenuti. Figura 5.14: Schermata dell'applicazione Orders La funzione di autocalcolo dei valori entra in azione appena dopo il caricamento dei valori nella form. Partendo dai dati base come il prezzo unitario e la quantità dei prodotti questa 5.8 L'applicazione Reports 71 funzione prova a calcolare i valori dell'ordine in modo automatico. Se questi combaciano con quelli caricati (presenti nel database) allora la funzione rimane attiva ricalcolando tutti i valori ad ogni modica dei campi, in caso contrario l'autocalcolamento viene disattivato e l'utente dovrà occuparsi del calcolo dei campi non conformi. Le motivazioni per cui i valori del database e quelli calcolati potrebbero non coincidere sono dovute alla modica della percentuale delle tasse (che in genere cambia annualmente), alla modica dei costi di spedizione o a regole non ancora introdotte nella logica dell'applicazione. 5.8 L'applicazione Reports Inizialmente reports era un'applicazione concepita solo con l'intento di controllare i dati contenuti nel database in base a regole predenite generando appunto un report della situazione, poi con l'evolversi del CMS sono state aggiunte le seguenti funzionalità: • Recompile website si occupa di convertire tutti quei campi di testo presenti nel database che contengono dei tag (ad esempio i testi degli specials) sostituendoli con il testo opportuno. In questo modo si alleggerisce il lavoro del web server che altrimenti dovrebbe svolgere l'operazione ad ogni richiesta di pagina. • Clean database elimina del database quei record che non sono più referenziati da altri oggetti o che sono datati e considerati inutili. Questi elementi sono generati da prove varie eseguite sulla base di dati o dovuti a cambiamenti avvenuti nel tempo. • Latest log entries permette di consultare tutti i log di ogni applicazione ltrandoli anche per un periodo di tempo specico. Per quanto riguarda le regole da controllare nella funzionalità di consistency check è stata sviluppata una classe astratta contenente i campi fondamentali da cui ogni regola implementata deriva. La classe CheckerBase contiene un Nome e una descrizione che spiegano che tipo di controllo svolge la regola, un campo enumerabile Module per il tipo di modulo su cui opera la funzione e una metodo Check() che conterrà il codice di controllo e restituisce una lista di oggetti CheckerResult per ogni singolo test eettuato. namespace Novedge.CMS.Reports.Checkers { public abstract class CheckerBase { public abstract string Name { get; } public abstract string Description { get; } 72 Implementazione public abstract Security.Module Module { get; } public abstract List<CheckerResult> Check(); } } La classe CheckerResult rappresenta il risultato del controllo di una regola applicato a un singolo elemento. Oltre ai campi ItemId e Title che rappresentano rispettivamente l'identicativo e il titolo (o nome) dell'oggetto testato vengono forniti: un messaggio testuale che viene visualizzato dall'applicazione, un campo Status con l'esito del test e un campo ActionTaken che specica l'azione del checker in base al risultato (None = nessuna azione, Alerted = utente avvisato, Fixed = errore risolto dal sistema). namespace Novedge.CMS.Reports.Checkers { public class CheckerResult { public int ItemId { get; set; } public Status Status { get; set; } public ActionTaken ActionTaken { get; set; } public string Message { get; set; } public string Title { get; set; } public CheckerResult(int p_ItemId, string p_Message, Status p_Status = Status.Ok, ActionTaken p_ActionTaken = ActionTaken.None, string p_Title = "") { ItemId = p_ItemId; Message = p_Message; Status = p_Status; ActionTaken = p_ActionTaken; Title = p_Title; } } public enum Status { Ok, Warning, Error } public enum ActionTaken { 5.8 L'applicazione Reports 73 None, Alerted, Fixed } } L'applicazione Consistency Check contiene una lista di tutti i checker utilizzabili consentendo all'amministratore di vedere i report. Attualmente sono state implementate le seguenti regole: • Verica che tutti i prezzi (per i prodotti attivi) siano maggiori di zero. • Verica che i prezzi Novedge siano compresi tra il costo e il prezzo di listino. • Verica che i prodotti contenuti in un bundle non siano a loro volta bundle. • Verica che tutti i prodotti che contengono altri prodotti siano categorizzati come bundle. • Verica che i bundle non contengano se stessi. (molto raro) • Verica che i prezzi dei bundle siano inferiori alla somma dei singoli prodotti in esso contenuti. • Verica che tutti i prodotti abbiano associato almeno un tag di platform (ovvero su che sistema operativo possono essere utilizzati). • Verica che tutti i prodotti abbiano l'immagine della scatola. • Vericare che tutti i prodotti abbiano almeno una categoria associata e una sola categoria principale. • Vericare che tutti i libri abbiano almeno una categoria associata e una sola categoria principale. • Vericare che tutti i link ai documenti siano online e raggiungibili. 74 Implementazione Figura 5.15: Schermata dell'applicazione Reports 5.9 Altre applicazioni Il CMS è composto da altre applicazioni, descritte brevemente nell'analisi, che non vengono illustrate in quanto sono simili a quelle già discusse in precedenza per quanto riguarda funzionalità e utilizzo. 5.10 Web services I web service implementati in questo progetto sono simili a pagine web dinamiche ma funzionano in modo leggermente diverso. Il processo chiamante invoca il web service attraverso un URL specico passandogli i parametri necessari all'elaborazione come query string, ovvero una lista di argomenti in formato chiave=valore separati dal carattere ?. Se le chiavi o i valori contengono caratteri speciali questi devono essere codicati in modo da essere conformi all'HTML. Una volta ricevuta la richiesta il code behind del web service controlla che l'utente del processo che lo ha invocato sia loggato nel sistema e che nell'URL ci siano tutti i parametri necessari per elaborare la risposta. Se una di queste due condizioni non viene soddisfatta verrà ritornato un messaggio di errore indicandone il motivo. Nel caso in cui il web service riesca a soddisfare la richiesta, il risultato dell'elaborazione viene ritornato in formato JSON e utilizzato dal codice JavaScript che lo ha invocato. Si è scelto questo formato in quanto i web sevices vengono utilizzati esclusivamente lato 5.10 Web services 75 client attraverso la tecnologia AJAX. Sono stati implementati i seguenti web services: • AjaxInsertComment e AjaxDeleteComment servono alle applicazioni che implementano il wall dei commenti. Utilizzando questi web service è possibile inserire o eliminare i commenti senza dover ricorrere al refresh della pagina rendendo questo processo molto simile agli odierni social network. • AjaxGetBundledProducts ritorna i prodotti contenuti in un budle il cui SKU è passato come parametro. • AjaxGetCompletionList serve all'autocompleter per avere una lista dei prodotti che contengono nel nome una sottostringa passata. • AjaxGetProductPicture ritorna gli URL delle immagini della scatola del prodotto in diverse risoluzioni. • AjaxGetSimpleProduct ha il compito di recuperare le informazioni basilari di un prodotto. • AjaxGetSpecialProductInfos ritorna i dati di un prodotto in promozione come i prezzi prima e dopo lo sconto. public partial class AjaxGetBundledProducts : Page { protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/json"; int productSku; if (!int.TryParse(Request.QueryString["sku"], out productSku)) { Response.Write(JSON.Error("AjaxGetBundledProducts", "Null Product")); return; } var product = new Product(productSku); if (product.SKU == Product.SkuUndefined) { Response.Write(JSON.Error("AjaxGetBundledProducts", "Null Product")); return; } 76 Implementazione Response.Write(product.ToJSON()); } } 5.11 Validazione Il processo di validazione viene eseguito in tutte le applicazioni del CMS ed è necessario per controllare che i dati nella form siano conformi prima che questi vengano inseriti nel database. La tecnologia ASP.NET include già alcuni meccanismi di validazione per i controlli più comuni, come ad esempio vericare che un campo non sia senza valore o che sia in un range di valori, tuttavia si è scelto di implementare un proprio meccanismo di validazione dei contenuti in modo da poter gestire gli errori integrandoli con il sistema di messaggi già presente in tutte le applicazioni. Ogni applicazione contiene nella propria cartella una classe Validator specica, ognuna della quali deriva dalla classe base Validator.cs localizzata nella cartella CommonCode. Questa classe contiene una lista di messaggi per ogni regola infranta e la proprietà ValidatorsMessagesAsHtmlList che ritorna questi messaggi in un formato HTML già pronto per essere visualizzato nel sistema di messaggi integrato nelle applicazioni. Il metodo CheckFieldNotEmpty, necessario per controllare che un campo non sia vuoto, è stato inserito in questa classe in quanto è uno dei controlli più frequenti e utilizzato da tutti i validatori. namespace Novedge.CMS.CommonCode { public abstract class Validator { // CONSTANTS protected readonly Color ERROR_COLOR = Color.Khaki; // ATTRIBUTES protected List<string> ValidatorsMessages; // PROPERTIES public string ValidatorsMessagesAsHtmlList { get { var messagesHtmlList = new StringBuilder(); 5.12 Liste per la consultazione delle entità 77 messagesHtmlList.Append("<ul>"); foreach (var message in ValidatorsMessages) messagesHtmlList.Append("<li>").Append(message).Append("</li>"); messagesHtmlList.Append("</ul>"); return messagesHtmlList.ToString(); } } public bool HasMessages { get { return ValidatorsMessages.Count > 0; } } // CONSTRUCTOR protected Validator() { ValidatorsMessages = new List<string>(); } // GENERAL FUNCTIONS protected bool CheckFieldNotEmpty(string p_Field, string p_ErrorMessage) { if (p_Field.Trim().Length == 0) { ValidatorsMessages.Add(p_ErrorMessage); return false; } return true; } } } 5.12 Liste per la consultazione delle entità La maggior parte delle applicazioni realizzate rende disponibile un bottone, situato in basso a sinistra, denominato List che consente di consultare la lista delle entità attualmente presenti nel database. Questo elenco viene visualizzato come tabella HTML contenente i campi più signicativi per ogni entità in modo da fornire all'operatore le informazioni necessarie per scegliere l'oggetto da editare nella form. 78 Implementazione Figura 5.16: Schermata della lista di Brands Per la generazione di queste tabelle è stato utilizzato il controllo GridView incluso nella piattaforma ASP.NET che consente di specicare, attraverso la proprietà DataSource, l'origine dei dati (sia questa una lista di oggetti o una DataView ottenuta mediante una query sul database) occupandosi poi di generare la vista in modo completamente automatico o secondo parametri specicati. <asp:GridView ID="h_brands_gridview" runat="server" AutoGenerateColumns="False" AllowSort-ing="True" OnRowDataBound="GridViewRowDataBound" OnSorting="SelectionGridViewSorting" DataKeyNames="ID" OnRowCom-mand="SelectionGridViewRowCommand" style="width:100%" > <HeaderStyle BackColor="#FFEECC" /> <AlternatingRowStyle BackColor="#FFFF8F" /> <Columns> <asp:ButtonField DataTextField="ID" HeaderText="Brand ID" SortExpression="ID" Button-Type="Link" CommandName="Select" /> <asp:ImageField HeaderText="Logo" DataImageUrlField="Logo" ReadOnly="True" NullDisplay-Text=""> <ControlStyle Width="60"></ControlStyle> </asp:ImageField> <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" /> <asp:BoundField DataField="TagLine" HeaderText="Tag Line" SortExpression="TagLine" /> <asp:BoundField DataField="PriceMode" HeaderText="Price Mode" SortExpres-sion="PriceMode" /> <asp:TemplateField HeaderText="Is Online" ItemStyle-HorizontalAlign="Center" 5.13 Funzioni di Wall e Log 79 SortEx-pression="IsOnline"> <ItemTemplate> <asp:CheckBox runat="server" Enabled="False" Checked='<%# (bool) DataBin-der.Eval(Container.DataItem, "IsOnline") %>'/> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> Settando il parametro AllowSorting a true viene attivata la funzione di ordinamento che consente, selezionando un campo nell'intestazione, di ottenere la tabella ordinata in base alla scelta eettuata. Un'altra caratteristica del controllo GridView che è tornata utile è il fatto di poter cambiare lo sfondo delle singole righe; impostando un colore grigio per quelle entità che non sono attive l'operatore ha un feedback graco immediato. 5.13 Funzioni di Wall e Log Le funzionalità di wall e log sono accessibili, per quelle entità che le implementano, attraverso delle tab dedicate. La tab Wall consente di associare dei commenti (lasciati dagli operatori) a un'entita. Questi vengono caricati assieme all'entità selezionata e visualizzati in ordine cronologico inverso in modo da spingere l'utente a cancellare i più datati una volta che questi non sono più ritenuti necessari. Un piccolo numero vicino nell'etichetta della tab mostra quanti commenti sono stati attualmente inseriti. Figura 5.17: Schermata della funzione wall nei Brands 80 Implementazione L'inserimento e la cancellazione dei messaggi avviene attraverso chiamate AJAX ai web service AjaxInsertComment e AjaxDeleteComment rendendo la gestione dei commenti uida e simile a quella dei moderni social network. La tab Log presenta all'operatore una vista tabellare con la storia dell'entità, dalla sua creazione no all'ultima modica eettuata, specicando data, ora, autore, modulo e descrizione dei cambiamenti avvenuti. Figura 5.18: Schermata della funzione log negli Specials 81 Conclusioni Il lavoro svolto è stato molto duro ma entusiasmante. Ho potuto per la prima volta vedere come nasce un software aziendale e partecipare al processo, comprendendone appieno dettagli e contesto di operazione. Applicando ed integrando sul campo le nozioni apprese separatamente nei vari esami di Informatica, ho potuto acquisire l'esperienza di un programmatore professionista. L'esperienza di lavoro con Novedge è stata fantastica e il periodo trascorso negli USA mi ha mostrato le potenzialità di un ambiente dinamico ed internazionale, consentendomi un salto di qualità notevole. Una ulteriore esperienza di lavoro con AREA Professional mi ha consentito di migliorare ulteriormente la conoscenza dei più avanzati strumenti del mondo .NET, raggiungendo una notevole conoscenza dello strumento. Il CMS realizzato per Novedge è attualmente in produzione e si è rivelato uno strumento potente in grado di gestire ecientemente i compiti di gestione dei prodotti e di tutte le entità a contorno. Il progetto passa quindi in una fase di manutenzione in cui è necessario modicare il codice sorgente solo in caso di malfunzionamenti dovuti a bug non ancora corretti o all'introduzione di nuove regole e funzionalità. La soddisfazione di Novedge è dimostrata dalla proposta di continuare la collaborazione sino al 2014. Nel nuovo progetto lavorerò su nuove parti del sistema. ELENCO DELLE FIGURE 2.1 Architettura del sistema informatico di Novedge . . . . . . . . . . . . . . 10 3.1 Rappresentazione della collocazione del sistema . . . . . . . . . . . . . . 14 3.2 Products Operator use case diagram . . . . . . . . . . . . . . . . . . . . 20 3.3 Orders Operator use case diagram . . . . . . . . . . . . . . . . . . . . . . 21 3.4 Administrator use case diagram 21 4.1 Struttura del progetto Novedge.CMS 4.2 Disposizione degli elementi nell'interfaccia utente 4.3 Diagramma ER della base di dati 4.4 Schema di funzionamento di un web service 5.1 Class Diagram delle classi in Novedge.Base utilizzate per le categorie 5.2 Barra di navigazione prima del login . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 . . . . . . . . . . . . . 28 . . . . . . . . . . . . . . . . . . . . . . 29 . . . . . . . . . . . . . . . . 30 . . 38 . . . . . . . . . . . . . . . . . . . . 48 5.3 Barra di navigazione dopo il login . . . . . . . . . . . . . . . . . . . . . . 48 5.4 Finestra che mostra gli utenti connessi al sistema . . . . . . . . . . . . . 49 5.5 Schermata dell'applicazione Products . . . . . . . . . . . . . . . . . . . . 49 5.6 Autocompleter in funzione applicato a una textbox . . . . . . . . . . . . 52 5.7 Esempio di messaggio di worning mostrato all'utente . . . . . . . . . . . 54 5.8 Plugin wikipedia in azione sul sito Novedge . . . . . . . . . . . . . . . . . 56 5.9 Schermata dell'applicazione Books . . . . . . . . . . . . . . . . . . . . . . 57 5.10 Schermata della tab Post It dell'applicazione Specials . . . . . . . . . . . 64 5.11 Schermata della tab Products dell'applicazione Specials . . . . . . . . . . 65 84 ELENCO DELLE FIGURE 5.12 Sequence diagram del caricamento dei le nell'applicazione Documents . 68 5.13 Schermata dell'applicazione Documents . . . . . . . . . . . . . . . . . . . 69 5.14 Schermata dell'applicazione Orders . . . . . . . . . . . . . . . . . . . . . 70 5.15 Schermata dell'applicazione Reports . . . . . . . . . . . . . . . . . . . . . 74 5.16 Schermata della lista di Brands . . . . . . . . . . . . . . . . . . . . . . . 78 5.17 Schermata della funzione wall nei Brands . . . . . . . . . . . . . . . . . . 79 5.18 Schermata della funzione log negli Specials . . . . . . . . . . . . . . . . . 80 BIBLIOGRAFIA [1] Giulio Destri. Introduzione ai sistemi informativi aziendali. Monte Università Parma Editore, 2007. [2] Abijit Chaudhury and Jean-Pierre Infrastructure. McGraw-Hill, 2002. [3] Ulrich Kampmeyer. Kuilboer. e-Business and e-Commerce ECM Enterprise Content Management. McGraw-Hill, 2006. [4] Matthew MacDonald and Adam Freeman. Pro ASP.NET 4 in C# 2010. APress, 2010. [5] Mike White Paul Nielsen, Uttam Paru. Microsoft SQL Server 2008 Bible. Wiley, 2009. [6] World Wide Web Consortium (W3C). Speciche uciali HTML. http://www.w3. org/community/webed/wiki/HTML/Specifications. [7] World Wide Web Consortium (W3C). Speciche uciali CSS. http://www.w3. org/Style/CSS/current-work. [8] Wikipedia - The free encyclopedia. JavaScript. http://it.wikipedia.org/wiki/ Javascript. [9] The Ocial Microsoft ASP.NET Site. ASP.NET Web Pages. web-pages. http://www.asp.net/ 86 BIBLIOGRAFIA [10] Wikipedia - The free encyclopedia. jQuery. http://it.wikipedia.org/wiki/ jQuery. [11] Jesse James Garrett. Ajax: A New Approach to Web Applications. http://www. adaptivepath.com/ideas/ajax-new-approach-web-applications. [12] ECMA (European Computer Manufacturers Association). Introducing JSON. http: //json.org. [13] Wikipedia - The free encyclopedia. Amazon Web Services. http://en.wikipedia. org/wiki/Amazon_Web_Services. [14] Data gn Manager Software Online. Videointervista. Novedge, The Desi- http://www.datamanager.it/news/ SuperStore. videointervista-novedge-design-software-superstore-43260.html. [15] Gazzetta di Parma. Da Parma alla leadership negli States. //www.gazzettadiparma.it/primapagina/dettaglio/3/41106/Da_Parma_ alla_leadership_negli_States__.html. http: