Sistem informațional pentru aprecierea calității de deservire în restaurante [303476]
Universitatea Tehnică a Moldovei
Sistem informațional pentru aprecierea calității de deservire în restaurante
QUALITY ASSESSMENT SYSTEM FOR restaurant services
Student: [anonimizat]:
lector universitar Catruc Mariana
Chișinău 2016
Ministerul Educației al Republicii Moldova
Universitatea Tehnică a Moldovei
Facultatea Calculatoare Informatică și Microelectronică
Catedra Automatică și Tehnologii Informaționale
Admis la susținere
Șef de catedră: dr. conf.univ. Ciorbă D.
„__”_____________ 2016
Sistem informațional pentru aprecierea calității de deservire în restaurante
Proiect de licență
Student: (M. Buga )
Conducător: (M. Catruc )
Consultanți: (N. Sava )
( A. Dodu )
(Sv.Cojocaru )
Șef de secție TI (R.Bulai )
Chișinău 2016
Universitatea Tehnică a [anonimizat].conf.univ. Dumitru Ciorbă
șef catedră
„__”_____________ 2016
CAIET DE SARCINI
pentru proiectul de licență al student: [anonimizat]
1. Tema proiectului de licență Sistem informațional pentru aprecierea calității de deservire în restaurante confirmată prin hotărârea Consiliului facultății de la „ 21” octombrie 2015
2. Termenul limită de prezentare a proiectului 31.05.2016
3. Date inițiale pentru elaborarea proiectului Sarcina pentru elaborarea proiectului de diplomă.
4. Conținutul memoriului explicativ
Introducere
1. Analiza domeniului de studiu
2. Proiectarea sistemului
3. Realizarea sistemului
4. Documentarea produsului realizat
5. Argumentarea economică
Concluzii
5. Conținutul părții grafice a proiectului
Diagrama cazurilor de utilizare “ Vederea generală”
6. Lista consultanților:
7. Data înmânării caietului de sarcini 01.09.2015
Conducător
semnătura
Sarcina a fost luată pentru a fi executată
de către student: [anonimizat] 01.09.2015
semnătura, data
PLAN CALENDARISTIC
Student: [anonimizat], [anonimizat], [anonimizat]. Declar că lucrarea nu a mai fost prezentată sub această formă la nici o instituție de învățământ superior în vederea obținerii unui grad sau titlu științific ori didactic.
Semnătura autorului
Semnatura conducătorului de licentă
AVIZ
la proiectul de licență
Tema: Sistem informațional pentru aprecierea calității de deservire în restaurante
Student: [anonimizat](a) Buga Marian gr. TI-122
1. Actualitatea temei: [anonimizat].
2. Caracteristica tezei de licență: Aplicația a fost creată cu scopul micoșărării timpului pentru alegerea unui restaurant ce corespunde așteptărilor consumatorilor după diferite criterii.
3. Analiza sistemului: Sistemul dat este compus din mai multe compartimente. Primul compartiment permite utilizatorilor să se informeze despre restaurantul dorit, al doilea compartiment permite postarea unui comentariu despre calitatea serviciilor oferite de restaurantul vizitat.
4. Estimarea rezultatelor obținute: Sistemul este realizat cu un meniu foarte intuitiv pentru consumator fiind foarte ușor de utilizat.
5. Corectitudinea materialului expus: Materialul expus este prezentat prin referințe ale unor surse ce au fost scrise de persoane ce dețin experiența în domeniul Tehnologiilor Informaționale.
6. Calitatea materialului grafic: Proiectul respectiv este prezentat prin: diagrame, tabele, interfețe ale sistemului.
7. Valoarea practică a tezei: Sistemul dat este destinat tuturor persoanelor ce dețin un dispozitiv cu conectare la internet și cunosc cum să-l utilizeze pentru navigare în internet.
8. Observații și recomandări: Cerințele față de teza de licență au fost îndeplinite în totalitate. Observații nu sunt.
9. Caracteristica studentului și titlul conferit : Studentul Buga Marian a dat dovadă de profesionalism în elaborarea lucrării, a respectat cerințele impuse și a manifestat exigență în elaborarea și calitatea tezei de licență. Din cele relatate, urmează că lucrarea de licență poate fi admisă spre susținere.
Conducătorul
tezei de licență lector superior Catruc Mariana .
(funcția, titlul științific), (semnătura, data), (numele, prenumele)
Rezumat
Teza dată a fost efectuată cu scopul elaborării unui sistem informațional compus dintr-un web site și o aplicație mobilă.
Sistemul dat a fost creat cu scopul de a oferi posibilitatea oamenilor simpli de a alege un loc bazîndu-se pe comentariile oamenilor care au vizitat acele restaurante anterior și au lăsat un cmentariu despre condițiile de deservire și tot o dată ei vor avea la îndemînă informațiile generale despre restaurant: orele de lucru, amplasare, menu ect, și îsi vor putea exprima mulțumirea sau nemulțumirea față de un restaurant lăsînd un comentariu.
În procesu de elaborare a sistemului au fost analizate mai multe sisteme asemănătoare și au fost stabilite punctele tari care au fost implimentate ulterior in proiect cu unele îmbunătățiri.
Cuvintele cheie sunt: comentariu, review, restaurant, proiectare, programare orientată pe obiecte.
în primul capitol sunt descrise aspecte generale ale sistemului, funcționalul;
al doilea capitol descrie modelarea sistemului;
capitolul trei descrie elaborarea sistemului propriu zis;
capitolul patru descrie cum să folosim acest sistem;
capitolul cinci analizează sistemul din punct de vedere economic, dacă este rentabilă, ce riscuri sunt, ce resurse sunt necesare.
Abstract
Dissertation was performed for developing an information system consists of a website and a mobile application.
This system was created in order to enable ordinary people to choose a place relying on the comments of people who have visited those restaurants before and left a review about conditions of service, they will have access to general information about restaurant: hours of operation, location, menu, and may express their satisfaction or dissatisfaction to a restaurant leaving a comment.
In development phase of the system were analyzed several similar systems, were established strengths, have been implementing in this project with some improvements.
Keywords are: review, restaurant, design, object-oriented programming.
the first chapter describes the general aspects of system functionality;
the second chapter describes the system modeling;
chapter three describes the development phase of the system;
chapter four describes how to use this system;
chapter five analyzes the economic system, if it is profitable, what risks are, what resources are used.
Introducere
Prezenta lucrare reprezintă suportul teoretico-practic al proiectului de diplomă cu tema “Sistem informațional pentru aprecierea calității de deservire în restaurante”. Tematica și conținutul proiectului vine în întâmpinarea cerințelor curente de pe piața produselor software care îmbunătățesc viața oamenilor de rând în fiecare zi.
Pentru aceasta va fi creată un sistem care va permite oamenilor simpli de a alege un local cu condițiile cele mai bune reieșind din evaluările altor utilizatori care au vizitat acest local și condițiile care îl vor satisface pe utilizator, așa ca amplasarea dorită, meniul dorit orele dorite precum și multe alte. Pentru utilizatorii care vor veni în vizită din alt oraș sau chiar din altă țara va permite de a găsi restaurante tematice și va permite să nu fie dezamăgiți. Iar pentru administratorii de restaurante, acest sistem va fi ca o legătura cu clienți și va permite de a corecta sau îmbunătăți serviciile și calitate de deservire.
Vom urmări toți pași necesari de a crea un sistem informațional, descrierea lui și evaluarea economică. Urmînd pas cu pas aceasta lucrare cititorul va putea înțelege cum se creaza o soluție software, va arăta sumarul cunoștințelor autorului în urma studiilor la universitate tehnică și va putea înțelege cum de creat o aplicație calitativă, cu un potențial mare și bazînduse pe tehnologii corecte care vor permite de a economisi timp la creare și suport în viitor. Deasemenea se vor prezenta cunoștințele în area de programare care au fost acumulate pe perioada învățămîntului, și cunostințele în area viziunii economice asupra proiectului îndeplenit.
1 Analiza domeniului de activitate
Pentru a putea crea un sistem informațional de nivel înalt este nevoie de a defini corect toate funcțiile care el trebuie să le execute, care sunt cerințele funcționale sau nefuncționale. A fost pus scop de a crea un sistem care va permite utilizatorilor să aprecieze calitate de deservire în restaurantele din Republica Moldova. Pentru a defini cerințele față de acest sistem este nevoie de a căuta și studia sistemele similare, de le analizat pe acestea, de a extrage din ele punctele tari, de a identifica punctele slabe și de a împlini setul de funcționalități care lipsesc. Cu ajutorul motoarelor de căutare au fost inditificate principalelii concurenți care sunt prezentațî în lista de mai jos:
foursquare.com;
yelp.com;
tripadvisor.com.
1.1 Reprezentarea site-ului fourscare.com
Pe pagina principală (figura 1.1) a acestui site putem vedea lista de restaurane despre care știe aplicația și notele cu care sunt apreciate aceste restaurante de către utilizatori. Deasemenea este posibil de a vedea amplasarea acestui restaurant pe harta. Acest lucru va permite căutarea unui restaurnat cît mai aproape de locul de aflare a utilizatorului.
Figura 1.1 – Pagina de start fourscare.com
Deasemenea deasupra listei de restaurante este un filtru rapid care va permite afișarea restaurantelor după anumite criterii cum ar fi:
să fie arătate numai restaurantele care i-au plăcut utilizatorului;
să fie sortate după nivelul de prețuri;
să fie arătate numai restaurante ce sunt deschise la momentul căutării;
să fie arătate restaurante în care utilizatorul a mai fost sau invers nu a vizitat niciodată.
Pentru a vedea mai multă informație despre un restaurant utilizatorul poate apăsa unul din restaurante. În figura 1.2 este arătat cum arată aceste detalii. Din ele putem obține informație ca:
tipuri de meniu ce se deservesc în restaurant;
ce tipuri de băuturi se servesc;
dacă sunt prezente servicii adiționale ca Wi-Fi sau prezența terasei;
orele de lucru al acestui restaurant;
fotografiile și adresa restaurantului;
descrierea generala a restaurantului;
cîteva funcții de înștiințare și distribuire a datelor despre acest restaurant în rețele de socializare.
Figura 1.2 – Detalii despre un restaurant
Deasemenea aplicația permite de a vizualiza informația care au indicat utilizatorii ce au vizitat acest restaurant. Acest lucru este arătat în figura 1.3. Din ea vedem că utilizatorii cu plăcere în afară de notă lasă și comentariile cu care argumentează nota pusă. Utilizatorul poate indica nota, comentariul și chiar lăsa o fotografie. Altor utilizatori li se permite de a salva unul din comentarii sau a împărtăși unul din comentarii în rețele de socializare.
Figura 1.3 – Comentariile utilizatorilor despre un restaurant
1.2 Reprezentarea site-ului yelp.com
Acest site oferă deasemenea anumite servicii de căutare și afișarea datelor despre restaurante. Cu părere de rău sunt prezente date despre restaurante din america de nord și cea latina, în schimb datele despre restaurante sunt mai bine controlate și revizuite. Pagina principală al acestui site este prezentat în figura 1.4. Chiar din start site-ul ne permite de a căuta restaurante dupa locul și denumire sau grupa din care face parte un restaurant. Deasemenea sunt prezente filtrele ce sunt prezente și în site-ul descris mai inainte și anume:
sortări după prețurile;
afișări la restaurante ce sunt deschise la moment;
să fie afișate numai restaurante din care poți comanda mîncare direct acasă;
să fie afișate numai restaurante unde poți face rezervări.
Figura 1.4 – Pagina de start Yelp
Deasemenea pe pagina principală sunt arătate locațiile restaurantelor pe harta. Și însăși lista de restaurante în formă generală. Dacă este necesar de văzut mai multe detalii despre un restaurant este nevoie de a apăsa pe el. Rezultatul îl putem vedea în figura 1.5.
Figura 1.5 – Detalii despre un restaurant
Aici putem vedea informația ca:
adresa și telefoane de contact al restaurantului;
amplasare pe harta;
datele despre meniu;
inspectare igienica;
comentariile utilizatorilor.
Deasemenea sunt prezente butoane care vor permite utilizatorului de a adăuga fotografiile și comentariile dacă ați vizitat acest restaurant și doriți să faceți o apreciere publică.
Reprezentarea site-ului tripadvisor.com
Pagina principală acestui site este prezentată în figura 1.6. Acest site ca și cele precedente are deasemenea un fitru, dar în cazult acestui site – un filtru mult mai avansat, dar în acelați timp mai greu de utilizat. Deasemenea este posibil de a vedea date generale despre un restaurant și amplasarea restaurantelor pe harta.
Figura 1.6 – Pagina de start tripadvisor.com
În figura 1.7 este arătat modul de afișare a dateler despre un restaurant. Sunt arătate fotografiile de bază despre acest restaurant și comentariile utilizatorilor. Toate sunt amplasate într-un format ușor de utilizat. Deasemenea este posibil de a împărtăși detalii despre acest restaurant în rețele de socializare.
Figura 1.7 – Datele despre un restaurant
1.4 Definirea problemei
În urma analizei siturilor ce au același scop cu cel propus în această lucrare au fost identificate punctele lor slabe și cele puternice. Este clar că funcțional site-ul creat trebuie să indeplinească urmatoarele funcții fără care nu este posibil de obținut rezultatul dorit:
să fie prezentă căutare;
să fie prezente anumite filtre care vor permite utilizatorului de a găsi repede un restaurant care îi va convine;
afișarea localurilor pe harta;
posibilitate de a afișa lista de restaurante într-o forma scurtă pentru revizuirea rapidă;
posibilitate de prezentare a detaliilor despre un restaurant;
posibilitate de a permite utilizatorilor de a vedea comentariile altor utilizatori și de a adăuga cele personale.
Deasemenea este nevoie de luat în calcul și cîteva cerințe nefuncționale dar fără care utilizatorii nu vor avea placere să lucreze cu aplicația creată:
simplicitate în utilizare;
design impecabil;
viteza sporită;
client mobil.
2 Modelarea și proiectarea sistemul informatic
Pentru a modela un sistem informațional și pentru a obține soluția corectă este necesar de a proiecta aplicația, de a defini cereri fundamentale, de a identifica funcțiile principale și de a defini modul de utilizare al aplicației. În industria calculatoarelor pentru efectuarea proiectărilor se utilizează limbajul UML.
UML nu este un simplu limbaj de modelare orientat pe obiecte, ci în prezent, este limbajul universal standard pentru dezvoltatorii software din toata lumea. UML este succesorul propriu-zis al celor mai bune trei limbaje de modelare anterioare orientate pe obiecte (Booch, OMT, si OOSE). UML se constituie din unirea acestor limbaje de modelare și în plus deține o expresivitate care ajută la rezolvarea problemelor de modelare pe care vechile limbaje nu o aveau. Notațiile UML constituie un element esențial al limbajului pentru realizarea propriu-zisă a modelării și anume partea reprezentării grafice pe care se bazează orice limbaj de modelare. Modelarea în acest limbaj se realizează prin combinarea notațiilor UML în cadrul elementelor principale ale acestora denumite diagrame. O diagramă oferă utilizatorului un mijloc de vizualizare și de manevrare a elementelor de modelare. Majoritatea diagramelor se prezintă sub forma unor grafuri, compuse din elemente și arce. Diagramele pot arăta o parte sau toate caracteristicile elementelor de modelare, conform nivelului de detaliu util în contextul unei diagrame de date. Diagramele pot grupa informații interdependente, pentru a arăta, de exemplu caracteristicile moștenite de o clasă. În cadrul UML-ului descoperim 9 tipuri de diagrame: diagrama cazurilor de utilizare, diagrama de secvență, diagrama de clase (cea mai utilizată), diagrama de obiecte, diagrama de activități, diagrama de colaborare, diagrama de stări, diagrama de componente, diagrama de construcție. Diagramele de colaborare împreună cu cele de secvență se numesc diagrame de interacțiune pe cînd diagramele de stare mai sunt denumite mașini cu stări finite, automate, etc. UML definește un mic număr de mecanisme comune care asigură integritatea conceptuală a notațiilor. Aceste mecanisme comune cuprind:
stereotipurile – specializează clasele meta modelului;
etichetele – extind atributele claselor meta modelului;
notele;
constrîngerile – extind semantica meta modelului;
relația de dependență;
dualitățile (tip , instanță) și (tip , clasă).
2.1 Diagrama cazurilor de utilizare
Modelarea vizuală în UML poate fi reprezentată ca un oarecare proces de lansare pe niveluri de la cel mai general și abstract model conceptual al sistemului inițial către model logic și mai apoi fizic, ce corespunde unui sistem de program. Pentru atingerea acestui scop de la început se crează un model în formă de diagarama cazurilor de utilizare (use case diagram) care descrie destinația functională a sistemului sau cu alte cuvinte descrie ceea ce sistemul va executa în procesul său de funcționare. Diagrama cazurilor de utilizare reprezintă un model inițial conceptual al unui sistem în procesul de proiectare și exploatare.
O diagramă a cazurilor de utilizare prezintă o colecție de cazuri de utilizare și actori, și este folosită în general pentru a indica sau caracteriza funcționalitățile și comportamentul intregii aplicații a sistemului interacționînd cu unul sau mai mulți actori. Utilizatorii și orice sistem ce poate interacționa cu sistemul sunt actori. Atît timp cît actorii reprezintă utilizatorii, ei ajută la delimitarea sistemului și oferă o imagine clară a ceea ce se asteaptă să se întîmple în sistem. Cazurile de utilizare sunt construite pe baza nevoilor pe care le au actorii. Aceasta asigură faptul ca sistemul va produce ceea ce s-a dorit.
Diagramele cazurilor de utilizare conțin elemente ce pot reprezenta actori, relații de asociere, relații de generalizare, pachete și cazuri de utilizare. Se poate crea o diagramă a cazurilor de utilizare de nivel înalt, pentru a vizualiza limitele și comportamentul sistemului. De asemenea, se pot crea una sau mai multe diagrame pentru a descrie o parte a aplicației sistemului. Cazurile de utilizare pot include alte cazuri de utilizare ca o parte a comportamentului sau. O diagramă a cazurilor de utilizare indică un set de actori externi și cazurile de utilizare ale sistemului în care participă respectivii actori.
Un actor este un stereotip al unei clase. Utilizatorii și orice sistem care poate interacționa cu sistemul în chestiune sunt actori. Astfel, un actor reprezintă un rol jucat de o persoană sau o entitate care interactionează cu sistemul.
Cum actorii reprezintă utilizatorii sistemului, ei ajută la delimitarea sistemului și oferă claritate în ceea ce se va întîmpla în respectivul sistem.Aceeași persoană fizică poate juca rolul mai multor actori, așa cum și mai multe persoane pot juca același rol, și astfel interacționa că același actor.
Fiecare actor trebuie să aibă un nume, iar numele acestuia descrie rolul jucat de către actor. În diagrama cazurilor de utilizare se pot desena asocieri de la actor la cazul de utilizare sau generalizări între actori. O asociere reprezintă o conexiune semantică între cazurile de utilizare și actori. Asocierile sunt unidirectionale; ele sunt relațiile cele mai generale și cele mai slabe din punct de vedere semantic.
O asociere poate avea nume și un stereotip care să identifice tipul sau semnificația relației. Relațiile de asociere se pot desena între cazuri de utilizare și actori. Fiecare apariție a unei asocieri în diagrama etalează un set de informații ale modelului despre relația de asociere în cauză, aceste informații fiind cuprinse în specificațiile asocierilor.
O generalizare între două cazuri de utilizare indică faptul următor: cazul de utilizare poate împărtăși comportamentul definit în unul sau mai multe cazuri de utilizare. De asemenea, generalizarea suportă utilizatori și extinde stereotipuri. O generalizare între actori arată că un actor moștenește structura și comportamentul al unui actor sau mai mulți actori.
Se foloseste numele relației și a stereotipului pentru a identifica tipul sau semnificațiile relației respective. Se pot desena relații de generalizare între cazuri de utilizare și actori. Apariția unei generalizari în cadrul unei diagrame indică un set de informații ale modelului despre relația de generalizare. Aceste informații reprezintă specificațiile generalizarii.
În figura 2.1 vedem diagrama cazurilor de utilizare a sistemului informațional propus care arată vedere generală asupra aplicației. Din această diagramă vedem că sistemul permite cîteva funcții principale ce au fost defenite la stagiul de studiu al domeniului:
persoana va putea căuta un restaurant;
persoana va putea filtra lista de restaurante conform unor parametri;
persoana va putea obține informații generale despre un restaurant;
persoana va putea obține informații detaliate despre un restaurant;
persoana va putea aprecia calitate de deservire în restaurantul în care a fost deservit.
Figura 2.1 – Diagram Use Case vederea generală
În figura 2.2 se arată cum va avea loc căutarea unui restaurant:
utilizatorul va putea indica denumirea restaurantului;
utilizatorul va putea indica locația unde este nevoie de căutat un restaurant;
utilizatorul va putea căuta restaurante care sunt în apropierea utilizatorului.
Figura 2.2 – Căutarea restaurantelor
În figura 2.3 sunt arătate modurile în care poate fi filtrată lista de restaurante după ce au fost arătate utilizatorului în urma căutării. Din aceasta figură vedem că utilizatorul poate indica:
nivelul de prețuri în restaurant;
să fie eliminate restaurantele ce nu sunt deschise la ora dată;
să fie arătate numai acelea restaurante în care este posibil de programat vizita;
să fie arătate numai restaurante ce au fost vizitate sau invers ce nu au fost vizitate de utilizator;
să fie arătate numai acelea restaurante ce au o nota medie anumită sau mai sus, ce reiese din evaluările altor utilizatori ce au vizitat acest restaurant.
Figura 2.3 – Filtrarea listei de restaurante
În figura 2.4 este detaliezată funcția de obținere a informației generale despre un restaurant. Din ea vedem că utilizatorului i se arată:
denumirea restaurantului;
nota medie a restaurantului (reieșind din evaluările al altor utilizatori);
adresa restaurantului;
datele de contact al restaurantului precum numărul de telefon, adresa web și adresa de e-mail;
fotografia generală despre un restaurant.
Figura 2.4 – Afișarea datelor generale despre un restaurant
În figura 2.5 sunt prezentate funcțiile care sunt oferite de sistem utilizatorului pentru a afla mai multă informație despre un restaurant:
afișarea detaliilor va include in ea afișarea datelor ce sunt afișate de asemenea și când se arată informația generală;
se vor afișa comentariile utilizatorilor;
se vor afișa răspunsurile administratorilor la comentariile utilizatorilor;
se vor afișa datele despre băuturile prestate în restaurant;
se vor afișa datele despre mâncare care se deservește la restaurant;
se vor afișa toate fotografiile ale restaurantului pentru a permite utilizatorului de a vedea mai bine anturajul restaurantului;
de asemenea se va arăta descrierea detaliată despre restaurantul dorit.
Figura 2.5 – Afisarea detaliată despre un restaurant
Pentru a afișa un comentariu de la utilizator sistemul informațional va presta funcțiile ce sunt arătate în figura 2.6:
afișarea fotografia utilizatorului;
afișează comentariul utilizatorului;
afișează nota media ce a pus utilizatorului la restaurantul dat;
posibilitate de împărtăși comentariul în rețele de socializare.
Figura 2.6 – Afișarea comentariului a unui utilizator
În figura 2.7 sunt arătate funcțiile necesare pentru a lăsa un comentariu și anume:
posibilitate de indica nota pe diferite parametri ca prețuri, calitatea produselor și calitatea deservirii;
posibilitate de a indica un comentariu in forma unui text;
de a indica fotografiile care vor argumenta comentariul.
Figura 2.7 – Plasarea unui comentariu
2.2 Diagrame de secvența
Pentru modelarea procesului de executare a operațiilor în limbajul UML se utilizează așa numitele diagrame de activități. Notația grafica acceptată pentru aceste diagrame are mult comun cu notația diagramei de stări ce se evidențiază prin notarea stărilor și tranzițiilor. Deosebirea constă în semantica stărilor care sunt utilizate pentru prezentarea acțiunilor dar nu activităților, și în aceea că tranzițiile evenimentelor nu sunt etichetate. Fiecare stare în diagrama de activități corespunde executării unei operațiuni elimentare, dar trecere în altă stare se execută numai la terminarea operației în starea precedentă. Grafic diagrama de activități se reprezintă în forma unui graf de activitate cu nodurile – stări activitate și muchile – tranziții de la o stare la altă. Diagramele de secventă reprezintă interacțiunile între obiecte din punct de vedere temporal, contextul obiectelor, nefiind reprezentat în mod explicit ca în diagramele de colaborare, reprezentarea concentrîndu-se pe exprimarea interacțiunilor.
O diagramă de secvență reprezintă o interacțiune între obiecte insistînd pe cronologia (ordinea temporală) a expedierii mesajelor la Obiecte.
Liniile de viața sunt elemente ce caracterizează diagramele de secvență. O linie de viață a unui obiect poate fi considerată ca axa timpului pentru diagrama de secvență.
Astfel, ordinea cronologică a expedierii mesajelor este dată de poziționarea lor pe aceste axe (linii de viață). În diagramele de secvență mesajele se reprezintă prin săgeți plasate între liniile de viață ale obiectelor în ordinea lor cronologică. Formele de sincronizare a mesajelor descriu natura mecanismelor de comunicație care permit trecerea mesajelor de la un obiect la alt obiect. Noțiunea de sincronizare are obiect atunci cînd mai multe obiecte sunt active simultan și este necesară protejarea accesului la obiecte partajate. Noțiunea de sincronizare precizează natura comunicației și regulile care conduc trimiterea mesajelor. Există 5 mari categorii de trimiteri de mesaje: simplu, sincron, condițional, întîrziat, asincron.
În figura 2.8 putem vedea așa un exemplu de diagrama. Ea ne prezintă cum se realizeaza căutarea unui restaurant de utilizator.
Figura 2.8 – Procesul de căutare a unui restaurant
În primul rînd utilizatorul va indica datele necesare pentru a căuta un restaurant, fie denumire, fie locația unde se află un restaurant sau chiar datele pot fi combinate pentru rafinarea căutării. Toate aceste date sunt trimise în aplicația web și ea la rîndul ei crează o selecție din baza de date. După ce a fost obținut rezultatul de pe serverul bazei de date, lista primită este afișată utilizatorului. În caz cînd utilizatorul va indica și anumite filtre după ce a fost afișat rezultatul căutării, pentru a salva numarul de chemări la serverul de baza de date și pentru a mări timpul de prelucrare a cererilor de la utilizator, se va filtra direct lista ce a fost obținută din baza de date în primul pas.
În figura 2.9 este prezentat procesul de pas cu pas de afișare a detaliilor despre un restaurant. Utilizatorul trimite id-ul restauranului la pagina web, care la rîndul ei trimite selectări speciale pentru a găsi datele necesare, inclusiv detalii generale, informația detaliata, lista de comentarii a utilizatorilor și lista de fotografii care descriu restaurantul dat.
După ce au fost obținută toată lista de informații din baza de date, se creează pagina cu toată această informație și se trimite către utilizator ca rezultat final care descrie complet un restaurant și permite utilizatorului de a înțelege în ce constă restaurantul.
Figura 2.9 – Afisarea detaliilor despre un restaurant
În figura 2.10 se arată procesul de plasarea unui comentariu de către utilizator despre un restaurant. Pentru a efectua acest lucru este necesar de a fi logat în sistem. După ce utilizatorul se logheaza in baza de date utilizatorul va trimite datele necesare și acestea vor fi salvate în baza de date. La sfîrșit utilizatorul va primi înștiințare despre salvarea comentariului in sistem.
Figura 2.10 – Adăugarea unui comentariu
2.3 Diagrame de stare
Diagramele de stari reprezinta vizual automatele cu numar finit de stări, din punctul de vedere al stărilor și tranzițiilor. O diagrama de stare este utilizată pentru a reprezenta stările unei clase date, evenimentele ce cauzează tranzițiile de la o stare la alta, și acțiunile care rezultă din schimbările stărilor.
Fiecare diagrama este asociată unei clase sau unui nivel mai inalt din diagrama de stare. O diagramă de stare este un graf bazat pe stări conectate prin tranziții. O diagramă de stare descrie o istorie a vieții obiectelor sau clasei date.
O diagrama de stare prezintă o singură stare inițială, una sau mai multe stări, una sau mai multe stări finale și tranzițiile între stări. Fiecare clasa din modelul curent ce are un comportament semnificativ în ceea ce privește evenimentele ordonate, poate conține o singură diagramă de stare pentru a descrie acest comportament. O specificație de stare poate indica și modifica proprietățile unei stări. Informațiile privind specificațiile stării sunt prezentate textual și în plus, pot apărea în desenul respectivei stări în reprezentarea diagramei de stare. Dacă modificăm în cadrul specificațiilor, proprietațile stării, atunci diagramele de stare se vor actualiza reflectînd aceste schimbări. Starea unui obiect reprezintă istoria cumulativa a comportamentului respectivului obiect. Starea acoperă toate proprietățile statice ale obiectului și valorile curente pentru fiecare proprietate. Toate instanțele ale aceleiași clase există în aceeași stare.
Numele unei stări trebuie sa fie unic in clasa pe care o descrie, sau dacă este imbricată unei stări, în interiorul acesteia. Actiunile dintr-o stare pot exista la unul din cele patru momente:
(on) entry (acțiune ce se execută la intrarea dintr-o stare);
(on) exit (acțiune ce se execută la ieșirea dintr-o stare);
on an activity (on event, on:) (acțiune executată la apariția unui eveniment);
upon event.
Acțiunea 'upon event' va fi similară cu tranzacție de stare avînd următoarea sintaxă: event(args)[condiție]: acțiunea upon event este diferită de autotranziție (tranziția unei stări la ea însăși). O autotranziție execută alte acțiuni 'entry' și 'exit', în timp ce o acțiune 'upon event' poate fi privită ca un eveniment intern care nu declanșează orice alte acțiuni.
Acțiunile sunt de două feluri:
simple: sunt texte simple. Textul reprezintă tot ce dorim să se întâmple când se produce un eveniment;
care trimit evenimente: sunt acțiuni care declanșează alt eveniment.
O stare initială este o stare specială care ne indică în mod explicit inițializarea mașinii cu stări. Starea inițială se conectează primei stări normale printr-o tranziție neetichetată. Intr-o diagramă de stare putem avea exact o stare inițială. Cînd folosim stări imbricate, trebuie să definim cîte o stare inițială în fiecare context. În general, doar o tranziție poate pleca din starea initială. Totuși, tranzițiile multiple pot fi atașate stării inițiale dacă măcar una dintre ele este etichetată cu o condiție. Nu se admit tranziții care nu vin dintr-o stare. Starile inițiale se pot eticheta dacă se dorește. Specificațiile stărilor sunt asociate fiecărei stări inițiale.
O stare finală reprezintă stare de final (terminală) a unui sistem. Aceasta se folosește în diagrama de stare cînd vrem să arătăm explicit finalul mașinii cu stări. Tranzițiile pot doar să existe în starea finală; odată ce mașina cu stări se sfîrșește, ea dispare. În mod normal, ne putem asigura ca mașina cu stări asociată unei clase nu va mai exista atunci cînd obiectul referit în aceasta este distrus și, de aceea, niciodată nu ajunge într-o stare finală. Totuși, putem folosi o stare finală pentru a arăta explicit finalul, dacă este necesar. Într-un context pot exista un număr nedefinit de stări finale.
În figura 2.11 este arătat procedeul prin care utilizatorul este autentificat în sistem și să fie apt de utilizare a sistemului în întregime. În primul rînd utilizatorul va decide cum va dori să se autentifice în sistem. Sunt două moduri de autentificare – facebook sau autentificare locală. Ca rezultatul autentificării utilizatorul va obține un identificator care va fi atribuit la conexiunea care o are la moment cu sistem și pe baza lui se vor executa funcțiile și se vor decide permisiuni.
Figura 2.11 – Autentificare in sistem
În figura 2.12 este arătat procedura de înregistrare a unui utilizator în sistem. Pentru aceasta utilizatorul va decide modul în care va dori să se autentifice în sistem. Pentru aceasta sistemul îi va oferi două modalități de înregistrare:
înregistrare locală;
înregistrarea cu ajutorul facebook.
Dacă utilizatorul va alege modul de înregistrare local, utilizatorul va trebui să întroducă datele personale precum nume, prenume, telefon, email, etc. de mîna, iar dacă va alege să fie înregistrat cu ajutorul rețelei de socializare facebook, toate date personale vor fi luate de acolo. Unica ce va trebui de făcut în ambele cazuri e de întrodus numele de utilizator și parola. După ce au fost introduse toate datele, ele for fi salvate ca mai ulterior să fie posibil de autentificat în sistem printr-unul sau altul mod.
Figura 2.12 – Înregistrare în sistem
2.4 Diagrama claselor
În figura 2.16 vedem diagrama claselor al componentei OrmComponents. Din aceasta diagrama vedem că clasele principale ale sistemului care și construiesc scheletul sistemului final sunt:
PersonDTO – clasa care descrie o persoana în general și conține date cum ar fi numele, prenumele, etc;
PersonDetailsDTO – clasa care conține informația detaliată despre o persoana;
RatingDTO – clasa care va conține date privind o apreciere din partea unei persoane;
RatingDetailsDTO – clasa care conține date privind scorul mediu a tuturor aprecierilor;
RestaurantDTO – identifică un restaurant și conține date generale despre un restaurant;
RestaurantDetailsDTO – permite utilizatorilor să obțină mai multe date despre un restaurant.
Figura 2.13 – Diagrama claselor principale
2.5 Diagrama de componente
Diagramele de componente descriu elementele fizice (hardware) și relațiile lor în mediul de implementare. Diagramele de componente arată opțiunile privind implementarea.
Componentele sunt derivate din următoarele elemente Booch: programe principale, module, subprograme și procese. Fiecare diagramă de componente descrie modelul din punct de vedere fizic. Diagramele de componente conțin următoarele elemente:
subsisteme;
componente:
programe principale;
module;
subprograme;
procese;
dependente.
Se pot crea una sau mai multe diagrame de componente pentru a descrie subsistemele și componentele la nivelul de top al modelului curent; unele diagrame de componente sunt conținute chiar ele în nivelul de top al modelului. De asemenea, se pot crea diagrame de componente pentru a arăta subsistemele și componentele conținute în fiecare subsistem al modelului curent; unele diagrame de componente pot fi chiar ele conținute de subsistemele care cuprind subsistemele și componentele care le descriu. Specificațiile subsistemelor și cele ale componentelor permit prezentarea și modificarea proprietăților acestora. Informația în aceste specificații este prezentă textual, o parte din această informație putînd apărea în simbolurile grafice ale subsistemelor sau componentelor. Dacă modificăm proprietățile subsitemelor sau componentelor în cadrul specificațiilor acestora, se vor actualiza toate diagramele de componente care includ aceste elemente. Dacă modificările au loc în cadrul unei diagrame, actualizarea se va face în specificațiile subsistemelor sau componentelor sau orice altă diagramă care conține diagrama modificată. Modulele reprezintă toate tipurile de elemente fizice care intra în construcția aplicațiilor informatice. Ele sunt constituite dintr-un modul specificație (interfață) și un modul implementare; modulul implementare este adesea referit ca un corp.
Fiecare modul trebuie să aibă un nume. De obicei, numele modelului este un nume simplu de fisier. Modulele cu același nume și de același tip reprezintă aceeași componenta a modelului, indiferent de diagrama de compoente în care apare. De exemplu, două module specificație cu același nume reprezintă de fapt același modul, în timp ce un modul corp avînd același nume cu cele două specificații reprezintă o componentă a modelului separat. Relațiile de dependență sunt utilizate în diagramele de componente pentru a indica faptul că o componentă folosește serviciile sau facilitățile oferite de altă componentă. Acest tip de dependență este reflectarea opțiunilor de implementare. Relația de dependență poate fi specializată printr-un stereotip pentru a preciza natura opțiunilor de implementare care conduc la relația de dependență. În diagrama de componente, relațiile de dependență reprezintă în general dependențe de compilare, ordinea compilării fiind dată de graful relațiilor de dependență. Procesele corespund componentelor care dețin propriul lor flux de control. Dacă procesele sunt compilate diferit decît modulele obișnuite, se poate aloca definirea unei clase, unui proces. Ca și celelalte elemente ale diagramei de componente și procesele sunt: procese specificație și procese corp. Fiecare proces trebuie să aibă un nume. În general, numele unui proces este un simplu nume de fișier. Procesele cu același nume și același tip reprezintă aceeași componentă din model indiferent de diagrama de componente în care apare. De exemplu, două procese specificație cu același nume reprezintă același proces specificație, în schimb ce un proces corp avînd de asemenea același nume reprezintă o componentă separată din model.
În figura 2.13 putem vedea din ce componente este construit sistemul creat. Componenta care face legătura directă cu baza de date este .NET Entity Framework. Ea prestează anumite interfețe prin care componenta Owin răspunde de logare și autentificare în sistem al utilizatorilor, iar componenta OrmComponents permite a scrie în baza de date informația ce este păstrată în baza de date despre restaurante. Componenta Website Package este de fapt pagina web care va permite utilizatorului de a interacționa cu sistemul prin pagina web. Iar toate sunt coordonate de componenta webapi package care presteaza api functii care permite obținerea sau înscrierea datelor după anumite reguli. Mobile client este defapt o componenta care va prezenta aplicația care va rula pe telefoane mobile ca utilizatorul să fie apt de a utiliza sistemul informațional creat cu ajutorul gadgetelor personale.
Figura 2.14 – Componentele principale ale sistemului creat
2.6 Diagrama de amplasări
Diagrama de amplasare reprezintă poziționarea fizică în rețea a diferitor componente ale sistemului. Elementele acestei diagrame sînt legate între ele prin relații de asociere. Procesul de lucru care leagă utilizatorul de baza de date este destul de complex, însă redarea lui grafică prin diagrama din Fig. 2.15 ne permite să vizualizam prin ce puncte importante trece informația si anume:
Vizualizare;
Introducere;
Prelucrare;
Salvare.
În figura 2.15 este prezentat modelul de amplasare a componentelor sistemului pe dispozitive implicate în sistem.
Figura 2.15 – Dispozitivele ale sistemului
2.7 Diagrama bazei de date
În acest capitol este proiectată diagrama care reprezintă baza de date utilizată de sistemul informațional. Diagrama bazei de date poate include tabele, coloane, chei primare, chei străine, relații de identificare, relații fără identificare, view-uri, proceduri stocate sau domenii (stereotipizate corespunzător). Pentru a construi diagrama bazei de date va trebui parcurs un proces de mapare a modelului logic obiectual (extragerea din diagramele de clase acele clase ale căror obiecte vor deveni persistente) cu un model logic ce poate fi portat într-o baza de date obișnuita. Modelele bazelor de date actuale suportă în general următoarele paradigme:
modelul relațional;
modelul relațional obiectual;
modelul obiectual.
Maparea modelului obiectual din UML într-un model relațional implementabil într-o baza de date presupune implementarea identității, domeniilor, claselor, asociațiilor și relațiilor de generalizare. O importantă parte a problemelor de mapare au fost rezolvate o dată cu definirea principiilor de mapare din E/R în relaționale în special în ceea ce privește asociațiile dar chiar și relațiile de generalizare pentru modelul E/R extins.
Figura 2.16 – Diagrama bazei de date
3 Realizarea sistemului
Sistemul informațional care va fi creat urmează să permită utilizatorilor de a căuta restaurante, să aleagă un restaurant pentru o odihnă placută bazînduse pe evaluările altor utilizatori al sistemului ce au fost în acel local, iar la rîndul social – sistemul va permite îmbunătățirea calității de deservire în restaurantele publice din țară. După ce a fost stabilit scopul principal al aplicației și au fost evedențiate principale funcții care va realiza sistemul este nevoie de a identifica baza de instrumente și tehnologii ce vor fi folosite pentru realizarea produsului final. În urma studiilor au fost selectate tehnologiile de la compania Microsoft ca una buna pentru realizarea sistemului repede și calitativ.
3.1 Visual Studio 2015 Community Edition
Microsoft Visual Studio este un mediu de dezvoltare integrat (integrated development environment – IDE) de la Microsoft. Acesta poate fi folosit pentru a dezvolta aplicații consolă, aplicații cu interfață grafică pentru toate platformele suportate de Microsoft Windows (ex. .NET Framework, Windows Mobile etc) și aplicații Web (ASP.NET, ASP.NET MVC, etc.). Acest mediu include un set complet de instrumente de dezvoltare pentru generarea de aplicații ASP.NET, Servicii Web XML, aplicații desktop și aplicații mobile. Visual Basic, Visual C++, Visual C# și Visual J# toate folosesc același mediu de dezvoltare integrat (IDE) care le permite partajarea instrumentelor și facilitează crearea de soluții folosind mai multe limbaje de programare. Aceste limbaje permit să beneficieze de caracteristicile .NET Framework care oferă acces la tehnologii cheie care simplifica dezvoltarea de aplicații web ASP și XML Web Services cu Visual Web Developer.
Visual Studio dispune de un editor complex de cod, care se folosește pentru crearea, modificarea și depanarea codului aplicației (poate fi vorba de cod Visual Basic.NET, Visual C#.NET etc.). De asemenea, oferă un set de obiecte și instrumente cu ajutorul cărora se pot realiza cu ușurință interfețe cu utilizatorul pentru Windows, Web, servicii WEB etc. O facilitate a editorului de cod din pachetul Microsoft Visual Studio, foarte utilă programatorilor, este „IntelliSense”. Aceasta implementează autocompletarea codului scris de programator (prin combinația de taste CTRL+Spațiu, sau în diverse momente ale scrierii codului sursă), servind de asemenea ca documentație pentru numele variabilelor, funcțiilor, metodelor etc.
Pentru a îmbunătăți viteza de lucru cu Visual Studio au fost folosite următoarele îmbunătățiri (addons):
Visual SVN – o componenta pentru utilizarea SVN direct din interfața a mediului de dezvoltare;
DevExpress CodeRush – o componenta care îmbunătățește intellisense și are un set de șabloane de coduri pentru a mări viteza de scrierea codului care se folosește des.
3.2 .NET Framework și Limbajul C#
Numele limbajului C# a fost inspirat din notația ♯ (diez) din muzică, care indică faptul că nota muzicală urmată de ♯ este mai înaltă cu un semiton. Este o similitudine cu numele limbajului C++, unde ++ reprezintă atât incrementarea unei variabile cu valoarea 1, dar și faptul că C++ este mai mult decât limbajul C.
Limbajul C# a fost dezvoltat în cadrul Microsoft. Principalii creatori ai limbajului sunt Anders Hejlsberg, Scott Wiltamuth și Peter Golde. Prima implementare C# larg distribuită a fost lansată de către Microsoft ca parte a inițiativei .NET în iulie 2000. Din acel moment, se poate vorbi despre o evoluție spectaculoasă. Mii de programatori de C, C++ și Java, au migrat cu ușurință spre C#, grație asemănării acestor limbaje, dar mai ales calităților noului limbaj. La acest moment, C# și-a câștigat și atrage în continuare numeroși adepți, devenind unul dintre cele mai utilizate limbaje din lume.
Creatorii C# au intenționat să înzestreze limbajul cu mai multe facilități. Succesul de care se bucură în prezent, confirmă calitățile sale:
este un limbaj de programare simplu, modern, de utilitate generală, cu productivitate mare în programare;
este un limbaj orientat pe obiecte;
permite dezvoltarea de aplicații industriale robuste, durabile;
oferă suport complet pentru dezvoltarea de componente software, foarte necesare de pildă în medii distribuite, de altfel se poate caracteriza C# ca fiind nu numai orientat obiect, ci și orientat spre componente.
La aceste caracteristici generale se adaugă și alte trăsături, cum este de pildă suportul pentru internaționalizare, adică posibilitatea de a scrie aplicații care pot fi adaptate cu ușurință pentru a fi utilizate în diferite regiuni ale lumii unde se vorbesc limbi diferite, fără să fie necesare pentru aceasta schimbări în arhitectura software.
În strânsă legătură cu Arhitectura .NET (.NET Framework) pe care funcționează, C# gestionează în mod automat memoria utilizată. Eliberarea memoriei ocupate (garbage collection) de către obiectele care nu mai sunt necesare aplicației, este o facilitate importantă a limbajului. Programatorii nu mai trebuie să decidă singuri, așa cum o fac de pildă în C++, care este locul și momentul în care obiectele trebuie distruse.
În C# se scriu de asemenea aplicații pentru sisteme complexe care funcționează sub o mare varietate de sisteme de operare, cât și pentru sisteme dedicate (embeded systems). Acestea din urmă se întind pe o arie largă, de la dispozitive portabile cum ar fi ceasuri digitale, telefoane mobile, MP3 playere, până la dispozitive staționare ca semafoare de trafic, sau controlere pentru automatizarea producției. Din punct de vedere sintactic C# derivă din limbajul C++, dar include și influențe din alte limbaje, mai ales Java.
Arhitectura .NET este o componentă software care oferă un mediu de programare și de execuție a aplicațiilor pentru sistemele de operare Microsoft și este un mediu care permite dezvoltarea și rularea aplicațiilor și a serviciilor Web, independente de platformă. Limbajul C# se află într-o strânsă legătură cu arhitectura .NET. Inițial, C# a fost dezvoltat de către Microsoft pentru crearea codului platformei .Net, la fel cum destinația inițială a limbajului C a fost aceea de a implementa sistemul de operare UNIX. .NET pune la dispoziție o colecție impresionantă de clase organizate în biblioteci, pe care C# le utilizează. Este momentul să precizăm că C# funcționează având .NET ca infrastructură, dar .NET suportă și alte limbaje, cum este C++, Visual Basic sau Java. În oricare dintre aceste limbaje programați, aveți la dispoziție aceleași biblioteci de clase. .NET se realizează în acest fel interoperabilitatea limbajelor.
3.3 MSSQL Server
SQL Server este un DBMS (Data Base Management System) –sistem pentru gestiunea bazelor de date, produs de Microsoft. Suporta versiunea Microsoft de SQL (Structured Query Language) – limbaj structurat de interogări, cel mai comun limbaj pentru bazele de date. Este un sistem din clasa Enterprise ce se poate aplica bazelor de date de dimensiuni foarte mari. Codul de baza pentru Microsoft SQL Server își are originile in Sybase SQL Server si a reprezentat intrarea Microsoft pe piața bazelor de date la nivel enterprise, concurând cu Oracle, IBM si Sybase. Microsoft, Sybase si Ashton-Tate s-au unit pentru a crea si a scoate pe piața prima versiune numita SQL Server 4.2 ptr Win OS/2. Mai târziu Microsoft a negociat pentru drepturi de exclusivitate la toate versiunile de SQL Server scrise pentru sistemele de operare Microsoft. Sybase si-a schimbat ulterior numele in Adaptive Server Enterprise pentru a se evita confuzia cu Microsoft SQL Server. SQL Server 7.0 a fost primul server de baze de date bazat pe GUI. O varianta de SQL Server 2000 a fost prima varianta comerciala pentru arhitectura Intel. Ultima versiune apăruta este Microsoft SQL Server 2015.Microsoft SQL Sever folosește o varianta de SQL numita T-SQL, sau Transact-SQL, o implementare de SQL-92 (standardul ISO pentru SQL) cu unele extensii. T-SQL in principal adăuga sintaxa adiționala pentru procedurile stocate si pentru tranzacții. Standardele SQL necesita ACID – patru condiții pentru orice tranzacție, sintetizate prin acronimul ACID: atomicitate, consistenta, izolare, durabilitate. MS SQL Server suporta ODBC (Open Database Connectivity).
SQL Server reprezintă un fragment dintr-un miez al unei familii de produse integrate care include dezvoltarea de unelte de management al sistemelor, componente distribuite de sistem și dezvoltarea deschisă de interfețe. Putem spune despre Microsoft SQL Server ca este o soluție integrată de management și analiză a datelor, care ajuta organizațiile de orice dimensiune să:
dezvolte, implementeze și administreze aplicații la nivel de întreprindere mai sigure, scalabile și fiabile;
maximizeze productivitatea IT prin reducerea complexității creării, implementării și administrării aplicațiilor pentru baze de date;
partajeze date pe mai multe platforme, aplicații și dispozitive pentru a facilita conectarea sistemelor interne și externe;
controleze costurile fără a sacrifica performanța, disponibilitatea, scalabilitatea sau securitatea.
3.4 MS Entity Framework
Entity Framework este un framework open source de mapare relațional obiectuala pentru platforma .Net. Per ansamblu este un set de tehnologii in ADO.Net ce susține dezvoltarea de aplicații software orientate pe date. Arhitecții si dezvoltatorii de aplicații orientate pe date s-au străduit sa atingă doua obiective foarte diferite:
trebuie sa modeleze entitățile, relațiile si logica de business a problemei pe care o rezolva;
trebuie sa lucreze cu motorul de date folosit pentru a stoca si regăsi datele.
Acest framework le permite sa lucreze cu date sub forma unor obiecte si proprietati specifice domeniului, cum ar fi clientul, sau adresa clientului fara sa fie preocupati de tabelele care stau la baza bazei de data sau coloanele unde vor fi stocate acestste date.Astfel dezvoltatorii pot lucra la un nivel superior de abstractizare a datelor si pot crea si intretine aplicatii orientate pe date cu mai putine linii de cod decat aplicatiile traditionale.
Prima versiune, EFv1 a fost inclusa in .Net Framework 3.5 Service Pack 1 si Visual Studio 2008 Service Pack 1 si lansata in August 2008.Ultima versiune este 5.0.0 si are ca tinta .Net Framework 4.5. Arhitectura Entity Framework contine elementele prezentate în figura 3.1:
provider specific de surse de date;
map provider – un provider specific bazei de date ce traduce command tree-ul EntitySQL într-o interogare nativa a bazei de date;
view mapping – din schema relaționala creează view-uri ale datelor corespondente modelului conceptual;
query and update pipeline – procesează interogări, filtrează si face update cererilor;
metadata services – gestionează metadatele legate de entități, relații si mapări;
transactions;
conceptual layer API – runtime-ul ce expune modelul de programare;
embedded database – include o baza de date incorporata pentru interogarea datelor relaționale;
desing tools – simplifica task-ul de mapare a schemei conceptuale la schema relaționala;
programming layer – expune EDM-ul (Entity Data Model) ca unități ce pot fi utilizate de limbajul de programare;
object services – cod generat automat pentru clasele CLR ce dețin aceleași proprietăți ca o entitate, dând astfel posibilitatea instanției entităților ce obiecte .Net;
web services – expun entitățile ca servicii web;
Entity Data Model(EDM) specifica modelul conceptual al datelor prin intermediul Entity-Relationship model, ce se ocupa in principal de entitati si asocierile din care acestea fac parte.In Visual Studio EDM Wizard initial genereaza o mapare 1:1 a schemei bazei de date la schema conceptuala.In schema relationala elementele sunt compuse din tabele, in care cheile primare si cheile externe tin tabelele corelate in stransa legatura.In contrast Entity Types defineste schema conceptuala a datelor.Tipurile de entitati sunt o agregare a unor tipuri de campuri multiple, fiecare camp mapand o coloana din baza de date, campuri ce pot contine informatii din mai multe tabele fizice.Tipurile de entitati pot fi corelate unele cu altele, independent de relatiile din schema fizica.Entitatile corelate sunt expuse similar prin intermediul unui camp al carui nume denota relatia in care acestea se afla.Scema logica si maparea ei pe schema fizica este reprezentata ca un EDM si specificata ca un fisier XML.
Entitatile sunt instante al tipurilor de entitati, reprezentand instante individuale ale obiectelor (de exemplu client sau comanda) la care se refera informatia.Tipul de entitate defineste clasa de care apartine o entitate dar si proprietatile pe care o entitate le are.Proprietatile descriu anumite aspecte ale entitatii dandu-i acesteia un nume si un tip.Oricare doua tipuri entitati pot avea o legatura fie printr-o relatie de tipul Association fie printr-una de tipul Contaninment, tipul de relatie este specificat printr-un Relationship Type ce este caracterizat de numarul de tipuri de entitate pe care le leaga dar si de multiplicitatea acestora(reprezentand numarul de entitati ce pot fi legate).Bazandu-ne pe multiplicitate relatiile pot fi de unu-la-unu, unu-la-multi sau multi-la-multi.Un tip de relatie poate avea atasata o Actiune sau o Operatie.Unei relatii i se poate specifica sa efectueze o actiune atunci cand o operatie este executata asupra unei entitati cu care are legatura.
ADO.Net Entity Framework foloseste o varianta de limbaj structurat de interogare denumit Entity SQL ce a fost creat pentru a scrie interogari si update-uri asupra entitatilor si relatiilor la nivel conceptual.
3.5 Descrierea codului sursă
Pentru a realiza cu success aplicația a fost creată o soluție care conține 4 proiecte:
proiectul paginii web;
proiectul api-ului pentru clienți diferiți;
proiectul care conține modelul a sistemului;
proiectul care conține clientul mobil.
Pentru început este necesar de inițializat baza de date și de inițializat primul utilizator care va permite a administra baza de date și lista de restaurante, acest lucru va fi efectuat de funcția Seed al migrației bazei de date. Codul care va adauga grupa administratorilor și primului utilizator este:
if (!context.Roles.Any(r => r.Name == "Admin"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "Admin" };
manager.Create(role);
}
if (!context.Users.Any(u => u.UserName == "bugamarian4ik@gmail.com"))
{
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
string name = "bugamarian4ik@gmail.com";
var user = new ApplicationUser { UserName = name, Email = name, EmailConfirmed = true };
user.Person = new Person();
user.Person.FirstName = "admin";
user.Person.LastName = "admin";
user.Person.BirthDate = new DateTime(1999, 02, 02);
user.Person.PhoneNumber = "+123123123123";
manager.Create(user, "WdlSawHd123$");
manager.AddToRole(user.Id, "Admin");
}
După ce a fost scrisă funcția dată, in consola de manager a fost pornită funcția de inițializare a bazei de date care a rulat cu success această funcție ( figura 3.1)
Figura 3.1 – Inițializarea bazei de date
Pentru a pastra lista de restaurante în baza de date s-a utilizat modelul prezentat mai jos:
public class Restaurant
{
public Restaurant()
{
Raitings = new List<Rating>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public double Longitude { get; set; }
public double Latitude { get; set; }
public string MenuType { get; set; }
public string ShortDescription { get; set; }
public string Website { get; set; }
public string Email { get; set; }
public string Facebook { get; set; }
public string Phone { get; set; }
public bool Wifi { get; set; }
public bool Outdoor { get; set; }
public bool AcceptCreditCards { get; set; }
public List<string> Photos { get; set; }
public virtual ICollection<Rating> Raitings { get; set; }
public double? StartWorkTime { get; set; }
public double? StopWorkTime { get; set; }
public bool Works24Hours { get; set; }
}
Iar pentru a pregati lista de restaurante pentru a afișa în partea utilizatorului a fost creată clasa:
public class RestaurantDTO
{
public string Caption { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
public double GeneralFeedback { get; set; }
public string ImageUrl { get; set; }
public double Long { get; set; }
public double Lat { get; set; }
public string OpeningHours { get; set; }
}
Pentru a transforma prima clasa in clasa gata pentru afișare și trimiterea listei de restaurante spre browser-ul utilizatorului se execută următorul cod:
List<RestaurantDTO> restaurants = new List<RestaurantDTO>();
foreach (var item in db.Restaurants.ToList())
{
var rest = new RestaurantDTO
{
Address = item.Address,
Caption = item.Name,
Lat = item.Latitude,
Long = item.Longitude,
Phone = item.Phone
};
if (item.Works24Hours)
rest.OpeningHours = "Open 24 hours";
else
rest.OpeningHours = string.Format("Open from: {0} – {1}", item.StartWorkTime, item.StopWorkTime);
foreach (var feedback in item.Raitings )
{
rest.GeneralFeedback += feedback.Medium;
}
rest.GeneralFeedback /= item.Raitings.Count;
if (item.Photos.Count > 0)
rest.ImageUrl = item.Photos[0];
restaurants.Add(rest);
}
return View(restaurants);
Afișarea pe pagina web a hărții și listei de restaurante în două coloane se efectuieaza în html cu ajutorul Razor și arată așa:
<div class="row">
<div class="col-md-6">
@if (Model != null)
{
foreach (var list in Model)
{
<div class="panel panel-default">
<div class="panel panel-heading">@list.Caption</div>
<div class="panel panel-body"></div>
</div>
}
}
</div>
<div class="col-md-6">
<!– This is the div that will contain the Google Map –>
<div id="map_canvas" style="height: 600px;"></div>
</div>
</div>
Pentru a plasa markerii pe hartă ce corespund cu lista de restaurante trimise de la server s-a folosit funcții jQuery
<script type="text/javascript">
@*<!– This code tells the browser to execute the "Initialize" method only when the complete document model has been loaded. –>*@
$(document).ready(function () {
Initialize();
});
// Where all the fun happens
function Initialize() {
// Google has tweaked their interface somewhat – this tells the api to use that new UI
google.maps.visualRefresh = true;
var Liverpool = new google.maps.LatLng(47.0599217, 28.8571532);
// These are options that set initial zoom level, where the map is centered globally to start, and the type of map to show
var mapOptions = {
zoom: 14,
center: Liverpool,
mapTypeId: google.maps.MapTypeId.G_NORMAL_MAP
};
// This makes the div with id "map_canvas" a google map
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
// This shows adding a simple pin "marker" – this happens to be the Tate Gallery in Liverpool!
var myLatlng = new google.maps.LatLng(47.0620337, 28.8681147);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: ''
});
// You can make markers different colors… google it up!
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/green-dot.png')
// a sample list of JSON encoded data of places to visit in Liverpool, UK
// you can either make up a JSON list server side, or call it from a controller using JSONResul
var data = []
@*for(var i = 0; i< @Model.Count; i++)
{
data.push()
}*@
// Using the JQuery "each" selector to iterate through the JSON list and drop marker pins
$.each(data, function (i, item) {
var marker = new google.maps.Marker({
'position': new google.maps.LatLng(item.GeoLong, item.GeoLat),
'map': map,
'title': item.PlaceName
});
// Make the marker-pin blue!
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/blue-dot.png')
// put in some information about each json object – in this case, the opening hours.
var infowindow = new google.maps.InfoWindow({
content: "<div class='infoDiv'><h2>" + item.PlaceName + "</h2>" + "<div><h4>Opening hours: " + item.OpeningHours + "</h4></div><div><h4>Address: "+ item.Address +"</h4></div></div>"
});
// finally hook up an "OnClick" listener to the map so it pops up out info-window when the marker-pin is clicked!
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
})
}
</script>
Pentru a prezenta datele detaliate despre un restaurant a fost scrisă clasa care moștenește cîmpurile din clasa RestaurantDTO și mai sunt adăugate cîteva cîmpuri pentru a arăta informația care nu este arătată în date generale:
public class RestaurantDetailsDTO : RestaurantDTO
{
/// <summary>
/// Initializes a new instance of the <see cref="RestaurantDetailsDTO"/> class.
/// </summary>
public RestaurantDetailsDTO()
{
ShortDescription = String.Empty;
Website = String.Empty;
Email = String.Empty;
Facebook = String.Empty;
Phone = String.Empty;
Wifi = false;
Outdoor = false;
AcceptCreditCards = false;
Photos = new List<string>();
}
public string ShortDescription { get; set; }
public string Website { get; set; }
public string Email { get; set; }
public string Facebook { get; set; }
public string Phone { get; set; }
public bool Wifi { get; set; }
public bool Outdoor { get; set; }
public bool AcceptCreditCards { get; set; }
public List<string> Photos { get; set; }
public List<RatingDTO> Ratings { get; set; }
}
Iar RatingDTO prezintă aprecierea unei persoane este prezentată prin următorul cod:
public class RatingDTO
{
public int Id { get; set; }
public double Medium { get; set; }
public string Comment { get; set; }
public PersonDTO Author { get; set; }
}
Pentru extragerea informației detaliate despre un restaurant în controlerul necesar a fost scris codul următor:
public async Task<ActionResult> Details(int id)
{
RestaurantDetailsDTO result = new RestaurantDetailsDTO();
var item = await db.Restaurants.FindAsync(id);
if (item == null)
return HttpNotFound();
var rest = new RestaurantDetailsDTO
{
Address = item.Address,
Caption = item.Name,
Lat = item.Latitude,
Long = item.Longitude,
Phone = item.Phone,
id = item.Id,
ShortDescription = item.ShortDescription,
Website = item.Website,
Email = item.Email,
Facebook = item.Facebook,
Photos = item.Photos,
AcceptCreditCards = item.AcceptCreditCards,
Outdoor = item.Outdoor,
Wifi = item.Wifi
};
if (item.Works24Hours)
rest.OpeningHours = "Open 24 hours";
else
rest.OpeningHours = string.Format("Open from: {0} – {1}", item.StartWorkTime, item.StopWorkTime);
foreach (var feedback in item.Raitings)
{
rest.GeneralFeedback += feedback.Medium;
rest.Ratings.Add(new RatingDTO
{
Comment = feedback.Comment,
Id = feedback.Id,
Medium = feedback.Medium,
Author = new PersonDTO { Id = feedback.Person.Id, FullName = String.Format("{0} {1}", feedback.Person.FirstName, feedback.Person.LastName) }
});
}
if (item.Raitings.Count > 0)
rest.GeneralFeedback /= item.Raitings.Count;
if (item.Photos.Count > 0)
rest.ImageUrl = item.Photos[0];
result = rest;
return View(result);
}
În momentul cînd utilizatorul va dori să lase o apreciere despre un restaurant au fost scrise două funcții:
funcția care va returna pagina unde utilizatorul va introduce datele;
funcția care va salva date postate de utilizator în baza de date și va redirecționa utilizatorul la pagina cu informații detaliate despre restaurant.
public async Task<ActionResult> LeaveRating(int id)
{
PostRatingDTO post = new PostRatingDTO();
post.RestaurantId = id;
var appUser = await Misc.GetMyPerson(User, db);
// incarcam date personale
await db.Entry(appUser).Reference(x => x.Person).LoadAsync();
post.PersonId = appUser.Person.Id;
return View(post);
}
Obținerea datelor despre persoana care este la moment logată
public static async Task<ApplicationUser> GetMyPerson(IPrincipal user, ApplicationDbContext dbContext)
{
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(dbContext));
var appUser = await UserManager.FindByIdAsync(user.Identity.GetUserId());
return appUser;
}
Pentru a obține date detaliate despre un restaurant și a vizualiza utilizatorului se folosește urmatorul cod HTMLcu adausuri Razor:
<script src="http://maps.google.com/maps/api/js?sensor=true" type="text/javascript"></script>
<style>
#map_canvas img {
max-width: none; }
</style>
<!– This css is to give a nice big popup "info window" when a marker is clicked on the map –>
<style>
.infoDiv {
height: 200px;
width: 300px;
-webkit-user-select: none;
background-color: white;}
</style>
<p>
</p>
<div class="row">
<div class="col-md-12">
@using (Html.BeginForm("Index", "Search", FormMethod.Post, new { @class = "form-inline" }))
{
<div class="form-group">
@Html.TextBoxFor(x => x.SearchText, new { @class = "form-control", placeholder = "Search…" })
</div>
<input type="submit" value="Find" class="btn btn-info" />
}
</div>
</div>
<p></p>
<div class="row">
<div class="col-md-7">
<div class="well">
<h1>@Model.RestaurantDetails.Caption – @Model.RestaurantDetails.MenuType</h1>
<p>@Model.RestaurantDetails.MenuType – @Model.RestaurantDetails.Address</p>
<hr />
<p>@Model.RestaurantDetails.ShortDescription</p>
<p><b>Phone</b>: @Model.RestaurantDetails.Phone <b>| Facebook</b>: @Model.RestaurantDetails.Facebook</p>
<p><b>Email</b>: @Model.RestaurantDetails.Email <b>| Website</b>: @Model.RestaurantDetails.Website</p>
<p><b>WiFi</b>: @(Model.RestaurantDetails.Wifi?"Yes":"No") <b>| Outdoor</b>: @(Model.RestaurantDetails.Outdoor?"Yes":"No") <b>| Credit Cards</b>: @(Model.RestaurantDetails.AcceptCreditCards?"Yes":"No")</p>
</div>
</div>
<div class="col-md-5">
<div id="map_canvas" style="height: 400px;"></div>
</div>
</div>
<div class="row">
<div class="col-md-7">
@foreach (var item in Model.RestaurantDetails.Ratings)
{
<div class="panel panel-default">
<div class="panel-heading">
<p>@item.Author.FullName</p>
<span class="badge pull-right">@item.Medium</span>
</div>
<div class="panel-body">
<p>@item.Comment</p>
</div>
</div>
}
</div>
</div>
<p></p>
@section scripts{
<section class="scripts">
<script type="text/javascript">
@*<!– This code tells the browser to execute the "Initialize" method only when the complete document model has been loaded. –>*@
$(document).ready(function () {
Initialize();
});
// Where all the fun happens
function Initialize() {
// Google has tweaked their interface somewhat – this tells the api to use that new UI
google.maps.visualRefresh = true;
var Liverpool = new google.maps.LatLng(47.0599217, 28.8571532);
// These are options that set initial zoom level, where the map is centered globally to start, and the type of map to show
var mapOptions = {
zoom: 13,
center: Liverpool,
mapTypeId: google.maps.MapTypeId.G_NORMAL_MAP
};
// This makes the div with id "map_canvas" a google map
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
// This shows adding a simple pin "marker" – this happens to be the Tate Gallery in Liverpool!
var myLatlng = new google.maps.LatLng(47.0620337, 28.8681147);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Universitatea Tehnica a Moldovei'
});
// You can make markers different colors… google it up!
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/green-dot.png')
// a sample list of JSON encoded data of places to visit in Liverpool, UK
// you can either make up a JSON list server side, or call it from a controller using JSONResult
var data = [];
data.push({ "Id": @Model.RestaurantDetails.id, "PlaceName": "@Model.RestaurantDetails.Caption", "OpeningHours": "@Model.RestaurantDetails.OpeningHours", "Address": "@Model.RestaurantDetails.Address", "Phone":"@Model.RestaurantDetails.Phone", "GeoLong": "@Model.RestaurantDetails.Long", "GeoLat": "@Model.RestaurantDetails.Lat" })
// Using the JQuery "each" selector to iterate through the JSON list and drop marker pins
$.each(data, function (i, item) {
var marker = new google.maps.Marker({
'position': new google.maps.LatLng(item.GeoLong, item.GeoLat),
'map': map,
'title': item.PlaceName
});
// Make the marker-pin blue!
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/blue-dot.png')
// put in some information about each json object – in this case, the opening hours.
var infowindow = new google.maps.InfoWindow({
content: "<div class='infoDiv'><h2>" + item.PlaceName + "</h2>" + "<div><h4>Opening hours: " + item.OpeningHours +
"</h4></div><div><h4>Address: "+ item.Address +"</h4></div><div><h4>Phone: "+ item.Phone +"</h4></div></div>"
});
// finally hook up an "OnClick" listener to the map so it pops up out info-window when the marker-pin is clicked!
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}) }
</script>
</section>
}
4 Descrierea aplicației
În acest capitol vom vedea cum a fost realizat sistemul informațional pe baza codului descris mai devreme și proiectării din capitolul precedent. Pentru a atrage utilizatorul la utilizarea site-ului a fost realizată pagina arătată în figura 4.1.
Figura 4.1 – Pagina start al sistemului
Pagina de start a fost creată în stil minimalistic pentru a permite utilizatorilor să găsească cît mai repede funcțiile principale. În mijlocul paginii este un buton care permite de a trece la căutarea restaurantului. Deasemenea meniul de sus permite să afli informația despre acest proiect și date de contact al suportului.
În figura 4.2 este prezentată pagina unde utilizatorul vede lista restaurantelor prezente în sistem. Lista este prezentată în forma prescurată pentru a da o privire generală asupra tuturor restaurantelor. În partea de sus vedem meniu principal al sistemului care permite logare sau delogare. Mai jos vedem cîmpul unde putem întroduce denumirea restaurantului care îl căutăm. Deasemenea aici putem găsi butoanele de filtrare a rezultatelor obținute.
Mai jos de filtre pagina este împărțită în două coloane, în prima coloana vedem lista de restaurante cu datele prescurtate:
adresa restaurantului;
orele în care lucrează restaurantul dat;
numărul de contact al restaurantului.
Deasemenea alături de denumirea restaurantului se arată nota media a restaurantului.
În partea dreaptă vedem mapa pe care sunt arătate toate restaurantele care se află lîngă persoană. Poziția persoanei este arătat prin markerul verde, iar restaurantele sunt arătate cu marchere albastre.
Figura 4.2 – Lista generală a restaurantelor
În figura 4.3 este arătat rezultatul căutării unui restaurant după denumire. Vedem că în afara de schimbări ce au apărut în lista de restaurante s-au făcut modificări și pe harta.
Figura 4.3 – Rezultatul căutării unui restaurant
În figura 4.4 este prezentat modul în care arată harta în momentul cînd utilizatorul încercă să vadă informația despre un restaurant apăsînd cu mouse asupra la un marcher a unui restaurant.
Figura 4.4 – Afișarea datelor despre un restaurant pe harta
În figura 4.5 este prezentată forma de înregistrare a utilizatorului. În aceasta forma este nevoie de întrodus:
adresa de email;
parola și confirmare de parola;
numele utilizatorului;
prenumele utilizatorului;
numărul de telefon a utilizatorului;
data nașterii a utilizatorului.
Figura 4.5 – Forma de înregistrare a utilizatorului
În figura 4.6 e reprezentată forma de logare a utilizatoruluiîn sistem. Este nevoie de întrodus numele utilizatorul și parola pentru logare. Deasemenea este posibilitate de a loga cu citeva servici globali cum ar fi:
Google;
Facebook;
Twitter;
Microsoft.
Figura 4.6 – Opțiuni de logare a utilizatorului
Pentru a vedea detaliile despre un restaurant a fot creată o pagină web care este prezentată în figura 4.7. În aceasta figura vedem că utilizatorului se permite căutarea unui alt restaurant după denumire. Deasemenea sunt prezentate date detaliate alături de date generale care au fot prezentate și în pasul precedent. În partea stînga este prezentată harta unde este arătată plasarea restaurantului pe harta ca să fie posibil de văzut cum se poate de ajuns la acest restaurant.
Deasemenea în partea de jos este prezentată lista de aprecieri a utilizatorilor despre acest restaurant.
Figura 4.7 – Detalii generale despre un restaurant
În figura 4.8 este prezentată pagina unde utilizatorul autentificat va avea o opțiune să lase o apreciere. Acest buton e vizibil numai pentru persoane autentificate.
Figura 4.8 – Butonul vizibil pentru utilizatori autentificați
Pentru a lasa o apreciere utilizatorul va vedea pagina web prezentată în figura 4.9. Aprecierea unui restaurant are loc după cîteva parametri:
calitatea bucatelor pregătite;
calitatea deservirii;
spațiul restaurantului;
igiena în restaurant;
nivelul prețurilor.
Figura 4.9 – Pagina de aprecierea unui restaurant
După ce a fost adăugata apreciere pagina cu detalii de la un restaurant arată cum este arătat în figura 4.10.
Figura 4.10 – Detaliile unui restaurant cu aprecieri
5 Argumentarea economică
5.1 Descrierea proiectului elaborat
Pentru elaborarea proiectului am ales ca temă: Sistem informațional pentru aprecierea calității de deservire în restaurante. Proiectul are un caracter comercial și reprezintă în plan informațional modul de agregare sistematică a datelor privind restaurantele din republica, informție despre calitate de deservire în ele, atît informația despre utilizatorii sistemului.
Drept un scop aplicația este creată pentru a rezolva cîteva probleme importante: va permite oamenilor simpli de a alege un local cu condițiile cele mai bune reieșind din evaluările altor utilizatori care au vizitat acest local și condițiile care il vor satisface pe utilizator, așa ca amplasarea dorită, meniul dorit orele dorite precum și multe alte.
Pentru utilizatorii care vor veni în vizita din alt oraș sau chiar din altă țara va permite de a găsi restaurante tematice și va permite sa nu fie dezămăgiți. Iar pentru administratorii de restaurante, acest sistem va fi ca o legătura cu clienți și va permite de a corecta sau îmbunătăți serviciile și calitate de deservire. Elaborarea bugetului proiectului este o modalitate universală de a planifica veniturile și cheltuielile și a previziona rezultatele financiare. Pentru o firmă bugetul este expresia cantitativă a obiectivelor pe care aceasta și-a propus să le atingă într-o perioadă de timp precizată, de regulă un an. Obiectivele se formulează în termeni de costuri, prețuri, profit, rentabilitate, etc. Procesul economic nu este un compartiment separat, el începe odată cu stabilirea temei și se manifestă pe întreaga porțiune de timp care este cuprinsă între evenimentul “stabilirea temei” și “prezentarea proiectului la comisie ”, deci orice activitate legată de diplomă în decursul timpului dintre aceste evenimente este necesar de inclus în planificarea economică a tezei.
5.2 Planul calendaristic al proiectului
La elaborarea acestui proiect a participat un programator care a îndeplinit și funcții de manager de proiect și de tester. Planul calendaristic include informația referitoare la executarea în timp a acțiunilor planificate. Rezultatele planificării sunt reflectate în tabelul 5.1.
Tabelul 5.1 – Planul calendaristic
Continuare Tabelul 5.1
Numărul total de zile utilizate pentru elaborarea proiectului este de 73 zile.
5.3 Analiza SWOT
Analiza SWOT pune în lumina punctele tari și slabe ale companiei sau proiectului, asociate cu oportunitățile și amenințările existente la un moment dat pe piața. În urma unei astfel de analize echipa managerială poate propune o îmbunătățire sau o schimbare radicală a planului strategic. Cercetarea joacă un rol important în prezicerea trendurilor viitoare și a direcției în care se îndreaptă compania. În cadrul SWOT, punctele tari și cele slabe sunt privite ca factori interni, pe când oportunitățile și amenințările sunt considerați factori externi. Punctele tari – sau atributele pe care proiectul le posedă și care îi oferă un avantaj pe piața. Punctele slabe – caracteristicile soluției care stau în calea atingerii obiectivelor și factorii care nu se ridică la standardele necesare. Acestea trebuie minimizate sau eliminate. Oportunități – factorii externi de influența care pot fi folosiți în favoarea firmei sau proiectului. În funcție de valorificarea lor, compania se poate dezvolta mai mult, într-un timp mai scurt. Amenințări – factori externi care pun în pericol afacerea. Aceștia nu depind de companie și nu pot fi controlați.
În figura 5.2 este prezentat tabelul SWOT al proiectului curent în care au fost evedențiate punctele descrise:
Tabelul 5.2 – Analiza SWOT
5.4 Argumentarea economică
Pentru evaluarea economică a proiectului, trebuie să determinăm eficiența utilizării rezultatelor de realizare a programului. Compartimentul acesta servește drept bază pentru concluzia dacă proiectul este eficient din punct de vedere economic. Toate calculele sunt efectuate în lei moldovenești (MDL). Prețurile materialelor, precum și plățile salariale sunt actuale. Calcularea bugetului reprezintă determinarea sumei de bani și cuantumului de active materiale și nemateriale necesare pentru realizarea proiectului .
Consumuri directe de material
Consumuri materiale directe, pentru elaborarea sistemului informatic sunt prezentate in tabelul 5.3.
Tabelul 5.3 – Consumuri materiale directe, pentru elaborarea sistemului informatic
Total consumuri materiale directe s-au obținut în sumă de 312,00 lei.
Active materiale și nemateriale pe termen lung
În tabelul 5.4 sunt reprezentate cheltuielile materiale și nemateriale susținute pentru elaborarea sistemului.
Tabelul 5.4– Active materiale și nemateriale pe termen lung
5.5 Cheltuieli privind retribuirea muncii
Calculul salariului de bază a colaboratorilor de proiect. Salariul de bază se plătește în lei pe zi. Asupra proiectului dat au lucrat un programator, care este capabil să îndeplinească funcțiile managerului de proiect și a persoanei care testează programele. Deasemenea s-au luat în calcul remunirarea altor specialiști ce au luat parte la crearea proiectului.Evaluarea cheltuielilor pe salariu de bază este dată în tabelul 5.5.
Tabelul 5.5 – Cheltuieli pentru retribuirea muncii
Conform datelor din tabelul 5.5, pentru remunerarea muncii au fost cheltuite 20625 lei. Totalul reprezintă FRM – Fondul de Retribuire a Muncii, în baza căruia se calculează suma contribuțiilor în Fondul Social (FS) – 23 % și valoarea primei de asigurare medicală obligatorie (AM) – 4,5%.
FAS = FRM Cfs(%) (5.1)
Unde, FAS – fondul de asigurari sociale, Cfs – cota contribuțiilor de asigurări sociale de stat obligatorii, se aprobă în fiecare an prin Legea Bugetului asigurărilor sociale de stat. Conform „Legii bugetului asigurărilor sociale de stat pe anul 2016” contribuția la bugetul asigurărilor sociale de stat obligatorii, suportată de angajator, constituie 23% din fondul de remunerare a muncii.
FAM = FRM Cam(%) (5.2)
Unde, FAM – Fondul Asigurarilor Sociale de stat, Cam – Cota primei de asigurare obligatorie de asistență medicală, se aprobă fiecare an prin Legea Republicii Moldova „Privind fondurile asigurării obligatorii de asistență medicală”. Conform „Legii privind fondurile asigurării obligatorii de asistență medicală pe anul 2015”, cota primei de asigurare obligatorie de asistență medicală suportată de angajator constituie 4,5 % din fondul de remunerare a muncii.
FAS = 20625 23% = 4743.75 lei
FAM = 20625 4,5% = 928.12 lei
La final calculăm fondul de remunerare a muncii total pentru cheltuielile necesare proiectului pentru salarizare. FRMT – Fondul de Remunerare a Muncii Total.
FRMT = FRM + FAS + FAM (5.3)
FRMT = 20625+ 4743.75 + 928.12 = 26296.87 lei
În acest compartiment se va calcula venitul net anual și suma impozitului pe venit anual a unuia din participanți la elaborarea proiectului care prezintă subiect de impozitare .
Astfel (anul 2016) sunt prevăzute următoarele taxe și scutiri la venituri pentru persoane fizice:
Impozit pe venit:
venituri anuale pînă la 29640 lei – se aplică cota de impozitare 7%;
venituri anuale mai mari de 29640 lei – se aplică cota de impozitare 18%;
fondul de pensionare – 6 % din venit;
fondul de Asigurare Medicală – 4,5 % din venit;
fiecare contribuabil (persoană fizică rezidentă) are dreptul la o scutire personală în sumă de 10128 lei pe an ;
contribuabilul (persoană fizică rezidentă) are dreptul la o scutire în sumă de 2256 lei anual pentru fiecare persoană întreținută;
suma scutirii personale majore 15060 lei anual.
Calculul impozitelor achitate pentru programator:
salariul programatorului pe perioada proiectului constituie 18975 lei, ceea ce reprezintă o perioada de lucru de 4 luni, lunar salariul a constituit 4743.75 lei.
Salariul anual = 4743.75 12=56925 lei
Se admite că salariul brut anual al programatorului este de 56925 lei. Astfel utilizăm cotele de impozitare actuale pentru 2016 vom calcula venitul net anual și respectiv suma impozitului pe venit transferat la bugetul de stat.
Calculăm reținerile în fondul social FS și contribuții asigurări medicale (FAS):
FP = 6% 56925 = 3415.5 lei
FAM = 4,5% 56925 = 2561.62 lei
Calculul venitului impozabil:
VI = VB – FP – FAM – SP – SiP – SM (5.4)
Unde VI – venitul impozabil:
VB – venitul brut;
FP – fondul de pensionare (asigurări sociale);
FAM – fondul de Asigurare Medicală;
SP – scutirea personală;
SiP – scutirea pentru persoana întreținută;
SM – scutirea personală majoră.
Folosind formula (5.4) se efectuează calculele:
VI = 56925 – 3415.5 – 2561.62 – 10128– 0 – 0 = 40819.88 lei
Se calculează suma venitului net aplicînd cotele de impozitare în vigoare:
VN = VB – IV – FP – FAM (5.5)
Unde VB – venitul brut:
IV – impozit pe venit;
FP – fondul de pensionare (asigurări sociale);
FAM – prima de Asigurare Medicală.
VN = 56925 – 4087,18 – 3415,5 – 2561,62 = 46860,7 lei
Se calculează suma impozitului pe venit:
IV = VI – I (5.6)
Unde IV – Impozit pe venit:
pentru venituri anuale de pîna la 29640 lei – se aplică cota de impozitare 7%;
pentru venituri mai mari de 29640 lei – se aplică cota de impozitare 18%.
IV = (29640 7%)+((40819,88 – 29640) 18%)= 4087,18 lei
5.6 Consumuri indirecte
Consumuri indirecte– reprezintă consumurile volumul cărora nu depinde sau depinde neesențial de volumul de producție, cum ar fi: consumul de energie electrică folosită pentru iluminare, consumul efectuat pentru încălzirea spațiului, consumuri privind paza , chiria, etc.
Tabelul 5.6 –Consumuri indirecte
5.7 Uzura mijloacelor fixe și amortizarea activelor nemateriale pe termen lung
Partea importantă a cheltuielilor indirecte constituie calcularea fondului de uzură și amortizare. Uzura mijloacelor fixe reprezintă repartizarea sistematică a valorii uzurabile a mijloacelor fixe în decursul duratei de funcționare utilă. Norma uzurii se calculează în dependență de durata utilizării activului. Durata utilizării activului se determină după categoria lui. AMTL – 3-5 ani, ANTL – 2-3 ani.
FA=Vi : DFU T1 (5.7)
Unde FA – fondul amortizării:
MFi – valoarea de intrare;
T1 – durata proiectului;
DFU – durata de funcționare utilă.
Se calculează identic suma amortizării activelor nemateriale pentru fiecare categorie în parte. În conformitate cu prevederile S.N.C. 16 “Contabilitatea activelor materiale pe termen lung” (p. 47) uzura poate fi calculată conform următoarelor metode:
casării lunare;
în raport cu volumul produselor fabricate (servicii prestate);
degresivă cu rată descrescătoare;
soldului degresiv.
Astfel fondul de amortizare pentru laptopul folosit în cadrul elaborării proiectului calculat conform formulei (5.7) este:
Astfel fondul de amortizare pentru printer folosit în cadrul elaborării proiectului calculat conform formulei (5.7) este:
Astfel fondul de amortizare pentru untitățile folosite în cadrul elaborării proiectului sunt:
5.8 Costul de producție
Costul de producție reprezintă totalitatea cheltuielilor, corespunzătoare consumului de factori de producție, pe care agenții economici le efectuează pentru producerea și vânzarea de bunuri materiale sau prestarea de servicii.
Prețul de cost se calculează pe o unitate. Dacă se elaborează un site sau o aplicație, atunci va fi prețul de cost al elaborării, dar dacă în cadrul proiectului se planifică multiplicarea produsului, atunci este nevoie de calculat costul de elaborare al unei copii.
Tabelul 5.7 – Costul de producție
5.9 Calculul indicatorilor economico – financiari
Preț de realizare
Având la dispoziție prețul de cost al unei copii de produs se poate de determinat prețul de realizare pe piață a programului elaborat prin următoarea metodă:
Metoda „bottom-up”
Preț brut = Preț de cost + Profitul Net (5.8)
Preț brut = 28974.51 + 15000 = 43974,51 lei
Rentabilitate = PN : CT 100% (5.9)
Rentabilitate = 15000 : 28974.51 100% = 51.76%
Prz = Preț brut + TVA (5.10)
TVA-taxa pe valoarea adăugată (prescurtat TVA, ) este un impozit indirect suportat de consumatorul final al bunului/serviciului respectiv. TVA este un impozit încasat în cascadă de fiecare agent economic care participă la ciclul economic al realizării unui produs sau prestării unui serviciu care intră în sfera de impozitare. După exercitarea dreptului de deducere, agenții economici impozabili care au participat la ciclul economic vizează soldul TVA la bugetul de stat. RM sunt în vigoare cota standard: 20%
Prz = 43974,51 + 8794,9= 52769.41
Concluzie
Elaborând această lucrare am studiat mai aprofundat ce constituie acest domeniu al informaticii și anume proiectarea sistemelor înzestrate cu anumite proprietăți. Am analizat ce este un sistem, de ce cunoștințe și capacități dispun în desfășurarea activității. Diagrama de stare ne poate arăta modul de lucru a sistemului, iar diagrama de desfășurare structura sistemului în modul amplasării elementelor într-un mediu.
Descrierea corecta a modului de lucru a Sistemului Informatic ușurează și face mai clara viziunea utilizatorului față de sistem.
De asemenea am studiat care sunt obiectivele și structura unui Sistem, conceptele de bază și caracteristicile lui.
Principiile noastre de funcționare sunt bazate pe onestitate, entuziasm, respect, proprietate, excelență și servicii. Aceste valori ghidează modul în care noi ne gestionăm sistemul și felul în care ne servim clienții. Sistemul nostru se concentrează asupra echipamentelor informaționale ale clienților. Experiența pe termen lung și cunoștințele noastre profesionale și a colaboratorilor noștri permit clienților noștri să colaboreze cu sistemul dat pe parcursul planificării și implementării proiectelor. Sistemul nostru are în vedere și optimul financiar și încadrarea într-un buget dat.
Sistemul dat este un sistem creat în urma unui studiu profund în practica a domeniului de activitate, pe perioada căruia s-au văzut punctele pozitive si negative ale sistemelor standarde, iar aceasta experiența ne-a oferit un bagaj noi de idei cum de îmbunătațit modul cum pot colabora persoanele ce au găsite unele obiecte cu altele persoane ce au pierdut aceste obiecte. A fost efectuată crearea unui sistem complet, cu ajutorul ultimelor tehnologii informaționale care arată că calculatorul poate ajuta pe toți fără excepții.
Bibliografie
Visual Studio Community 2015 descarcare, accesat 01.09.2015, [Resursa electronica]. – Regim de acces: https://www.visualstudio.com/post-download-vs?sku=community&clcid=0x419
Microsoft SQL Server Express descarcare, accesat 01.09.2015, [Resursa electronica]. – Regim de acces: https://www.microsoft.com/en-us/download/details.aspx?id=42299
Lucru cu Entity Framework 6, accesat 01.09.2015, [Resursa electronica]. – Regim de acces: http://www.entityframeworktutorial.net/entityframework6/introduction.aspx
Lucru cu ASP .Net MVC 5, accesat 01.09.2015, [Resursa electronica]. – Regim de acces: https://www.asp.net/mvc/overview/getting-started/introduction/getting-started
Lucru cu JQuery Google Maps, accesat 03.3.2016, [Resursa electronica]. – Regim de acces: http://marcgrabanski.com/jquery-google-maps-tutorial-basics/
Jesse Liberty C# Language Fundamentals
Anexa A
Codul sursă
public class BundleConfig
{
// For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*"));
// Use the development version of Modernizr to develop with and learn from. Then, when you're
// ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"));
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));
}
}
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
[Authorize]
public class AccountController : Controller
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public AccountController()
{
}
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
{
UserManager = userManager;
SignInManager = signInManager;
}
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
//
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
//
// GET: /Account/VerifyCode
[AllowAnonymous]
public async Task<ActionResult> VerifyCode(string provider, string returnUrl, bool rememberMe)
{
// Require that the user has already logged in via username/password or external login
if (!await SignInManager.HasBeenVerifiedAsync())
{
return View("Error");
}
return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe });
}
//
// POST: /Account/VerifyCode
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> VerifyCode(VerifyCodeViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// The following code protects for brute force attacks against the two factor codes.
// If a user enters incorrect codes for a specified amount of time then the user account
// will be locked out for a specified amount of time.
// You can configure the account lockout settings in IdentityConfig
var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, isPersistent: model.RememberMe, rememberBrowser: model.RememberBrowser);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(model.ReturnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid code.");
return View(model);
}
}
//
// GET: /Account/Register
[AllowAnonymous]
public ActionResult Register()
{
return View();
}
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
user.PersonalInformation = new Person();
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/ConfirmEmail
[AllowAnonymous]
public async Task<ActionResult> ConfirmEmail(string userId, string code)
{
if (userId == null || code == null)
{
return View("Error");
}
var result = await UserManager.ConfirmEmailAsync(userId, code);
return View(result.Succeeded ? "ConfirmEmail" : "Error");
}
//
// GET: /Account/ForgotPassword
[AllowAnonymous]
public ActionResult ForgotPassword()
{
return View();
}
//
// POST: /Account/ForgotPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
{
// Don't reveal that the user does not exist or is not confirmed
return View("ForgotPasswordConfirmation");
}
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
// var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Reset Password", "Please reset your password by clicking <a href=\"" + callbackUrl + "\">here</a>");
// return RedirectToAction("ForgotPasswordConfirmation", "Account");
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/ForgotPasswordConfirmation
[AllowAnonymous]
public ActionResult ForgotPasswordConfirmation()
{
return View();
}
//
// GET: /Account/ResetPassword
[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
return code == null ? View("Error") : View();
}
//
// POST: /Account/ResetPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null)
{
// Don't reveal that the user does not exist
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
if (result.Succeeded)
{
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
AddErrors(result);
return View();
}
//
// GET: /Account/ResetPasswordConfirmation
[AllowAnonymous]
public ActionResult ResetPasswordConfirmation()
{
return View();
}
//
// POST: /Account/ExternalLogin
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
// Request a redirect to the external login provider
return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}
//
// GET: /Account/SendCode
[AllowAnonymous]
public async Task<ActionResult> SendCode(string returnUrl, bool rememberMe)
{
var userId = await SignInManager.GetVerifiedUserIdAsync();
if (userId == null)
{
return View("Error");
}
var userFactors = await UserManager.GetValidTwoFactorProvidersAsync(userId);
var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList();
return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe });
}
//
// POST: /Account/SendCode
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SendCode(SendCodeViewModel model)
{
if (!ModelState.IsValid)
{
return View();
}
// Generate the token and send it
if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider))
{
return View("Error");
}
return RedirectToAction("VerifyCode", new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe });
}
//
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
// Sign in the user with this external login provider if the user already has a login
var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
case SignInStatus.Failure:
default:
// If the user does not have an account, then prompt the user to create an account
ViewBag.ReturnUrl = returnUrl;
ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
}
}
//
// POST: /Account/ExternalLoginConfirmation
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
{
if (User.Identity.IsAuthenticated)
{
return RedirectToAction("Index", "Manage");
}
if (ModelState.IsValid)
{
// Get the information about the user from the external login provider
var info = await AuthenticationManager.GetExternalLoginInfoAsync();
if (info == null)
{
return View("ExternalLoginFailure");
}
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user);
if (result.Succeeded)
{
result = await UserManager.AddLoginAsync(user.Id, info.Login);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToLocal(returnUrl);
}
}
AddErrors(result);
}
ViewBag.ReturnUrl = returnUrl;
return View(model);
}
//
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("Index", "Home");
}
//
// GET: /Account/ExternalLoginFailure
[AllowAnonymous]
public ActionResult ExternalLoginFailure()
{
return View();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_userManager != null)
{
_userManager.Dispose();
_userManager = null;
}
if (_signInManager != null)
{
_signInManager.Dispose();
_signInManager = null;
}
}
base.Dispose(disposing);
}
#region Helpers
// Used for XSRF protection when adding external logins
private const string XsrfKey = "XsrfId";
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error);
}
}
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToAction("Index", "Home");
}
internal class ChallengeResult : HttpUnauthorizedResult
{
public ChallengeResult(string provider, string redirectUri)
: this(provider, redirectUri, null)
{
}
public ChallengeResult(string provider, string redirectUri, string userId)
{
LoginProvider = provider;
RedirectUri = redirectUri;
UserId = userId;
}
public string LoginProvider { get; set; }
public string RedirectUri { get; set; }
public string UserId { get; set; }
public override void ExecuteResult(ControllerContext context)
{
var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
if (UserId != null)
{
properties.Dictionary[XsrfKey] = UserId;
}
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
}
}
#endregion
}
public class PersonController : Controller
{
ApplicationDbContext db = new ApplicationDbContext();
// GET: Person
public ActionResult Index()
{
List<PersonDTO> list = new List<PersonDTO>();
foreach (var item in db.ListOfPersons.ToList())
{
PersonDTO pers = new PersonDTO();
pers.Id = item.Id;
pers.Name = item.Nume;
pers.Prenume = item.Prenume;
pers.RaitingTotals = item.Raitings.Count();
list.Add(pers);
}
return View(list);
}
public ActionResult Details(int id)
{
var per = db.ListOfPersons.Find(id);
if (per==null)
{
return HttpNotFound();
}
PersonDetailsDTO temp = new PersonDetailsDTO();
temp.Id = per.Id;
temp.Name = per.Nume;
temp.PhoneNUmber = per.PhoneNUmber;
temp.Prenume = per.Prenume;
temp.YearOfBorn = per.YearOfBorn;
temp.RaitingTotals = per.Raitings.Count();
foreach (var item in per.Raitings)
{
RatingDTO tempR = new RatingDTO();
tempR.Id = item.Id;
tempR.Message = item.Message;
tempR.Rest.Title = item.Restaurant.RestaurantName;
tempR.Rest.Id = item.Restaurant.Id;
temp.Ratings.Add(tempR);
}
return View(temp);
}
public ActionResult Filter()
{
return View();
}
//Special Permision, only for registered users
public ActionResult Profil()
{
return View();
}
}
public class RatingController : Controller
{
ApplicationDbContext db = new ApplicationDbContext();
// GET: Rating
public ActionResult Index()
{
List<RatingDTO> list = new List<RatingDTO>();
foreach (var item in db.ListOfRatings.ToList())
{
RatingDTO rating = new RatingDTO();
rating.Id = item.Id;
rating.Rest.Title = item.Restaurant.RestaurantName;
rating.Deservirea = item.Deservirea;
rating.FAnturajul = item.FAnturajul;
rating.FoodQuality = item.FoodQuality;
rating.Igiena = item.Igiena;
rating.Price = item.Price;
rating.Message = item.Message;
list.Add(rating);
}
return View(list);
}
public ActionResult Details(int id)
{
var rtemp = db.ListOfRatings.Find(id);
if (rtemp == null)
{
return HttpNotFound();
}
RaitingDetailsDTO rating = new RaitingDetailsDTO();
rating.Id = rtemp.Id;
rating.Igiena = rtemp.Igiena;
rating.Message = rtemp.Message;
rating.Price = rtemp.Price;
rating.Rest.Title = rtemp.Restaurant.RestaurantName;
rating.FAnturajul = rtemp.FAnturajul;
rating.FoodQuality = rtemp.FoodQuality;
rating.Deservirea = rtemp.Deservirea;
rating.ScorFinal = (rtemp.Deservirea + rtemp.FAnturajul + rtemp.FoodQuality + rtemp.Igiena + rtemp.Price) / 5;
rating.Pers.Name = rtemp.Person.Nume;
rating.Pers.Prenume = rtemp.Person.Prenume;
rating.Pers.Id = rtemp.Person.Id;
return View(rating);
}
[Authorize]
public ActionResult CreateRating(int id)
{
var rtemp = db.ListOfRestaurants.Find(id);
RatingDTO tempRat = new RatingDTO();
tempRat.Rest.Title = rtemp.RestaurantName;
tempRat.Rest.Id = id;
return View(tempRat);
}
[HttpPost, Authorize]
public async Task<ActionResult> CreateRating(RatingDTO formData)
{
var tempRest = db.ListOfRestaurants.Find(formData.Id);
if (tempRest == null)
{
return new HttpStatusCodeResult(HttpStatusCode.NotFound);
}
Rating rating = new Rating();
rating.Deservirea = formData.Deservirea;
rating.FAnturajul = formData.FAnturajul;
rating.FoodQuality = formData.FoodQuality;
rating.Igiena = formData.Igiena;
rating.Price = formData.Price;
rating.Message = formData.Message;
//obtinem utilizatorul
var appUser = await Misc.GetMyPerson(User, db);
// incarcam date personale
await db.Entry(appUser).Reference(x => x.PersonalInformation).LoadAsync();
tempRest.Raitings.Add(rating);
appUser.PersonalInformation.Raitings.Add(rating);
db.SaveChanges();
return RedirectToAction("Details", "Restaurant", new { id = formData.Id });
}
[Authorize]
public async Task<ActionResult> DeleteRating(int? id)
{
var appUser = await Misc.GetMyPerson(User, db);
var userID = appUser.PersonalInformation.Id;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var temp = db.ListOfRatings.Find(id);
if (temp == null)
{
return HttpNotFound();
}
var tempR = new RaitingDetailsDTO();
tempR.Deservirea = temp.Deservirea;
tempR.FAnturajul = temp.FAnturajul;
tempR.FoodQuality = temp.FoodQuality;
tempR.Id = temp.Id;
tempR.Igiena = temp.Igiena;
tempR.Message = temp.Message;
tempR.Price = temp.Price;
tempR.ScorFinal = (temp.Deservirea + temp.FAnturajul + temp.FoodQuality + temp.Igiena + temp.Price) / 5;
tempR.Rest.Title = temp.Restaurant.RestaurantName;
tempR.Rest.Id = temp.Restaurant.Id;
if (userID != temp.Person.Id)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
return View(tempR);
}
[Authorize]
public async Task<ActionResult> FinalDelete(int id)
{
var appUser = await Misc.GetMyPerson(User, db);
var userID = appUser.PersonalInformation.Id;
var tempRating = db.ListOfRatings.Find(id);
int idrest = tempRating.Restaurant.Id;
if (tempRating == null)
{
return HttpNotFound();
}
if (userID == tempRating.Person.Id)
{
db.ListOfRatings.Remove(tempRating);
db.SaveChanges();
return RedirectToAction("Details", "Restaurant", new { id = idrest });
}
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
[Authorize]
public async Task<ActionResult> EditeRating(int? id)
{
var appUser = await Misc.GetMyPerson(User, db);
var userID = appUser.PersonalInformation.Id;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var temp = db.ListOfRatings.Find(id);
if (temp == null)
{
return HttpNotFound();
}
var tempR = new RatingDTO();
tempR.Deservirea = temp.Deservirea;
tempR.FAnturajul = temp.FAnturajul;
tempR.FoodQuality = temp.FoodQuality;
tempR.Id = temp.Id;
tempR.Igiena = temp.Igiena;
tempR.Message = temp.Message;
tempR.Price = temp.Price;
tempR.Rest.Title = temp.Restaurant.RestaurantName;
tempR.Rest.Id = temp.Restaurant.Id;
tempR.Pers.Id = temp.Person.Id;
if (userID != tempR.Pers.Id)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
return View(tempR);
}
[Authorize, HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> EditeRating(RatingDTO temp)
{
var appUser = await Misc.GetMyPerson(User, db);
var userID = appUser.PersonalInformation.Id;
if (userID == temp.Pers.Id)
{
var itemr = db.ListOfRatings.Find(temp.Id);
if(itemr==null)
{
return HttpNotFound();
}
itemr.Deservirea = temp.Deservirea;
itemr.FAnturajul = temp.FAnturajul;
itemr.FoodQuality = temp.FoodQuality;
itemr.Igiena = temp.Igiena;
itemr.Message = temp.Message;
itemr.Price = temp.Price;
itemr.Id = temp.Id;
var idrating = temp.Rest.Id;
db.SaveChanges();
return RedirectToAction("Details", "Restaurant", new { id = idrating });
}
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Sistem informațional pentru aprecierea calității de deservire în restaurante [303476] (ID: 303476)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
