github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/client/controllers/cont_suivi_dossiers_taches.backup (about)

     1  package controllers
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net/http"
     9  	"os"
    10  	"path/filepath"
    11  
    12  	"github.com/benoitkugler/goACVE/server/core/documents"
    13  
    14  	"github.com/benoitkugler/goACVE/server/core/utils/mails"
    15  
    16  	"github.com/benoitkugler/goACVE/server/core/apiserver"
    17  
    18  	dm "github.com/benoitkugler/goACVE/server/core/datamodel"
    19  	rd "github.com/benoitkugler/goACVE/server/core/rawdata"
    20  )
    21  
    22  // Ce fichier définit les différents actions
    23  // liées au suivi d'un dossier.
    24  
    25  // AjoutePaiement ajoute le paiement au dossier courant.
    26  func (c *SuiviDossiers) AjoutePaiement(paiement rd.Paiement) {
    27  	if c.Etat.FactureCurrent == nil {
    28  		c.main.ShowError(errors.New("Aucun dossier courant !"))
    29  		return
    30  	}
    31  	c.main.Controllers.Paiements.CreePaiement(paiement)
    32  }
    33  
    34  func (c *SuiviDossiers) RenderAttestation() string {
    35  	fac := c.Etat.FactureCurrent
    36  	if fac == nil {
    37  		c.main.ShowError(errors.New("Aucun dossier courant !"))
    38  		return ""
    39  	}
    40  	b, err := documents.NewPresence(*fac).Render(nil)
    41  	if err != nil {
    42  		c.main.ShowError(fmt.Errorf("Impossible de générer l'attestation : %s", err))
    43  		return ""
    44  	}
    45  	path := filepath.Join(LocalFolder, "attestation.pdf")
    46  	if err = ioutil.WriteFile(path, b, os.ModePerm); err != nil {
    47  		c.main.ShowError(fmt.Errorf("Impossible d'enregistrer l'attestation : %s", err))
    48  		return ""
    49  	}
    50  	return path
    51  }
    52  
    53  // ------------------- Communication ------------------------------------------
    54  
    55  func (c *SuiviDossiers) envoiSimpleMessage(fac dm.AccesFacture, messageKind rd.MessageKind) {
    56  	message := rd.Message{
    57  		IdFacture: fac.Id,
    58  		Kind:      messageKind,
    59  	}
    60  	params := apiserver.NotifieMessageIn{Message: message}
    61  
    62  	job := func() (interface{}, error) {
    63  		var out apiserver.NotifieMessageOut
    64  		err := Requete(apiserver.UrlNotifieMessages, http.MethodPost, params, &out)
    65  		return out, err
    66  	}
    67  	onSuccess := func(_out interface{}) {
    68  		out := _out.(apiserver.NotifieMessageOut)
    69  		c.Base.Messages[out.Message.Id] = out.Message
    70  		c.main.ShowStandard("Message envoyé avec succès.", false)
    71  		c.Reset()
    72  	}
    73  	if !c.main.Background.EnsureFree() {
    74  		return
    75  	}
    76  	c.main.ShowStandard("Envoi du message...", true)
    77  	c.main.Background.Run(job, onSuccess)
    78  }
    79  
    80  // EnvoiAccuseReception affiche la prévisualisation
    81  // de l'accusé de réception, puis transmet l'envoi au serveur (asynchrone).
    82  func (c *SuiviDossiers) EnvoiAccuseReception(fac dm.AccesFacture, withRIB bool) {
    83  	var detParts []mails.DetailsParticipant
    84  	for _, part := range fac.GetDossiers() {
    85  		detParts = append(detParts, part.GetDetailsMails())
    86  	}
    87  	var (
    88  		labelVirement string
    89  		pjs           []mails.PieceJointe
    90  	)
    91  	if withRIB {
    92  		labelVirement = fac.LabelVirement()
    93  		pjs = []mails.PieceJointe{documents.RIB{}}
    94  	}
    95  	dest, to := fac.GetDestinataire()
    96  	pm := mails.NewParamsAccuseReception(detParts, fac.UrlEspacePerso(), labelVirement, fac.NeedAcompte(),
    97  		mails.Contact{NomPrenom: dest.NomPrenom, Sexe: dest.Sexe})
    98  
    99  	mailHtml := c.Onglet.PrevisualiseMail(pm, pjs, to)
   100  	if mailHtml == "" {
   101  		c.main.ShowStandard("Envoi de l'accusé de réception annulé", false)
   102  		return
   103  	}
   104  
   105  	params := apiserver.ParamsEnvoiAccuseReception{
   106  		Facture: fac.RawData(),
   107  		Html:    mailHtml,
   108  		WithRIB: withRIB,
   109  		To:      to,
   110  		Ccs:     fac.RawData().CopiesMails,
   111  	}
   112  	job := func() (interface{}, error) {
   113  		var out rd.Facture
   114  		err := Requete(apiserver.UrlMailsAccuseReception, http.MethodPost, params, &out)
   115  		return out, err
   116  	}
   117  	onSuccess := func(_out interface{}) {
   118  		out := _out.(rd.Facture)
   119  		c.Base.Factures[out.Id] = out
   120  		c.main.ShowStandard("Accusé de réception envoyé avec succès.", false)
   121  		c.Reset()
   122  
   123  	}
   124  	if !c.main.Background.EnsureFree() {
   125  		return
   126  	}
   127  	c.main.ShowStandard("Envoi de l'accusé de réception...", true)
   128  	c.main.Background.Run(job, onSuccess)
   129  }
   130  
   131  // EnvoiFacture génère et envoie un mail avec une facture en pièce jointe (asynchrone)
   132  // Si isRappel vaut `true`, le mail est simplifié.
   133  func (c *SuiviDossiers) EnvoiFacture(fac dm.AccesFacture, isRappel bool) {
   134  	var detParts []mails.DetailsParticipant
   135  	for _, part := range fac.GetDossiers() {
   136  		if part.RawData().Role.IsInscrit() {
   137  			detParts = append(detParts, part.GetDetailsMails())
   138  		}
   139  	}
   140  	if len(detParts) == 0 {
   141  		c.main.ShowError(errors.New("Aucun participant n'est en liste principale !"))
   142  		return
   143  	}
   144  	dest, to := fac.GetDestinataire()
   145  	pm := mails.NewMetaFacture(detParts,
   146  		mails.Contact{
   147  			NomPrenom: dest.NomPrenom,
   148  			Sexe:      dest.Sexe,
   149  		}, isRappel)
   150  
   151  	pjs := []mails.PieceJointe{documents.NewFacture(fac)}
   152  	mailHtml := c.Onglet.PrevisualiseMail(pm, pjs, to)
   153  	if mailHtml == "" {
   154  		c.main.ShowStandard("Envoi de la facture annulé", false)
   155  		return
   156  	}
   157  	params := apiserver.ParamsEnvoiFacture{
   158  		Facture: fac.RawData(),
   159  		Html:    mailHtml,
   160  		To:      to,
   161  		Ccs:     fac.RawData().CopiesMails,
   162  	}
   163  	job := func() (interface{}, error) {
   164  		var out rd.Facture
   165  		err := Requete(apiserver.UrlMailsFacture, http.MethodPost, params, &out)
   166  		return out, err
   167  	}
   168  	onSuccess := func(_out interface{}) {
   169  		out := _out.(rd.Facture)
   170  		c.Base.Factures[out.Id] = out
   171  		c.main.ShowStandard("Facture envoyée avec succès.", false)
   172  		c.Reset()
   173  
   174  	}
   175  	if !c.main.Background.EnsureFree() {
   176  		return
   177  	}
   178  	c.main.ShowStandard("Envoi de la facture...", true)
   179  	c.main.Background.Run(job, onSuccess)
   180  }
   181  
   182  // EnvoiPlaceLiberee envoie un mail et modifie le rôle
   183  func (c *SuiviDossiers) EnvoiPlaceLiberee(fac dm.AccesFacture, idParticipant int64, newRole rd.Role) {
   184  	dest, to := fac.GetDestinataire()
   185  	part := c.Base.NewParticipant(idParticipant)
   186  	mailPart, mailContact := part.GetDetailsMails().Participant, mails.Contact{
   187  		NomPrenom: dest.NomPrenom,
   188  		Sexe:      dest.Sexe,
   189  	}
   190  	var pm mails.MailRenderer = mails.NewParamsPlaceLiberee(mailPart, mailContact)
   191  	if newRole == rd.RoleInscrit {
   192  		pm = mails.NewParamsConfirmePlaceLiberee(mailPart, mailContact)
   193  	}
   194  	mailHtml := c.Onglet.PrevisualiseMail(pm, nil, to)
   195  	if mailHtml == "" {
   196  		c.main.ShowStandard("Modification et notification annulées.", false)
   197  		return
   198  	}
   199  
   200  	msg := "Envoi d'un mail de notification..."
   201  	if newRole == rd.RoleInscrit {
   202  		msg = "Passage en liste principale..."
   203  	}
   204  	params := apiserver.ParamsEnvoiAttenteToInscrits{
   205  		IdFacture:     fac.Id,
   206  		Html:          mailHtml,
   207  		To:            to,
   208  		Ccs:           fac.RawData().CopiesMails,
   209  		IdParticipant: idParticipant,
   210  		NewRole:       newRole,
   211  	}
   212  	job := func() (interface{}, error) {
   213  		var out rd.Participant
   214  		err := Requete(apiserver.UrlMailsToInscrits, http.MethodPost, params, &out)
   215  		return out, err
   216  	}
   217  	onSuccess := func(_out interface{}) {
   218  		out := _out.(rd.Participant)
   219  		c.Base.Participants[out.Id] = out
   220  		c.main.ShowStandard("Mail envoyé avec succès.", false)
   221  		c.main.ResetAllControllers()
   222  
   223  	}
   224  	if !c.main.Background.EnsureFree() {
   225  		return
   226  	}
   227  	c.main.ShowStandard(msg, true)
   228  	c.main.Background.Run(job, onSuccess)
   229  }
   230  
   231  // EnvoiAttestations envoi les documents demandés par le champ `Attestations`
   232  // de la facture
   233  func (c *SuiviDossiers) EnvoiAttestations(fac dm.AccesFacture) {
   234  	at := fac.RawData().Attestations
   235  	if !at.Facture && !at.Presence {
   236  		c.main.ShowError(errors.New("Aucune attestation n'est demandée pour ce dossier !"))
   237  		return
   238  	}
   239  	bilan := fac.EtatFinancier(false)
   240  	dest, to := fac.GetDestinataire()
   241  	if at.Facture && !bilan.IsAcquitte() {
   242  		msg := "Une facture acquittée est demandée, mais les paiements sont insuffisants."
   243  		c.main.ShowError(errors.New(msg)) // on continue quand même
   244  	}
   245  	withFacture := at.Facture && bilan.IsAcquitte()
   246  	withPresence := at.Presence
   247  	if !withFacture && !withPresence {
   248  		return
   249  	}
   250  
   251  	metaMails := mails.NewParamsAttestations(withPresence, withFacture, mails.Contact{
   252  		NomPrenom: dest.NomPrenom,
   253  		Sexe:      dest.Sexe,
   254  	})
   255  
   256  	var pjs []mails.PieceJointe
   257  	metaFacture := documents.NewFacture(fac)
   258  	metaPresence := documents.NewPresence(fac)
   259  	if withFacture {
   260  		pjs = append(pjs, metaFacture)
   261  	}
   262  	if withPresence {
   263  		pjs = append(pjs, metaPresence)
   264  	}
   265  	mailHtml := c.Onglet.PrevisualiseMail(metaMails, pjs, to)
   266  	if mailHtml == "" {
   267  		c.main.ShowStandard("Envoi des attestations annulé.", false)
   268  		return
   269  	}
   270  
   271  	params := apiserver.ParamsEnvoiAttestations{
   272  		Facture:      fac.RawData(),
   273  		Html:         mailHtml,
   274  		To:           to,
   275  		Ccs:          fac.RawData().CopiesMails,
   276  		WithFacture:  withFacture,
   277  		WithPresence: withPresence,
   278  	}
   279  	job := func() (interface{}, error) {
   280  		var out rd.Facture
   281  		err := Requete(apiserver.UrlMailsAttestations, http.MethodPost, params, &out)
   282  		return out, err
   283  	}
   284  	onSuccess := func(_out interface{}) {
   285  		out := _out.(rd.Facture)
   286  		c.Base.Factures[out.Id] = out
   287  		c.main.ShowStandard("Attestation(s) envoyée(s) avec succès.", false)
   288  		c.Reset()
   289  
   290  	}
   291  	if !c.main.Background.EnsureFree() {
   292  		return
   293  	}
   294  	c.main.ShowStandard("Envoi des attestations...", true)
   295  	c.main.Background.Run(job, onSuccess)
   296  }
   297  
   298  func (c *SuiviDossiers) EnvoiRIB(fac dm.AccesFacture) {
   299  	dest, to := fac.GetDestinataire()
   300  	metaMails := mails.NewParamsEnvoiRIB(mails.Contact{
   301  		NomPrenom: dest.NomPrenom,
   302  		Sexe:      dest.Sexe,
   303  	})
   304  
   305  	pjs := []mails.PieceJointe{documents.RIB{}}
   306  
   307  	mailHtml := c.Onglet.PrevisualiseMail(metaMails, pjs, to)
   308  	if mailHtml == "" {
   309  		c.main.ShowStandard("Envoi du RIB annulé.", false)
   310  		return
   311  	}
   312  
   313  	params := apiserver.ParamsEnvoiRIB{
   314  		Html: mailHtml,
   315  		To:   to,
   316  		Ccs:  fac.RawData().CopiesMails,
   317  	}
   318  	job := func() (interface{}, error) {
   319  		var out string
   320  		err := Requete(apiserver.UrlMailsRIB, http.MethodPost, params, &out)
   321  		return out, err
   322  	}
   323  	onSuccess := func(_out interface{}) {
   324  		out := _out.(string)
   325  		c.main.ShowStandard(out, false)
   326  		c.Reset()
   327  	}
   328  	if !c.main.Background.EnsureFree() {
   329  		return
   330  	}
   331  	c.main.ShowStandard("Envoi du RIB...", true)
   332  	c.main.Background.Run(job, onSuccess)
   333  }
   334  
   335  type envoiDocsHandler struct {
   336  	onError   func(int, string)
   337  	onSuccess func(int, rd.Facture)
   338  
   339  	counter int
   340  }
   341  
   342  func (e *envoiDocsHandler) Write(p []byte) (int, error) {
   343  	outFac := new(rd.Facture)
   344  	if err := json.Unmarshal(p, outFac); err != nil {
   345  		outErr := new(string)
   346  		if err = json.Unmarshal(p, outErr); err != nil {
   347  			return 0, err
   348  		} else {
   349  			e.onError(e.counter, *outErr)
   350  		}
   351  	} else {
   352  		e.onSuccess(e.counter, *outFac)
   353  	}
   354  	e.counter += 1
   355  	return len(p), nil
   356  }
   357  
   358  func (c *SuiviDossiers) FilterFactures(campId int64, factures rd.Table) []int64 {
   359  	var filtredIds []int64
   360  	for _, ac := range factures {
   361  		f := ac.(dm.AccesFacture)
   362  		isConcerned := false
   363  		for _, doss := range f.GetDossiers() {
   364  			if doss.GetCamp().Id == campId {
   365  				isConcerned = true
   366  			}
   367  		}
   368  		if isConcerned {
   369  			filtredIds = append(filtredIds, f.Id)
   370  		}
   371  	}
   372  	return filtredIds
   373  }
   374  
   375  type FacError struct {
   376  	Fac, Err string
   377  }
   378  
   379  // EnvoiDocuments envois les documents du camp donné aux factures données.
   380  // `onError` et `onSuccess` sont exécutées dans le même thread
   381  // à la fin de chaque envoi effectué sur le serveur.
   382  func (c *SuiviDossiers) EnvoiDocuments(campId int64, messagePerso string, filtredIds []int64, onError func(index int, err string),
   383  	onSuccess func(index int, out rd.Facture)) (facErrors []FacError, err error) {
   384  	camp := c.Base.Camps[campId]
   385  	if len(filtredIds) == 0 {
   386  		return nil, fmt.Errorf("Aucun dossier n'est concerné par le <i>%s</i> !", camp.Label())
   387  	}
   388  	params := apiserver.ParamsEnvoiDocuments{
   389  		IdCamp:       campId,
   390  		IdsFactures:  filtredIds,
   391  		MessagePerso: messagePerso,
   392  	}
   393  	facErrors = []FacError{}
   394  	writer := envoiDocsHandler{
   395  		onError: func(i int, s string) {
   396  			fac := c.Base.NewFacture(filtredIds[i])
   397  			facErrors = append(facErrors, FacError{
   398  				Fac: fac.GetResponsable().RawData().NomPrenom(),
   399  				Err: s,
   400  			})
   401  			onError(i, s)
   402  		},
   403  		onSuccess: func(i int, facture rd.Facture) {
   404  			onSuccess(i, facture)
   405  		},
   406  	}
   407  	if err := RequestMonitor(apiserver.UrlMailsDocuments, http.MethodPost, params, &writer); err != nil {
   408  		return nil, fmt.Errorf("Impossible de lancer l'envoi des mails : %s", err)
   409  	}
   410  	return facErrors, nil
   411  }