/*		Programme : facture chez ti père
        auteur    : Martin Robinson
		date      : 26 février 2012
		description : prendre l'information contenu dans un fichier et
		              rediger une facture pour chaque client et un rapport
					  pour la totalité des factures générer
		methode     : J'ai utilisé les "Functor"s fonction objet

======================================================================		
Directive du préprocesseur============================================*/
#include "rapportFacture.hpp"

/*=========================================================================
methode des classes
=========================================================================*/

/*=========================
article , objet pour chaque item
=========================*/

//constructeur , initialisé à meme le fichier
article::article(ifstream &entree,int clientMembre)
{
	//lecture de l'information dans le fichier
	entree >> articleID		//numeraux d'article
			>> nom			//nom de l'article
			>> qty			//quantiyé
			>> prix			//prix à l'unité
			>> selection;	//s si selectionné
	//validation
	if (entree.fail())	
		echec=true;
	else
		echec=false;
	//calcul du soustotal
	soustotal = prix*qty;
	//verification du statu membre pour le rabais
	if (clientMembre==2)
	{
		if (selection=='s')
			rabais = vipS;
		else
			rabais = vip;
	}
	else if(clientMembre==1)
	{
		if (selection=='s')
			rabais = membreS;
		else
			rabais = membre;
	}
	else
	{
		if (selection=='s')
			rabais = nonMembreS;
		else
			rabais = 0;
	}
	//total pour l'article
	total = soustotal-(rabais*soustotal);
}

//formatage de sortie, surcharge de l'operateur stream << , usage tel que cout << objet
ostream& operator<<(ostream& output, article& input)
{
	output << setprecision(2) << fixed << "    " << left << setw(8) << input.articleID
		   << setw(14) << input.nom
		   << input.qty
		   << right << setw(9) << input.prix << '$'
		   << setw(9) << input.soustotal << '$'
		   << setw(9) << (input.selection=='s'?"oui":"non")
		   << setw(9) << (int)(input.rabais*100) << '%' 
		   << setw(8) << input.total << '$'
		   << endl;
	return output;  // for multiple << operators.
}

/*=========================
facture , objet pour chaque client
=========================*/
//constructeur : initialisé a meme le fichier
facture::facture(ifstream &entree,string laDate, int numerauxFacture)
{
	//initialisation
	soustotal = 0;		//soustotal de la facture
	rabais = 0;			//total des rabais pour la facture
	date = laDate;		//la date donné
	numFacture = numerauxFacture;	//numéraux de facture donné
	nbArticle = 0;		//nombre total d'article dans la facture

	//saisi des données à meme le fichier
	entree >> clientID	//numéraux de client
			>> Prenom   //prénom du client
			>> Nom		// nom de famille du client
			>> status	//statu membre
			>> nbItem;	//nombre d'item à saisir
	//validation
	if (entree.fail())
		echec = true;
	else
		echec = false;
}

//fermeture de facture, surcharge d'operateur (), usage telque objet()
//dans la méthode "Functional" ou les "Functor" fonction objet , il y a la "Closure"
void facture::operator () ()
{
	total = soustotal;		//calcul de la taxe a partir du soustotal
	tps = total * tauxTps;
	total += tps;
	tvq = total * tauxTvq;
	total += tvq;
}

//ajout d'item à la facture, surcharge d'operateur +=, usage telque objet += article
//les articles sont directement ajouté à l'objet
void facture::operator += (article & ajout)
{
	lesArticles.push(ajout);				//ajout de l'article dans la liste
	soustotal += ajout.total;				//ajout du total pour l'article au soustotal de la facture
	rabais += ajout.rabais*ajout.soustotal;	//accumulation des rabais par article
	nbArticle += ajout.qty;					//accumulation des quantité au nombre d'article
}

//formatage de sortiem surcharge d'operateur stream <<, usage telque cout << objet
ostream& operator<<(ostream& output, facture& input) 
{
	//entete de facture
	output << setprecision(2) << fixed << left << setw (70) << "Magasin chez Ti-Pere" << right << setw(8) << "No : "<< input.numFacture << endl
			<< left << setw (69) << "2550 blv. Portland" << right << setw(9) << input.date << endl
			<< "Sherbrooke, Qc\n"
			<< "(819) 555-7662\n"
			<< "-------------------------------------------------------------------------------\n"
			<< "Client : " << left << setw(15) << input.clientID << input.Prenom << ' ' << input.Nom << "\n\n"
			<< "    No.Art. Description  Qty    Prix  Sous-Total  Selection   Rabais  Total\n"
			<< "    =======================================================================\n";
	//chaque article de la liste
	while(!input.lesArticles.empty())  //tanqu'il reste des articles dans la queue
	{
		output << input.lesArticles.front(); 
		input.lesArticles.pop();
	}
	//pied de facture
	output << setprecision(2) << fixed << endl << right << setw (59) << "sous-total : " << setw(15) << input.soustotal << "$\n"
		   << setw (59) << "tps : " << setw(15) << input.tps << "$\n"
		   << setw (59) << "tvq : " << setw(15) << input.tvq << "$\n"
		   << setw (59) << "total : " << setw(15) << input.total << "$\n\n"
		   << setprecision(2) << fixed << " Nb. d'article sur la facture : " << right <<  setw(4) << input.nbArticle 
		   << "   Aujourd'hui, vous avez epargne " << right <<  setw(8) << input.rabais << "$\n"
		   << "    =======================================================================\n"
		   << right << setw(57) << "Merci d'avoir magasine chez Ti-Pere\n"
		   << "    =======================================================================\n\f";
	return output;  // for multiple << operators.
}

