TP commerciaux

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.

1) Gestion des notes de frais de chaque commercial

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.

1.1 La méthode ToString

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é

1.2 Gestion des classes dérivées

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 :

1.3 Gestion des notes de frais d'un commercial

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 List<NoteFrais> qui réalise la relation entre Commercial et NoteFrais. Le constructeur de la classe Commercial doit créer cette List :
                       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.

1.4 Affichage.

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 :

1.5 Une classe ServiceCommercial

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.

Solution

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 :

 

1.6 Sauvegarde des informations dans un fichier

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.

Lire à ce propos.

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).