La société Camaurel fabrique et vend des placards et rangements à monter soi-même. Son siège est installé dans la région parisienne ; un nombre important de commerciaux rayonne en France afin de développer et consolider sa clientèle : principalement des distributeurs (magasins d'aménagement, surfaces de bricolage). Pendant ses déplacements, le commercial est amené à engager des frais, pour ses transports, ses repas ou les nuits passées à l'hôtel. L'application proposée ici vise à gérer ces notes de frais, documents rendus justifiant des frais engagés.
Régulièrement après chaque mission, le commercial remet ses notes de frais en indiquant notamment la date du frais; il y a trois types de notes de frais.
- Les notes de transport routier dues au carburant (les péages
sont pris en charge par une carte de société).
Le commercial précise sur sa note le nombre de km, sans autres justifications
; le remboursement se fait sur la base de la puissance de la voiture : 0.7 €/km
pour une voiture de moins de 5 chevaux, 0.8 € pour une voiture entre 5
et 10 chevaux et 0.9 € au delà de 10 chevaux.
- Les notes de repas de midi.
Le commercial doit fournir la facture du repas. Le remboursement se fait en
tenant compte de la catégorie du commercial (échelle interne à
la profession) ; la catégorie A donne lieu à un remboursement
de 25 €, la catégorie B donne lieu à un remboursement de
22 € et la catégorie C à un remboursement de 20 €. Dans
le cas où la facture n'atteint pas ce plafond, le commercial est remboursé
du montant de la facture produite.
- les notes de nuité, comprenant également le repas du
soir et le petit déjeuner.
Deux éléments interviennent ; la catégorie pour laquelle
la même règle est appliqué que pour les repas de midi (
A --> 65 € , B --> 55€, C --> 50€ ) et la région
touristique dans laquelle se trouve l'hôtel. Un coefficient est appliqué
aux tarifs : 0.90 pour la région 1, 1 pour la région 2 et 1.15
pour la région 3. Le plafond indiqué n'est remboursé que
si le montant de la facture lui est supérieur.
Le système a besoin de connaître, à chaque création d'une note de frais, le montant à rembourser et si chaque note de frais a été remboursée; chaque note est identifiée par un numéro distinct pour chaque commercial. Chaque commercial possède un nom, un prénom, la puissance de son véhicule (entier) et sa catégorie (caractère).
Travail à faire
Faire le diagramme de classes sans faire apparaître les méthodes.
Solution
Travail à faire
Ecrire la classe Commercial avec un constructeur qui valorise chaque champ ainsi que des accesseurs sur chacun des champs.
Ecrire la classe NoteFrais avec un constructeur qui
valorise chaque champ ainsi que la référence de dépendance
avec la classe Commercial :
Seul le champ leCommercial dans la classe NoteFrais dispose d'un accesseur. Un modificateur (set) permet de mettre à jour le champ montantARembourser ; une méthode virtual (sans code) est déclarée :
C'est cette méthode -redéfinie- qui calculera les réels montants des remboursements pour les classes dérivées ; la méthode set sera appelée à la construction des instances des classes dérivées.
Chaque classe hérite de la classe Object et dispose d'une méthode ToString(). Nous allons redéfinir cette méthode dans la classe Commercial.
Travail à faire
Redéfinir dans la classe Commercial la méthode ToString() de manière à pouvoir être utilisée, par exemple, ainsi :
produisant :
Faire de même pour la classe NoteFrais.
produit :
Légende :
le numéro de la note - date-montant à rembourser E- NR pour non
rembourse, R pour remboursé
Travail à faire
Ecrire les trois classes dérivées, et notamment la méthode calculMontantA rembourser() de chacune des classes.
1- Pour la classe FraisTransport, vérifier que le code :
produit bien :
Légende :
T (pour transport)-le numéro de la note - date-montant à rembourser
E- NR pour non rembourse, R pour remboursé-kilométrage km-
2- Pour la classe RepasMidi, vérifier que le code :
produit bien :
Légende :
R (pour repas)-le numéro de la note - date-montant à rembourser
E- NR pour non rembourse, R pour remboursé - montant payé E
et que le code :
produit aussi :
3- Pour la classe Nuite, vérifier que le code :
produit bien :
Légende :
N (pour nuité)-le numéro de la note - date-montant à rembourser
E- NR pour non rembourse, R pour remboursé - montant payé E -région-
mais que le code :
produit bien :
Pour enregistrer les différentes notes de frais, nous allons utiliser, non pas une ArrayList, mais une liste typée.
Ajouter un champ privé mesNotes de typ
mesNotes
= new List<NoteFrais>(); //
notez la syntaxe
Les méthodes sont très proches de l'ArrayList ; le gros avantage de la classe List<type> est que nous n'avons pas à caster, lorsque nous voulons accéder à un élément.
C'est la classe Commercial qui créera ses notes de frais et les enregistrera dans le champ mesNotes.
Travail à faire
Ecrire les méthodes ajouteNote (surchargées) qui permettent
de créer les différents types de notes de frais.
Ce qui produit l'affichage suivant :
Remarque : le numéro des notes de frais est géré automatiquement; imaginez une solution.
Une classe écran se chargera de l'affichage.
Travail à faire
Ecrire le code de la classe Ecran qui permet de faire l'appel suivant :
qui produit :
Nous allons ajouter une classe ServiceCommercial, conteneur de commerciaux. Cette classe contiendra un attribut associatif lesCommerciaux de type List<Commercial>.
Travail à faire
Ajouter au diagramme de classe la classe ServiceCommercial.
La classe ServiceCommercial permet d'ajouter des commerciaux ainsi que leurs notes de frais.
On désire pouvoir faire les appels suivants dans le Main :
Commercial
c1, c2,c3;
ServiceCommercial
sc;
sc = new ServiceCommercial();
c1 = new Commercial("Dupond",
"Jean", 7, 'B');
c2 = new Commercial("Durand",
"Dominique", 11, 'C');
c3 = new Commercial("Chamir",
"Jéremy", 15, 'A');
sc.ajouterCommercial(c1);
sc.ajouterCommercial(c2);
sc.ajouterCommercial(c3);
DateTime d = new DateTime(2009, 10, 21);
sc.ajouterNote(c1, d, 100); // ajoute un frais de transport
sc.ajouterNote(c1, d, 15.5); // ajoute une note de repas
sc.ajouterNote(c1, d, 75, '3'); // ajoute une nuité
DateTime d1 = new DateTime(2009, 10, 23);
sc.ajouterNote(c1, d1, 150); // ajoute un frais de transport
sc.ajouterNote(c1, d1, 25.5); // ajoute une note de repas
sc.ajouterNote(c1, d1, 85, '3'); // ajoute une nuitésc.ajouterNote(c2, d, 120); // ajoute un frais de transport
sc.ajouterNote(c2, d, 22.5); // ajoute une note de repas
sc.ajouterNote(c2, d, 95, '2'); // ajoute une nuité
sc.ajouterNote(c2, d1, 70); // ajoute un frais de transport
sc.ajouterNotec2, d1, 15.5); // ajoute une note de repas
sc.ajouterNote(c2, d1, 105, '2'); // ajoute une nuitésc.ajouterNote(c3, d, 250); // ajoute un frais de transport
sc.ajouterNote(c3, d, 19.5); // ajoute une note de repas
sc.ajouterNote(c3, d, 75, '1'); // ajoute une nuité
Ecran.affiche(sc);
De même, la classe Ecran sera enrichie d'une nouvelle méthode
affiche :
public static void affiche(ServiceCommercial sc)
{
for(int i = 0; i <sc.nbCommerciaux(); i++)
affiche(sc.getCommercial(i));
}
Travail à faire
Ecrire le code de la classe ServiceCommercial conforme à ces appels de
méthodes.
Tester afin d'obtenir :
Actuellement les données sont conservées en mémoire ; il n'y a pas de sauvegarde des informations sur un support de masse.
nous allons utliser un mécanisme qui va nous permettre de sauvegarder les instances des classes créées : la sérialisation.
Nous allons créer une classe PersisteCommercial qui permettra d'écrire les appels suivants :
...suite du code fourni plus haut et qui charge les notes de frais des commerciaux du service commercial
PersisteServiceCommercial.sauve(sc, "service.sr");
ServiceCommercial sc1 = PersisteServiceCommercial.charge("service.sr");
Ecran.affiche(sc1);Remarque : le ServiceCommercial sc est lu à partir de la mémoire, le ServiceCommercial sc1 est désérialisé.
Travail à faire
Ecrire la classe PersisteCommercial qui ne contiendra que deux méthodes
statiques (utiliser la sérialisation binaire).