github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/client/GUI/onglets/inscriptions.go (about) 1 package onglets 2 3 import ( 4 "fmt" 5 "strings" 6 7 dm "github.com/benoitkugler/goACVE/server/core/datamodel" 8 rd "github.com/benoitkugler/goACVE/server/core/rawdata" 9 10 "github.com/benoitkugler/goACVE/client/GUI/common" 11 12 "github.com/benoitkugler/goACVE/client/GUI/lists" 13 "github.com/therecipe/qt/core" 14 15 "github.com/benoitkugler/goACVE/client/GUI/basic" 16 "github.com/therecipe/qt/widgets" 17 18 "github.com/benoitkugler/goACVE/client/controllers" 19 ) 20 21 func (t *Inscriptions) Render() { 22 t.liste.Model().SetData(t.controller.Liste) 23 t.liste.SetSearch(t.controller.Etat.Recherche) 24 t.liste.Fold(t.controller.Etat.CritereIsFolded) 25 if insc := t.controller.Etat.InscriptionCurrent; insc != nil { 26 t.liste.SelectRow(insc) 27 } 28 t.renderSimilaires() 29 t.renderInfo() 30 t.stats.SetData(t.controller.GetStats()) 31 } 32 33 func (t *Inscriptions) renderInfo() { 34 info := t.controller.CurrentInfo() 35 t.info.SetAlignment(core.Qt__AlignLeft) 36 if info == "" { 37 t.info.SetAlignment(core.Qt__AlignCenter) 38 info = "<i>Aucun message.</i>" 39 } 40 t.info.SetText(info) 41 } 42 43 func (t *Inscriptions) renderSimilaires() { 44 var in rd.Personne 45 if acces := t.controller.AsAcces(t.controller.Etat.InscriptionCurrent); acces != nil { 46 in = acces.GetPersonne().RawData() 47 } 48 t.similaires.SetData(in.BasePersonne, bool(in.IsTemporaire)) 49 t.similaires.SetEnabled(t.controller.Etat.InscriptionCurrent != nil) 50 } 51 52 func (t *Inscriptions) ConfirmeSupprimeDossier(facture dm.AccesFacture) bool { 53 msg := fmt.Sprintf("Voulez-vous vraiment <b>supprimer</b> l'inscription de <i>%s</i> (comprenant %d participant(s))?", 54 facture.GetPersonne().RawData().NomPrenom(), len(facture.GetDossiers(nil))) 55 return basic.Confirmation(msg, "Supprimer", basic.ONDelete) 56 } 57 58 func (t *Inscriptions) DemandeEnvoiAccuseReception(respo rd.Personne) controllers.ChoixEnvoi { 59 dialog := basic.Dialog2("Accusé de réception") 60 msg := fmt.Sprintf("Souhaitez-vous envoyer l'accusé de réception à %s - <b>%s</b>?", respo.NomPrenom(), respo.Mail) 61 62 var out controllers.ChoixEnvoi 63 btnCancel := basic.Button("Ne pas envoyer") 64 btnCancel.SetObjectName(basic.ONDelete) 65 btnCancel.ConnectClicked(func(_ bool) { 66 out = controllers.NoEnvoi 67 dialog.Reject() 68 }) 69 70 btnEnvoi := basic.Button("Envoyer") 71 btnEnvoi.SetObjectName(basic.ONAction) 72 btnEnvoi.ConnectClicked(func(_ bool) { 73 out = controllers.Envoi 74 dialog.Accept() 75 }) 76 77 btnEnvoiBascule := basic.Button("Envoyer et aller au dossier") 78 btnEnvoiBascule.SetObjectName(basic.ONAction) 79 btnEnvoiBascule.ConnectClicked(func(_ bool) { 80 out = controllers.EnvoiEtBascule 81 dialog.Accept() 82 }) 83 84 layout := widgets.NewQVBoxLayout2(dialog) 85 layout.AddWidget(basic.Label(msg), 2, 0) 86 btnsLay := widgets.NewQHBoxLayout() 87 btnsLay.AddWidget(btnCancel, 1, core.Qt__AlignLeft) 88 btnsLay.AddWidget(btnEnvoiBascule, 1, core.Qt__AlignCenter) 89 btnsLay.AddWidget(btnEnvoi, 1, core.Qt__AlignRight) 90 layout.AddLayout(btnsLay, 1) 91 92 dialog.Exec() 93 return out 94 } 95 96 func (t *Inscriptions) ConfirmeValideMailInvalide(msg string) bool { 97 return basic.Confirmation(msg, "Valider quand même", basic.ONAction) 98 } 99 100 type Inscriptions struct { 101 *widgets.QFrame 102 controller *controllers.Inscriptions 103 parent *widgets.QTabWidget 104 toolbar *widgets.QToolBar 105 106 liste lists.Tree 107 similaires *common.Similaires 108 stats common.Statistics 109 info *widgets.QLabel 110 } 111 112 func newInscriptions(ct *controllers.Inscriptions) *Inscriptions { 113 p := Inscriptions{QFrame: basic.Frame(), controller: ct} 114 p.liste = lists.Tree{ 115 Liste: lists.Liste{ 116 Headers: ct.Header, 117 Placeholder: "Aucune inscription.", 118 Title: "Inscriptions", 119 OnSearch: func(pattern string) { 120 ct.Etat.Recherche = pattern 121 ct.Reset() 122 }, 123 OnSort: func(field rd.Field, reverse bool) { 124 ct.Etat.CriteresTri = ct.Etat.CriteresTri.AddCritere(field, reverse) 125 ct.Reset() 126 }, 127 OnClick: func(acces rd.Item, _ int) { 128 ct.Etat.InscriptionCurrent = acces.Id 129 // pour permettre un oudble click, on ne reset pas commplètement 130 p.UpdateToolbar() 131 p.renderInfo() 132 p.renderSimilaires() 133 }, 134 OnRightClick: func(acces rd.Item, pos *core.QPoint) { 135 menu := widgets.NewQMenu(p.liste.View) 136 menu.AddAction("Aller à ...").ConnectTriggered(func(_ bool) { 137 switch acces := ct.AsAcces(acces.Id).(type) { 138 case dm.Inscrit: 139 ct.Main().Controllers.Camps.SelectParticipant(acces) 140 case dm.AccesFacture: 141 ct.Main().Controllers.Personnes.SelectPersonne(acces.GetPersonne()) 142 } 143 }) 144 p.liste.ShowContextMenu(menu, pos) 145 }, 146 }, 147 } 148 p.liste.Init() 149 p.liste.HorizontalHeader().SetMinimumSectionSize(150) 150 p.liste.FoldButton.ConnectClicked(func(checked bool) { 151 ct.Etat.CritereIsFolded = checked 152 ct.Reset() 153 }) 154 155 // tri initial 156 ct.Etat.CriteresTri = ct.Etat.CriteresTri.AddCritere(dm.InscriptionDateHeure, true) 157 ct.Reset() 158 159 p.similaires = common.NewSimilaires(ct.Base, p.controller.Identifie) 160 p.stats = common.NewStatistics(true) 161 162 p.info = basic.Label("") 163 p.info.SetWordWrap(true) 164 infoArea := widgets.NewQScrollArea(nil) 165 infoArea.SetObjectName("cadre-info") 166 infoArea.SetWidget(p.info) 167 infoArea.SetWidgetResizable(true) 168 infoArea.SetMinimumHeight(100) 169 infoArea.SetMaximumWidth(300) 170 171 lay := widgets.NewQVBoxLayout2(p) 172 lay.AddWidget(p.stats, 0, 0) 173 lay.AddWidget(p.liste, 3, 0) 174 bas := widgets.NewQHBoxLayout() 175 bas.AddWidget(p.similaires, 3, 0) 176 bas.AddWidget(infoArea, 1, 0) 177 lay.AddLayout(bas, 2) 178 return &p 179 } 180 181 func (t *Inscriptions) supprimer() { 182 t.controller.SupprimeInscription() 183 } 184 185 func (t *Inscriptions) valider() { 186 basic.Delay(t.controller.Valide) 187 } 188 189 func (t *Inscriptions) loadLog() { 190 d := basic.Dialog("Historique des inscriptions") 191 var ( 192 inscs rd.Inscriptions // all inscriptions 193 data rd.Table // initial inscriptions 194 ) 195 list := lists.Table{ 196 Liste: lists.Liste{ 197 Title: "Inscriptions", 198 MinHeight: 500, 199 MinWidth: 800, 200 Headers: []rd.Header{ 201 {Field: rd.IDateHeure, Label: "Moment d'inscription"}, 202 {Field: rd.IResponsable, Label: "Responsable"}, 203 {Field: rd.INbParticipants, Label: "Nombre de participants"}, 204 }, 205 }, 206 } 207 list.OnSearch = func(pattern string) { 208 if pattern == "" { 209 list.Model().SetData(data) 210 } else { 211 list.Model().SetData(dm.RechercheDetaillee(list.Model().GetData(), pattern, list.Headers)) 212 } 213 } 214 list.OnRightClick = func(acces rd.Item, pos *core.QPoint) { 215 rawInsc := inscs[acces.Id.Int64()] 216 menu := widgets.NewQMenu(t) 217 menu.AddAction("Afficher les détails").ConnectTriggered(func(_ bool) { 218 details := basic.Dialog("Détails") 219 label := t.newLogInscription(rawInsc) 220 label.SetWordWrap(true) 221 scroll := widgets.NewQScrollArea(nil) 222 scroll.SetWidget(label) 223 scroll.SetMaximumHeight(800) 224 scroll.SetMinimumWidth(650) 225 details.Layout().AddWidget(scroll) 226 details.Exec() 227 }) 228 menu.AddSeparator() 229 menu.AddAction("Rejouer l'inscription").ConnectTriggered(func(_ bool) { 230 success := t.controller.RejouerInscription(rawInsc) 231 if !success { 232 return 233 } 234 basic.Confirmation("L'inscription a été enregistrée sur le serveur. <br/> "+ 235 "Veuillez <b>rafraichir</b> les données pour la voir.", "Ok", "") 236 }) 237 238 list.ShowContextMenu(menu, pos) 239 } 240 list.Init() 241 list.View.(*widgets.QTableView).SetColumnWidth(0, 250) 242 list.View.(*widgets.QTableView).SetColumnWidth(1, 350) 243 list.View.(*widgets.QTableView).SetColumnWidth(2, 200) 244 245 d.Layout().AddWidget(list) 246 d.Show() 247 248 basic.Delay(func() { // to avoid freeze 249 inscs = t.controller.LoadLogInscriptions() 250 data = make(rd.Table, 0, len(inscs)) 251 for _, v := range inscs { 252 data = append(data, v.AsItem()) 253 } 254 // tri par moment d'inscription 255 dm.SortBy(data, rd.IDateHeure, true) 256 list.Model().SetData(data) 257 }) 258 } 259 260 // détail une inscription 261 func (t *Inscriptions) newLogInscription(insc rd.Inscription) *widgets.QLabel { 262 html := fmt.Sprintf("[%s] <b>Responsable: </b> %s %s", insc.DateHeure, insc.Responsable.Prenom, insc.Responsable.Nom) 263 html += "<ul>" 264 html += fmt.Sprintf("<li>Sexe: %s</li>", insc.Responsable.Sexe) 265 html += fmt.Sprintf("<li>Date de naissance: %s</li>", insc.Responsable.DateNaissance) 266 html += fmt.Sprintf("<li>Mail: %s</li>", insc.Responsable.Mail) 267 html += fmt.Sprintf("<li>Tels: %s</li>", insc.Responsable.Tels.String()) 268 html += fmt.Sprintf("<li>Adresse: %s</li>", insc.Responsable.Adresse) 269 html += fmt.Sprintf("<li>Code postal: %s</li>", insc.Responsable.CodePostal) 270 html += fmt.Sprintf("<li>Ville: %s</li>", insc.Responsable.Ville) 271 html += fmt.Sprintf("<li>Pays: %s</li>", insc.Responsable.Pays) 272 html += "</ul>" 273 274 html += fmt.Sprintf("<b>Participants: </b>") 275 html += "<ul>" 276 for _, part := range insc.Participants { 277 html += "<li>" 278 html += fmt.Sprintf("%s %s", part.Prenom, part.Nom) 279 html += "<ul>" 280 html += fmt.Sprintf("<li>Date de naissance: %s</li>", part.DateNaissance) 281 html += fmt.Sprintf("<li>Sexe: %s</li>", part.Sexe) 282 html += fmt.Sprintf("<li>Camp: %s</li>", t.controller.Base.Camps[part.IdCamp].Label()) 283 html += "</ul></li>" 284 } 285 html += "</ul>" 286 287 html += fmt.Sprintf("<b>Mails en copie: </b> %s", strings.Join([]string(insc.CopiesMails), ", ")) 288 label := basic.Label(html) 289 return label 290 }