github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/acvegestion/crudspec.go (about) 1 package acvegestion 2 3 import ( 4 "database/sql" 5 "errors" 6 "fmt" 7 "time" 8 9 "github.com/benoitkugler/goACVE/server/core/apiserver" 10 rd "github.com/benoitkugler/goACVE/server/core/rawdata" 11 "github.com/benoitkugler/goACVE/server/core/rawdata/composites" 12 "github.com/benoitkugler/goACVE/server/core/utils/mails" 13 "github.com/benoitkugler/goACVE/server/shared" 14 "github.com/labstack/echo" 15 ) 16 17 const notifDonReplyTo = "contact@acve.asso.fr" 18 19 // ajoute les actions spécifiques au CRUD 20 21 func (ct Controller) deleteAide(idAide int64) (rd.Ids, error) { 22 tx, err := ct.DB.Begin() 23 if err != nil { 24 return nil, err 25 } 26 27 // liens 28 rows, err := tx.Query("DELETE FROM document_aides WHERE id_aide = $1 RETURNING id_document", idAide) 29 if err != nil { 30 return nil, shared.Rollback(tx, err) 31 } 32 deletedDocuments, err := rd.ScanIds(rows) 33 if err != nil { 34 return nil, shared.Rollback(tx, err) 35 } 36 37 //documents 38 _, err = rd.DeleteDocumentsByIds(tx, deletedDocuments...) 39 if err != nil { 40 return nil, shared.Rollback(tx, err) 41 } 42 43 _, err = rd.DeleteAideById(tx, idAide) 44 if err != nil { 45 return nil, shared.Rollback(tx, err) 46 } 47 err = tx.Commit() 48 return deletedDocuments, err 49 } 50 51 func (ct Controller) createCamp(params apiserver.CreateCampIn) (rd.Camp, error) { 52 tx, err := ct.DB.Begin() 53 if err != nil { 54 return rd.Camp{}, err 55 } 56 camp, err := params.Camp.Insert(tx) 57 if err != nil { 58 return camp, shared.Rollback(tx, err) 59 } 60 61 // on importe le html de la lettre directeur 62 if idCamp := params.CopyLettreFrom; idCamp.IsNotNil() { 63 lettre, found, err := rd.SelectLettredirecteurByIdCamp(tx, idCamp.Int64) 64 if err != nil { 65 return camp, shared.Rollback(tx, err) 66 } 67 if found { 68 lettre.IdCamp = camp.Id 69 err = rd.InsertManyLettredirecteurs(tx, lettre) 70 if err != nil { 71 return camp, shared.Rollback(tx, err) 72 } 73 } // sinon, le camp source n'a pas de lettre, on ne fait rien 74 75 // copie des potentielles images associées 76 // le lien d'accès n'est pas changé ce qui évite de devoir modifier 77 // le contenu de la lettre 78 imgs, err := rd.SelectImageuploadedsByIdCamps(tx, idCamp.Int64) 79 if err != nil { 80 return camp, shared.Rollback(tx, err) 81 } 82 for i := range imgs { 83 imgs[i].IdCamp = camp.Id // on redirige vers le nouveau camp 84 } 85 err = rd.InsertManyImageuploadeds(tx, imgs...) 86 if err != nil { 87 return camp, shared.Rollback(tx, err) 88 } 89 90 // les tables lettre et images sont ignorées par le client : 91 // on en renvoit rien 92 } 93 err = tx.Commit() 94 return camp, err 95 } 96 97 // CreateCamp ajoute un camp 98 func (ct Controller) CreateCamp(c echo.Context) error { 99 if err := authentifie(c); err != nil { 100 return err 101 } 102 var in apiserver.CreateCampIn 103 if err := c.Bind(&in); err != nil { 104 return fmt.Errorf("Camp invalide : %s", err) 105 } 106 out, err := ct.createCamp(in) 107 if err != nil { 108 return err 109 } 110 return c.JSON(200, out) 111 } 112 113 // UpdateCamp met à jour et renvoie le camp modifié; le statut simple 114 // ne peut pas être modifié. 115 func (ct Controller) UpdateCamp(c echo.Context) error { 116 if err := authentifie(c); err != nil { 117 return err 118 } 119 in := new(rd.Camp) 120 if err := c.Bind(in); err != nil { 121 return fmt.Errorf("Camp invalide : %s", err) 122 } 123 trueCamp, err := rd.SelectCamp(ct.DB, in.Id) 124 if err != nil { 125 return err 126 } 127 if trueCamp.InscriptionSimple != in.InscriptionSimple { 128 return errors.New("Le mode d'inscription ne peut pas être modifié.") 129 } 130 updated, err := in.Update(ct.DB) 131 if err != nil { 132 return err 133 } 134 return c.JSON(200, updated) 135 } 136 137 // renvoie une erreur si un équipier ou un participant est encore inscrit 138 // en revanche, cascade la suppression des groupes et documents du séjour 139 func (ct Controller) deleteCamp(idCamp int64) (apiserver.DeleteCampOut, error) { 140 var out apiserver.DeleteCampOut 141 tx, err := ct.DB.Begin() 142 if err != nil { 143 return out, err 144 } 145 146 // liens documents 147 rows, err := tx.Query("DELETE FROM document_camps WHERE id_camp = $1 RETURNING id_document", idCamp) 148 if err != nil { 149 return out, shared.Rollback(tx, err) 150 } 151 out.IdsDocuments, err = rd.ScanIds(rows) 152 if err != nil { 153 return out, shared.Rollback(tx, err) 154 } 155 156 //documents 157 _, err = rd.DeleteDocumentsByIds(tx, out.IdsDocuments...) 158 if err != nil { 159 return out, shared.Rollback(tx, err) 160 } 161 162 // contraintes demandées 163 _, err = rd.DeleteCampContraintesByIdCamps(tx, idCamp) 164 if err != nil { 165 return out, shared.Rollback(tx, err) 166 } 167 168 // liens groupes 169 _, err = tx.Exec(`DELETE FROM groupe_contraintes 170 USING groupes WHERE groupes.id_camp = $1 AND 171 groupe_contraintes.id_groupe = groupes.id`, idCamp) 172 if err != nil { 173 return out, shared.Rollback(tx, err) 174 } 175 176 // groupes 177 out.IdsGroupes, err = rd.DeleteGroupesByIdCamps(tx, idCamp) 178 if err != nil { 179 return out, shared.Rollback(tx, err) 180 } 181 182 _, err = rd.DeleteCampById(tx, idCamp) 183 if err != nil { 184 return out, shared.Rollback(tx, err) 185 } 186 err = tx.Commit() 187 return out, err 188 } 189 190 // DeleteCamp supprime 191 func (ct Controller) DeleteCamp(c echo.Context) error { 192 if err := authentifie(c); err != nil { 193 return err 194 } 195 id, err := shared.ParseId(c, "id") 196 if err != nil { 197 return fmt.Errorf("Id (Camp) invalide : %s", err) 198 } 199 out, err := ct.deleteCamp(id) 200 if err != nil { 201 return err 202 } 203 return c.JSON(200, out) 204 } 205 206 // charger les données et trouve un groupe pour le nouveau participant 207 // ne commit ni ne rollback 208 func (ct Controller) findGroupe(tx *sql.Tx, participant rd.Participant) (rd.GroupeParticipant, bool, error) { 209 personne, err := rd.SelectPersonne(tx, participant.IdPersonne) 210 if err != nil { 211 return rd.GroupeParticipant{}, false, err 212 } 213 // charge le camp et les groupes 214 camp, err := rd.SelectCamp(tx, participant.IdCamp) 215 if err != nil { 216 return rd.GroupeParticipant{}, false, err 217 } 218 219 groupes, err := rd.SelectGroupesByIdCamps(tx, camp.Id) 220 if err != nil { 221 return rd.GroupeParticipant{}, false, err 222 } 223 var gp rd.GroupeParticipant 224 groupe, foundGroupe := composites.NewCampGroupes(camp, groupes).TrouveGroupe(personne.DateNaissance) 225 if foundGroupe { // on ajoute 226 gp = rd.GroupeParticipant{IdCamp: camp.Id, IdGroupe: groupe.Id, IdParticipant: participant.Id} 227 err = rd.InsertManyGroupeParticipants(tx, gp) 228 if err != nil { 229 return rd.GroupeParticipant{}, false, err 230 } 231 } 232 return gp, foundGroupe, nil 233 } 234 235 // CreateParticipant ajoute et renvoie, avec un éventuel groupe 236 func (ct Controller) CreateParticipant(c echo.Context) error { 237 if err := authentifie(c); err != nil { 238 return err 239 } 240 in := new(rd.Participant) 241 if err := c.Bind(in); err != nil { 242 return fmt.Errorf("Participant invalide : %s", err) 243 } 244 tx, err := ct.DB.Begin() 245 if err != nil { 246 return err 247 } 248 var out apiserver.CreateParticipantOut 249 out.Participant, err = in.Insert(tx) 250 if err != nil { 251 return shared.Rollback(tx, err) 252 } 253 254 out.GroupeParticipant, out.FoundGroupe, err = ct.findGroupe(tx, out.Participant) 255 if err != nil { 256 return shared.Rollback(tx, err) 257 } 258 if err = tx.Commit(); err != nil { 259 return err 260 } 261 return c.JSON(200, out) 262 } 263 264 // UpdateParticipant met à jour le groupe si le camp change 265 func (ct Controller) UpdateParticipant(c echo.Context) error { 266 if err := authentifie(c); err != nil { 267 return err 268 } 269 in := new(rd.Participant) 270 if err := c.Bind(in); err != nil { 271 return fmt.Errorf("Participant invalide : %s", err) 272 } 273 tx, err := ct.DB.Begin() 274 if err != nil { 275 return err 276 } 277 currentParticipant, err := rd.SelectParticipant(tx, in.Id) 278 if err != nil { 279 return shared.Rollback(tx, err) 280 } 281 isChangingCamp := in.IdCamp != currentParticipant.IdCamp 282 if isChangingCamp { 283 // on doit transférer un éventuel groupe 284 _, err := rd.DeleteGroupeParticipantsByIdParticipants(tx, in.Id) 285 if err != nil { 286 return shared.Rollback(tx, err) 287 } 288 } 289 var out apiserver.CreateParticipantOut 290 out.Participant, err = in.Update(tx) 291 if err != nil { 292 return shared.Rollback(tx, err) 293 } 294 if isChangingCamp { 295 // on affecte à un nouveau groupe 296 out.GroupeParticipant, out.FoundGroupe, err = ct.findGroupe(tx, out.Participant) 297 if err != nil { 298 return shared.Rollback(tx, err) 299 } 300 } 301 if err = tx.Commit(); err != nil { 302 return err 303 } 304 return c.JSON(200, out) 305 } 306 307 // CreateFacture génère une clé unique, ratache les participants donnés à la facture 308 // et renvois la facture et les participants mis à jour. 309 // Note: Si un participant était déjà dans un dossier, il est simplement redirigé. 310 func (ct Controller) CreateFacture(c echo.Context) error { 311 if err := authentifie(c); err != nil { 312 return err 313 } 314 in := new(apiserver.CreateFactureIn) 315 if err := c.Bind(in); err != nil { 316 return fmt.Errorf("Facture invalide : %s", err) 317 } 318 tx, err := ct.DB.Begin() 319 if err != nil { 320 return err 321 } 322 key, err := shared.GetNewKey(tx) 323 if err != nil { 324 err = fmt.Errorf("Création de la clé du dossier impossible : %s", err) 325 return shared.Rollback(tx, err) 326 } 327 // l'inscription est créé par le centre, donc elle est valide 328 // le champ IsConfirmed n'a pas vraiment de sens : il faut mieux 329 // le cocher pour éviter des avertissements 330 // On permet le partage des coordonnées: permissif par défaut 331 fac := rd.Facture{IdPersonne: in.IdResponsable, Key: rd.String(key), 332 IsValidated: true, IsConfirmed: true, PartageAdressesOK: true} 333 fac, err = fac.Insert(tx) 334 if err != nil { 335 return shared.Rollback(tx, err) 336 } 337 out := apiserver.CreateFactureOut{Facture: fac} 338 339 rows, err := tx.Query("UPDATE participants SET id_facture = $1 WHERE id = ANY($2) RETURNING *", 340 fac.Id, in.IdParticipants.AsSQL()) 341 if err != nil { 342 return shared.Rollback(tx, err) 343 } 344 out.Participants, err = rd.ScanParticipants(rows) 345 if err != nil { 346 return shared.Rollback(tx, err) 347 } 348 349 // enregistre le moment "d'inscription" 350 out.Message = rd.Message{Kind: rd.MInscription, Created: rd.Time(time.Now()), IdFacture: fac.Id} 351 out.Message, err = out.Message.Insert(tx) 352 if err != nil { 353 return shared.Rollback(tx, err) 354 } 355 356 if err = tx.Commit(); err != nil { 357 return err 358 } 359 return c.JSON(200, out) 360 } 361 362 // supprime la facture et les paiements associés, 363 // et met à jour les participants si besoin 364 func (ct Controller) deleteFacture(id int64) (apiserver.DeleteFactureOut, error) { 365 var out apiserver.DeleteFactureOut 366 tx, err := ct.DB.Begin() 367 if err != nil { 368 return out, err 369 } 370 371 out.DeletedPaiements, err = rd.DeletePaiementsByIdFactures(tx, id) 372 if err != nil { 373 return out, shared.Rollback(tx, err) 374 } 375 376 rows, err := tx.Query("UPDATE participants SET id_facture = NULL WHERE id_facture = $1 RETURNING *", id) 377 if err != nil { 378 return out, shared.Rollback(tx, err) 379 } 380 out.Participants, err = rd.ScanParticipants(rows) 381 if err != nil { 382 return out, shared.Rollback(tx, err) 383 } 384 385 _, err = rd.DeleteFactureById(tx, id) 386 if err != nil { 387 return out, shared.Rollback(tx, err) 388 } 389 err = tx.Commit() 390 return out, err 391 } 392 393 // supprime aussi les aides (et leurs justificatifs) 394 // si le participant est temporaire, supprime aussi la personne associée 395 func (ct Controller) deleteParticipant(id int64) (apiserver.DeleteParticipantOut, error) { 396 tx, err := ct.DB.Begin() 397 if err != nil { 398 return apiserver.DeleteParticipantOut{}, err 399 } 400 out, err := deleteOneParticipant(tx, id) 401 if err != nil { 402 return out, shared.Rollback(tx, err) 403 } 404 err = tx.Commit() 405 return out, err 406 } 407 408 // supprime aussi les aides associées (et leurs documents) 409 func (ct Controller) deleteStructureaide(id int64) (apiserver.DeleteStructureaideOut, error) { 410 var out apiserver.DeleteStructureaideOut 411 tx, err := ct.DB.Begin() 412 if err != nil { 413 return out, err 414 } 415 416 // liens documents 417 rows, err := tx.Query(`DELETE FROM document_aides 418 USING aides WHERE aides.id = document_aides.id_aide AND aides.id_structureaide = $1 419 RETURNING document_aides.id_document`, id) 420 if err != nil { 421 return out, shared.Rollback(tx, err) 422 } 423 out.IdsDocuments, err = rd.ScanIds(rows) 424 if err != nil { 425 return out, shared.Rollback(tx, err) 426 } 427 428 _, err = rd.DeleteDocumentsByIds(tx, out.IdsDocuments...) 429 if err != nil { 430 return out, shared.Rollback(tx, err) 431 } 432 433 out.IdsAides, err = rd.DeleteAidesByIdStructureaides(tx, id) 434 if err != nil { 435 return out, shared.Rollback(tx, err) 436 } 437 438 _, err = rd.DeleteStructureaideById(tx, id) 439 if err != nil { 440 return out, shared.Rollback(tx, err) 441 } 442 err = tx.Commit() 443 return out, err 444 } 445 446 // si l'équipier est temporaire, supprime aussi la personne associée (et ses documents) 447 func (ct Controller) deleteEquipier(id int64) (apiserver.DeleteEquipierOut, error) { 448 var out apiserver.DeleteEquipierOut 449 450 tx, err := ct.DB.Begin() 451 if err != nil { 452 return out, err 453 } 454 455 equipier, err := rd.DeleteEquipierById(tx, id) 456 if err != nil { 457 return out, shared.Rollback(tx, err) 458 } 459 460 isTmp, docs, err := shared.DeletePersonne(tx, equipier.IdPersonne) 461 if err != nil { 462 return out, shared.Rollback(tx, err) 463 } 464 out.IdsDocuments = docs 465 466 // si la personne était temporaire 467 out.IdPersonne = -1 468 if isTmp { 469 out.IdPersonne = equipier.IdPersonne 470 } 471 472 err = tx.Commit() 473 return out, err 474 } 475 476 func (ct Controller) deleteDocument(id int64) (rd.Contraintes, error) { 477 tx, err := ct.DB.Begin() 478 if err != nil { 479 return nil, err 480 } 481 482 // les liens et le contenu cascadent 483 484 // contrainte 485 rows, err := tx.Query("UPDATE contraintes SET id_document = NULL WHERE id_document = $1 RETURNING *", id) 486 if err != nil { 487 return nil, shared.Rollback(tx, err) 488 } 489 contraintes, err := rd.ScanContraintes(rows) 490 if err != nil { 491 return nil, shared.Rollback(tx, err) 492 } 493 _, err = rd.DeleteDocumentById(tx, id) 494 if err != nil { 495 return nil, shared.Rollback(tx, err) 496 } 497 err = tx.Commit() 498 return contraintes, err 499 } 500 501 // supprime les liens et marque le message 502 func (ct Controller) deleteMessages(ids rd.Ids) (rd.Messages, error) { 503 // on ne supprime pas vraiment, on change 'kind', donc on doit "manuellement" 504 // supprimer les liens 505 tx, err := ct.DB.Begin() 506 if err != nil { 507 return nil, err 508 } 509 for _, table := range rd.ComplementMessagesTables { 510 _, err := tx.Exec(fmt.Sprintf("DELETE FROM %s WHERE id_message = ANY($1)", table), ids.AsSQL()) 511 if err != nil { 512 return nil, shared.Rollback(tx, err) 513 } 514 } 515 rows, err := tx.Query("UPDATE messages SET (kind, modified) = ($1 , $2) WHERE id = ANY($3) RETURNING *", 516 rd.MSupprime, rd.Time(time.Now()), ids.AsSQL()) 517 if err != nil { 518 return nil, shared.Rollback(tx, err) 519 } 520 out, err := rd.ScanMessages(rows) 521 if err != nil { 522 return nil, shared.Rollback(tx, err) 523 } 524 err = tx.Commit() 525 return out, err 526 } 527 528 // DeleteMessages supprime 529 func (ct Controller) DeleteMessages(c echo.Context) error { 530 if err := authentifie(c); err != nil { 531 return err 532 } 533 var ids rd.Ids 534 if err := c.Bind(&ids); err != nil { 535 return fmt.Errorf("Ids (Messages) invalides : %s", err) 536 } 537 out, err := ct.deleteMessages(ids) 538 if err != nil { 539 return err 540 } 541 return c.JSON(200, out) 542 } 543 544 // Ajoute l'équipier transmit et ajoute des contraintes par défaut 545 func (ct Controller) CreateEquipier(c echo.Context) error { 546 if err := authentifie(c); err != nil { 547 return err 548 } 549 in := new(rd.Equipier) 550 if err := c.Bind(in); err != nil { 551 return fmt.Errorf("Equipier invalide : %s", err) 552 } 553 tx, err := ct.DB.Begin() 554 if err != nil { 555 return err 556 } 557 var out apiserver.CreateEquipierOut 558 out.Equipier, err = in.Insert(tx) 559 if err != nil { 560 return shared.Rollback(tx, err) 561 } 562 out.Contraintes, err = shared.AddEquipierDefautContraintes(tx, ct.ContraintesEquipiers, out.Equipier) 563 if err != nil { 564 return shared.Rollback(tx, err) 565 } 566 if err = tx.Commit(); err != nil { 567 return err 568 } 569 return c.JSON(200, out) 570 } 571 572 func (ct Controller) CreateDon(c echo.Context) error { 573 if err := authentifie(c); err != nil { 574 return err 575 } 576 var in apiserver.CreateDonIn 577 if err := c.Bind(&in); err != nil { 578 return fmt.Errorf("Détails du don invalides : %s", err) 579 } 580 out, err := ct.createDon(in) 581 if err != nil { 582 return err 583 } 584 return c.JSON(200, out) 585 } 586 587 // inscrit le don et envoie un mail de remerciement, sauf pour les dons Helloasso 588 func (ct Controller) createDon(params apiserver.CreateDonIn) (apiserver.CreateDonIn, error) { 589 tx, err := ct.DB.Begin() 590 if err != nil { 591 return params, err 592 } 593 params.Don, err = params.Don.Insert(tx) 594 if err != nil { 595 return params, shared.Rollback(tx, err) 596 } 597 // ajout de l'id nouvellement créé 598 params.Donateur.IdDon = params.Don.Id 599 600 // on n'ajoute pas de lien pour les dons anonymes 601 if params.Donateur.IId() != nil { 602 err = rd.InsertManyDonDonateurs(tx, params.Donateur) 603 if err != nil { 604 return params, shared.Rollback(tx, err) 605 } 606 } 607 608 // mail de remerciement 609 if params.Notifie && params.Don.ModePaiement != rd.MPHelloasso { 610 611 // on résoud le donateur 612 contact, mail := mails.Contact{}, "" 613 if p := params.Donateur.IdPersonne; p.IsNotNil() { 614 donateur, err := rd.SelectPersonne(tx, p.Int64) 615 if err != nil { 616 return params, shared.Rollback(tx, err) 617 } 618 contact = mails.Contact{Prenom: donateur.FPrenom(), Sexe: donateur.Sexe} 619 mail = donateur.Mail.String() 620 } else if p := params.Donateur.IdOrganisme; p.IsNotNil() { 621 orga, err := rd.SelectOrganisme(tx, p.Int64) 622 if err != nil { 623 return params, shared.Rollback(tx, err) 624 } 625 if p := orga.IdContactDon; p.IsNotNil() { 626 donateur, err := rd.SelectPersonne(tx, p.Int64) 627 if err != nil { 628 return params, shared.Rollback(tx, err) 629 } 630 contact = mails.Contact{Prenom: donateur.FPrenom(), Sexe: donateur.Sexe} 631 mail = donateur.Mail.String() 632 } else if p := orga.IdContact; p.IsNotNil() { 633 donateur, err := rd.SelectPersonne(tx, p.Int64) 634 if err != nil { 635 return params, shared.Rollback(tx, err) 636 } 637 contact = mails.Contact{Prenom: donateur.FPrenom(), Sexe: donateur.Sexe} 638 mail = donateur.Mail.String() 639 } else { // adresse propre 640 contact = mails.Contact{} 641 mail = orga.Contact.Mail.String() 642 } 643 } 644 645 if mail == "" { 646 return params, shared.Rollback(tx, errors.New("Aucune adresse mail.")) 647 } 648 649 body, err := mails.NewNotificationDon(contact, params.Don.Valeur) 650 if err != nil { 651 return params, shared.Rollback(tx, err) 652 } 653 err = mails.NewMailer(ct.SMTP).SendMail(mail, "[ACVE] - Remerciement", body, nil, 654 mails.CustomReplyTo(notifDonReplyTo)) 655 if err != nil { 656 return params, shared.Rollback(tx, err) 657 } 658 } 659 660 err = tx.Commit() 661 return params, err 662 } 663 664 func (ct Controller) UpdateDon(c echo.Context) error { 665 if err := authentifie(c); err != nil { 666 return err 667 } 668 var in apiserver.CreateDonIn 669 if err := c.Bind(&in); err != nil { 670 return fmt.Errorf("Détails du don invalides : %s", err) 671 } 672 out, err := ct.updateDon(in) 673 if err != nil { 674 return err 675 } 676 return c.JSON(200, out) 677 } 678 679 func (ct Controller) updateDon(params apiserver.CreateDonIn) (apiserver.CreateDonIn, error) { 680 tx, err := ct.DB.Begin() 681 if err != nil { 682 return params, err 683 } 684 params.Don, err = params.Don.Update(tx) 685 if err != nil { 686 return params, shared.Rollback(tx, err) 687 } 688 689 // on assure la cohérence, sait-on jamais ? 690 params.Donateur.IdDon = params.Don.Id 691 692 // suppression de l'ancien lien ... 693 _, err = rd.DeleteDonDonateursByIdDons(tx, params.Don.Id) 694 if err != nil { 695 return params, shared.Rollback(tx, err) 696 } 697 // ... et ajout du nouveau 698 // on n'ajoute pas de lien pour les dons anonymes 699 if params.Donateur.IId() != nil { 700 err = rd.InsertManyDonDonateurs(tx, params.Donateur) 701 if err != nil { 702 return params, shared.Rollback(tx, err) 703 } 704 } 705 err = tx.Commit() 706 return params, err 707 } 708 709 func (ct Controller) deleteOrganisme(id int64) (apiserver.DeleteOrganismeOut, error) { 710 out := apiserver.DeleteOrganismeOut{Id: id} 711 tx, err := ct.DB.Begin() 712 if err != nil { 713 return out, err 714 } 715 liens, err := rd.DeleteDonDonateursByIdOrganismes(tx, id) 716 if err != nil { 717 return out, shared.Rollback(tx, err) 718 } 719 var ids rd.Ids 720 for idDon := range liens.ByIdDon() { 721 ids = append(ids, idDon) 722 } 723 out.Dons, err = rd.DeleteDonsByIds(tx, ids...) 724 if err != nil { 725 return out, shared.Rollback(tx, err) 726 } 727 _, err = rd.DeleteOrganismeById(tx, id) 728 if err != nil { 729 return out, shared.Rollback(tx, err) 730 } 731 err = tx.Commit() 732 return out, err 733 }