//méthode d'objet simple , retourne le satus membre par enumération, 0=nonmembre 1=membre 2=vip
int facture::membre()
{
	if (status == "vip")
		return 2;
	else if(status == "membre")
		return 1;
	return 0;
}

/*=========================
sommaire , un objet pour toute les factures
=========================*/
//constructeur, initialiser avec la date de facturation
sommaire::sommaire(string laDate)
{
	nbFacture = 0;			//nombre de facture générer
	moyArticleClient = 0;	//moyenne d'article par client
	montTotRabais = 0;		//montant total des rabais
	montTotTaxe = 0;		//montant total des taxes
	montTotal = 0;			//montant total avec rabais et taxe
	membre = 0;				//pourcentage de membre
	vip = 0;				//pourcentage de vip
	nonMembre = 0;			//pourcentage de nonmembre
	date = laDate;			//date fournis
}

//fermeture de facture,  surcharge d'operateur (), usage telque objet()
//dans la méthode "Functional" ou les "Functor" fonction objet , il y a la "Closure"
void sommaire::operator()()
{
	if (nbFacture)	// s'il n'y a aucune facture ajouté, il est inutile de continuer
	{
		moyArticleClient /= nbFacture;								//moyenne d'article par client
		montTotAvRabais = montTotal + montTotRabais - montTotTaxe;	//montant total avant rabais et taxe
		membre = (membre/nbFacture) * 100;					//les pourcentages de membre
		nonMembre = (nonMembre/nbFacture) * 100;			//vip
		vip = (vip/nbFacture) * 100;						//et nonmembre
	}
}

//ajout de facture au rapport, surcharge d'operateur +=, usage telque objet += article
//les articles sont directement ajouté à l'objet
void sommaire::operator += (facture & lui)
{
	nbFacture++;						//une facture de plus
	moyArticleClient+=lui.nbArticle;	//accumulation pour la moyenne d'article par client
	montTotal += lui.total;				//accumulation montant total
	montTotRabais += lui.rabais;		//accumulation montant total des rabais
	montTotTaxe += lui.tps + lui.tvq;	//accumulation montant total des taxes
	switch(lui.membre())			//accumulation pour les statistique membre nonmembre et vip
	{
	case 0:
		nonMembre++;
		break;
	case 1:
		membre++;
		break;
	case 2:
		vip++;
		break;
	}
}

//formatage de sortiem surcharge d'operateur stream <<, usage telque cout << objet
ostream& operator<<(ostream& output, sommaire& input) 
{
	if (input.nbFacture)
	{
		output << setprecision(2) << fixed << right << setw(46) << "Sommaire des factures du " << input.date << "\n"
			   << setw(56) << "===================================" << "\n\n"
				<< setw(42) << "Nombre de factures :" << setw(14) << input.nbFacture << endl
				<< setw(42) << "Moyenne d'article par client :" << setw(14) << (int)input.moyArticleClient <<"\n\n"
				<< setw(42) << "Montant total des factures avant rabais :" << setw(12) << input.montTotAvRabais << " $\n"
				<< setw(42) << "Montant total des rabais :" << setw(12) << input.montTotRabais << " $\n"
				<< setw(42) << "Montant total des taxes :" << setw(12) << input.montTotTaxe << " $\n"
				<< setw(42) << "Montant total avec rabais et taxes :" << setw(12) << input.montTotal << " $\n\n"
				<< setw(42) << "Clients membre :" << setw(12) << input.membre << " %\n"
				<< setw(42) << "Clients VIP :" << setw(12) << input.vip << " %\n"
				<< setw(42) << "Clients Non-membre :" << setw(12) << input.nonMembre << " %\n";
	}
	else
		cout << "aucune vente pour la journee de " << input.date << endl;
	return output;  // for multiple << operators.
}