001/*
002 *  Copyright 2022 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016
017package org.ametys.plugins.odfsync.pegase.ws.structure;
018
019import java.io.IOException;
020import java.math.BigDecimal;
021import java.util.HashMap;
022import java.util.HashSet;
023import java.util.List;
024import java.util.Map;
025import java.util.Optional;
026import java.util.Set;
027import java.util.regex.Pattern;
028import java.util.stream.Collectors;
029import java.util.stream.Stream;
030
031import org.apache.avalon.framework.activity.Initializable;
032import org.apache.avalon.framework.component.Component;
033import org.apache.avalon.framework.service.ServiceException;
034import org.apache.avalon.framework.service.ServiceManager;
035import org.apache.commons.lang3.StringUtils;
036
037import org.ametys.cms.data.ContentValue;
038import org.ametys.cms.data.RichText;
039import org.ametys.cms.data.RichTextHelper;
040import org.ametys.cms.repository.Content;
041import org.ametys.odf.ODFHelper;
042import org.ametys.odf.ProgramItem;
043import org.ametys.odf.course.Course;
044import org.ametys.odf.course.CourseFactory;
045import org.ametys.odf.courselist.CourseList;
046import org.ametys.odf.enumeration.OdfReferenceTableEntry;
047import org.ametys.odf.enumeration.OdfReferenceTableHelper;
048import org.ametys.odf.program.AbstractProgram;
049import org.ametys.odf.program.Container;
050import org.ametys.odf.program.Program;
051import org.ametys.odf.program.ProgramFactory;
052import org.ametys.odf.program.ProgramPart;
053import org.ametys.odf.program.SubProgram;
054import org.ametys.plugins.odfsync.export.AbstractExportStructure;
055import org.ametys.plugins.odfsync.export.ExportReport;
056import org.ametys.plugins.odfsync.export.ExportReport.ExportStatus;
057import org.ametys.plugins.odfsync.export.ExportReport.ProblemTypes;
058import org.ametys.plugins.odfsync.pegase.ws.PegaseApiManager;
059import org.ametys.plugins.odfsync.pegase.ws.PegaseExportException;
060import org.ametys.runtime.config.Config;
061import org.ametys.runtime.i18n.I18nizableText;
062import org.ametys.runtime.model.ElementDefinition;
063
064import fr.pcscol.pegase.odf.ApiException;
065import fr.pcscol.pegase.odf.externe.model.Formation;
066import fr.pcscol.pegase.odf.externe.model.Groupement;
067import fr.pcscol.pegase.odf.externe.model.Pageable;
068
069/**
070 * The structure to export the program in Pegase
071 * 
072 * TODO rewrite completely for Pegase 24
073 */
074public class PegaseProgramStructure extends AbstractExportStructure implements Component, Initializable
075{
076    /** Role */
077    public static final String ROLE = PegaseProgramStructure.class.getName();
078//    
079//    /** The attribute name for the code Pégase */
080//    public static final String CODE_PEGASE_ATTRIBUTE_NAME = "codePegase";
081//    
082//    /* Constants */
083//    private static final String __PEGASE_SYNC_CODE = "pegaseSyncCode";
084//    private static final Pattern __PROGRAM_CODE_PATTERN = Pattern.compile("^[A-Z0-9\\-]{3,25}(/[1-9][0-9]*)?$");
085//    private static final Pattern __DEFAULT_CODE_PATTERN = Pattern.compile("^[A-Z0-9\\-]{3,25}$");
086//    private static final String __CODE_FORMATION_DIPLOMANTE = "0";
087//    private static final Map<String, Set<String>> __MANDATORY_ATTRIBUTES_BY_CONTENT_TYPE = new HashMap<>();
088//    static
089//    {
090//        __MANDATORY_ATTRIBUTES_BY_CONTENT_TYPE.put(
091//                ProgramFactory.PROGRAM_CONTENT_TYPE,
092//                Set.of(
093//                        AbstractProgram.DOMAIN,
094//                        AbstractProgram.EDUCATION_KIND,
095//                        AbstractProgram.DEGREE,
096//                        AbstractProgram.LEVEL,
097//                        AbstractProgram.RNCP_LEVEL
098//                )
099//        );
100//        __MANDATORY_ATTRIBUTES_BY_CONTENT_TYPE.put(
101//                CourseFactory.COURSE_CONTENT_TYPE,
102//                Set.of(Course.COURSE_TYPE)
103//        );
104//        __MANDATORY_ATTRIBUTES_BY_CONTENT_TYPE.put(
105//                OdfReferenceTableHelper.DEGREE,
106//                Set.of(
107//                        "degreeNature",
108//                        "cursus"
109//                )
110//        );
111//    }
112//    
113//    /* Components */
114//    private PegaseApiManager _pegaseApiManager;
115//    private ODFHelper _odfHelper;
116//    private RichTextHelper _richTextHelper;
117//
118//    /* Pégase configuration */
119//    private boolean _isActive;
120//    private String _structureCode;
121//    private boolean _trustAmetys;
122    
123    @Override
124    public void service(ServiceManager manager) throws ServiceException
125    {
126        super.service(manager);
127        
128//        _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE);
129//        _richTextHelper = (RichTextHelper) manager.lookup(RichTextHelper.ROLE);
130//        _pegaseApiManager = (PegaseApiManager) manager.lookup(PegaseApiManager.ROLE);
131    }
132    
133    public void initialize() throws Exception
134    {
135//        _isActive = Config.getInstance().getValue("pegase.activate", true, false);
136//        if (_isActive)
137//        {
138//            _structureCode = Config.getInstance().getValue("pegase.structure.code");
139//            _trustAmetys = Config.getInstance().getValue("pegase.trust", true, false);
140//        }
141    }
142    
143//    private String _getPegaseCodeOrCode(Content content)
144//    {
145//        String code = content.getValue(CODE_PEGASE_ATTRIBUTE_NAME);
146//        if (StringUtils.isEmpty(code))
147//        {
148//            code = content.getValue(OdfReferenceTableEntry.CODE);
149//        }
150//        return code;
151//    }
152//
153//    private String _getPegaseCodeOrCodeOfAttribute(Content content, String attributeName)
154//    {
155//        return _getContentValue(content, attributeName)
156//            .map(this::_getPegaseCodeOrCode)
157//            .orElse(null);
158//    }
159//
160//    private void _addMandatoryDataPathAndReport(Content content, String dataPath, ExportReport report)
161//    {
162//        I18nizableText invalidMessage = new I18nizableText(
163//            "plugin.odf-sync",
164//            "PLUGINS_ODF_SYNC_EXPORT_PEGASE_MANDATORY_FIELD",
165//            Map.of("fieldName", content.getDefinition(dataPath).getLabel())
166//        );
167//        report.addInvalidDataPath(content, invalidMessage);
168//    }
169//    
170//    private Optional<Content> _getContentValue(Content content, String attributeName)
171//    {
172//        return Optional.of(attributeName)
173//            .map(content::<ContentValue>getValue)
174//            .flatMap(ContentValue::getContentIfExists);
175//    }
176//    
177//    private Stream<Content> _getContentValues(Content content, String attributeName)
178//    {
179//        return Optional.of(attributeName)
180//            .map(content::<ContentValue[]>getValue)
181//            .map(Stream::of)
182//            .orElseGet(Stream::of)
183//            .map(ContentValue::getContentIfExists)
184//            .flatMap(Optional::stream);
185//    }
186//    
187    /**
188     * Checks if the program has all the required fields, their Pegase correspondence and that the program has a valid structure
189     * @param program the program
190     * @param report the Pegase export report
191     */
192    @Override
193    public void checkProgram(Program program, ExportReport report)
194    {
195//        if (!_isActive)
196//        {
197//            throw new UnsupportedOperationException("Pégase is not active in the configuration, you cannot check the program for the export.");
198//        }
199//        
200//        try
201//        {
202//            _checkAttributes(program, report);
203//            
204//            if (program.hasValue(__PEGASE_SYNC_CODE))
205//            {
206//                String codeAndVersion = program.getValue(__PEGASE_SYNC_CODE);
207//                Map<String, Object> dataCodeAndVersion = _getCodeAndVersion(codeAndVersion);
208//                String code = (String) dataCodeAndVersion.get("code");
209//                String versionString = (String) dataCodeAndVersion.get("version");
210//                
211//                // If the code is not missing, check if it is valid
212//                if (StringUtils.isNotBlank(versionString))
213//                {
214//                    BigDecimal version = new BigDecimal(versionString);
215//                    _checkProgramVersionCoherence(report, code, version);
216//                }
217//            }
218//            
219//            // If the education kind has a Pegase correspondence and is of code "0" (diplomante)
220//            if (__CODE_FORMATION_DIPLOMANTE.equals(_getPegaseCodeOrCodeOfAttribute(program, AbstractProgram.EDUCATION_KIND)))
221//            {
222//                _checkProgramDiplomanteField(program, report);
223//            }
224//            
225//            _checkChildren(program, report);
226//            
227//        }
228//        catch (IOException e)
229//        {
230//            report.updateStatus(ExportStatus.ERROR);
231//            getLogger().error("Le jeton d'authentification à Pégase n'a pas pu être récupéré", e);
232//        }
233    }
234//    
235//    private void _checkAttributes(Content content, ExportReport report)
236//    {
237//        if (content instanceof ProgramItem)
238//        {
239//            if (!content.hasValue(__PEGASE_SYNC_CODE))
240//            {
241//                _addMandatoryDataPathAndReport(content, __PEGASE_SYNC_CODE, report);
242//            }
243//            else if (content instanceof Program)
244//            {
245//                if (!_matches(__PROGRAM_CODE_PATTERN, content, __PEGASE_SYNC_CODE))
246//                {
247//                    report.addInvalidDataPath(content, new I18nizableText("plugin.odf-sync", "PLUGINS_ODF_SYNC_EXPORT_PEGASE_INVALID_CODE_PROGRAM"));
248//                }
249//            }
250//            else if (!_matches(__DEFAULT_CODE_PATTERN, content, __PEGASE_SYNC_CODE))
251//            {
252//                report.addInvalidDataPath(content, new I18nizableText("plugin.odf-sync", "PLUGINS_ODF_SYNC_EXPORT_PEGASE_INVALID_CODE_DEFAULT"));
253//            }
254//        }
255//        
256//        String contentType = content.getTypes()[0];
257//        Set<String> mandatoryAttributes = __MANDATORY_ATTRIBUTES_BY_CONTENT_TYPE.getOrDefault(contentType, Set.of());
258//        for (String attribute : mandatoryAttributes)
259//        {
260//            if (!content.hasValue(attribute))
261//            {
262//                _addMandatoryDataPathAndReport(content, attribute, report);
263//            }
264//        }
265//    }
266//    
267//    private boolean _matches(Pattern regex, Content content, String attributeName)
268//    {
269//        return regex.matcher(content.getValue(attributeName)).matches();
270//    }
271//    
272//    private void _checkProgramVersionCoherence(ExportReport report, String code, BigDecimal version) throws IOException
273//    {
274//        // If the Program already exist in this version
275//        ObjetMaquette objetMaquette = _getObjetMaquetteIfAlreadyExists(code, version);
276//        
277//        Long versionLong = version.longValue();
278//        if (objetMaquette != null)
279//        {
280//            // If it is not of type "FORMATION" or if it is not editable
281//            if (!objetMaquette.getType().getCode().equals("FORMATION") || !objetMaquette.getModifiable())
282//            {
283//                report.setStatus(ExportStatus.NON_EDITABLE_PROGRAM_ALREADY_EXISTS);
284//            }
285//        }
286//        
287//        // If nothing was found for this code and version, and the version is not null
288//        else
289//        {
290//            // Get the element for this code without requesting a specific version
291//            objetMaquette = _getObjetMaquetteIfAlreadyExists(code);
292//            
293//            // If something was found and it's a Program
294//            if (objetMaquette != null && objetMaquette.getType().getCode().equals("FORMATION"))
295//            {
296//                // Check if the version is compatible (versionFound == versionRequested or versionFound == versionRequested - 1)
297//                Long versionFound = Long.valueOf(objetMaquette.getDetail().getFormation().getVersion());
298//                if (versionLong != versionFound && versionLong != (versionFound + 1))
299//                {
300//                    report.setStatus(ExportStatus.PROGRAM_IMPOSSIBLE_VERSION);
301//                }
302//            }
303//            
304//            // If something was found but it is not a Program
305//            else if (objetMaquette != null && !objetMaquette.getType().getCode().equals("FORMATION"))
306//            {
307//                report.setStatus(ExportStatus.NON_EDITABLE_PROGRAM_ALREADY_EXISTS);
308//            }
309//            
310//            // If nothing was found, check if the version requested is one
311//            else if (versionLong != 1)
312//            {
313//                report.setStatus(ExportStatus.PROGRAM_IMPOSSIBLE_VERSION);
314//            }
315//        }
316//    }
317//    
318//    private void _checkProgramDiplomanteField(Program program, ExportReport report)
319//    {
320//        // dataDegree which contains degree, cursus and degreeNature
321//        _getContentValue(program, AbstractProgram.DEGREE)
322//                .ifPresent(degree -> _checkAttributes(degree, report));
323//    }
324//    
325//    private void _checkChildren(ProgramItem programItem, ExportReport report)
326//    {
327//        for (ProgramItem child : _odfHelper.getChildProgramItems(programItem))
328//        {
329//            _checkProgramItem(child, report);
330//        }
331//    }
332//    
333//    private void _checkChildrenOfYear(Container container, ExportReport report)
334//    {
335//        container.getProgramPartChildren()
336//            .stream()
337//            .filter(Container.class::isInstance)
338//            .map(Container.class::cast)
339//            .filter(c -> "annee".equals(getContainerNatureCode(c)))
340//            .forEach(
341//                child ->
342//                {
343//                    report.setStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
344//                    getLogger().error("L'élément {} (Année) ne peut avoir comme enfant une année : {}", container.getTitle(), child.getTitle());
345//                }
346//            );
347//    }
348//    
349//    private void _checkChildrenOfSemester(Container container, ExportReport report)
350//    {
351//        container.getProgramPartChildren()
352//            .stream()
353//            .filter(Container.class::isInstance)
354//            .map(Container.class::cast)
355//            .filter(c ->
356//            {
357//                String nature = getContainerNatureCode(c);
358//                return "annee".equals(nature) || "semestre".equals(nature);
359//            })
360//            .forEach(
361//                child ->
362//                {
363//                    report.setStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
364//                    getLogger().error("L'élément {} (Semestre) ne peut avoir comme enfant une année ou un semestre : {}", container.getTitle(), child.getTitle());
365//                }
366//            );
367//    }
368//    
369//    private void _checkChildrenOfSubProgram(SubProgram subProgram, ExportReport report)
370//    {
371//        for (ProgramItem child : _odfHelper.getChildProgramItems(subProgram))
372//        {
373//            // If the child is a SubProgram, then it is not compatible with the parent : SubProgram
374//            if (child instanceof SubProgram childSubProgram)
375//            {
376//                report.setStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
377//                getLogger().error("L'élément {} (Parcours) ne peut avoir comme enfant un parcours : {}", subProgram.getTitle(), childSubProgram.getTitle());
378//            }
379//            
380//            _checkProgramItem(child, report);
381//        }
382//    }
383//    
384//    private void _checkProgramItem(ProgramItem programItem, ExportReport report)
385//    {
386//        _checkAttributes((Content) programItem, report);
387//        
388//        if (programItem instanceof CourseList couresList)
389//        {
390//            // Check if the courseList has children, because a Pegase group has to have at least one child
391//            if (!couresList.hasCourses())
392//            {
393//                getLogger().error("L'élément {} n'a pas d'enfant alors qu'il aurait dû être exporté en tant que groupement", couresList.getTitle());
394//                report.setStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
395//            }
396//        }
397//        else if (programItem instanceof Container container)
398//        {
399//            String childNatureCode = getContainerNatureCode(container);
400//            
401//            if ("annee".equals(childNatureCode))
402//            {
403//                _checkChildrenOfYear(container, report);
404//            }
405//            else if ("semestre".equals(childNatureCode))
406//            {
407//                _checkChildrenOfSemester(container, report);
408//            }
409//            else
410//            {
411//                // Check if the container (without a nature) has children, because a Pegase group has to have at least one child
412//                if (!container.hasProgramPartChildren())
413//                {
414//                    getLogger().error("L'élément {} n'a pas d'enfant alors qu'il aurait dû être exporté en tant que groupement", container.getTitle());
415//                    report.setStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
416//                }
417//            }
418//        }
419//        
420//        else if (programItem instanceof SubProgram subProgram)
421//        {
422//            _checkChildrenOfSubProgram(subProgram, report);
423//        }
424//        
425//        for (ProgramItem child : _odfHelper.getChildProgramItems(programItem))
426//        {
427//            _checkProgramItem(child, report);
428//        }
429//    }
430//    
431//    private ObjetMaquette _getObjetMaquetteIfAlreadyExists(String code) throws IOException
432//    {
433//        return _getObjetMaquetteIfAlreadyExists(code, null);
434//    }
435//    
436//    /**
437//     * Get the latest version of an objetMaquette if it exists
438//     * @param code The code wanted
439//     * @param version The version wanted
440//     * @return The ObjetMaquette wanted or null if it was not found
441//     * @throws IOException If an error occurs while retrieving the token
442//     */
443//    private ObjetMaquette _getObjetMaquetteIfAlreadyExists(String code, BigDecimal version) throws IOException
444//    {
445//        Pageable pageable = new Pageable();
446//        pageable.setPage(0);
447//        pageable.setTaille(10);
448//        pageable.setTri(List.of("version,desc"));
449//        
450//        PagedObjetMaquette pagedObjetMaquette;
451//        try
452//        {
453//            // Get the objetMaquette for the code and the version
454//            pagedObjetMaquette = _pegaseApiManager.getObjetsMaquetteApi().lireListeObjetsMaquette(_structureCode, null, null, null, code, null, null, null, null, null, null, version, null, null, null, null, null, null, pageable);
455//            List<ObjetMaquette> objetsMaquette = pagedObjetMaquette.getItems();
456//            
457//            // If it was found, return it
458//            if (objetsMaquette.size() >= 1)
459//            {
460//                return objetsMaquette.get(0);
461//            }
462//        }
463//        catch (ApiException e)
464//        {
465//            getLogger().warn("Une erreur est survenue lors la recherche de l'élément de code de synchronization Pégase {} pour vérifier son existance préalable dans Pégase", code, e);
466//        }
467//        
468//        return null;
469//    }
470//    
471//    private Map<String, Object> _getCodeAndVersion(String codeAndVersion)
472//    {
473//        Map<String, Object> result = new HashMap<>();
474//        
475//        String code = codeAndVersion;
476//        String version = null;
477//        
478//        if (codeAndVersion.contains("/"))
479//        {
480//            String[] codeAndVersionTab = codeAndVersion.split("/");
481//            if (codeAndVersionTab.length == 2)
482//            {
483//                code = codeAndVersionTab[0];
484//                version = codeAndVersionTab[1];
485//            }
486//        }
487//        
488//        result.put("code", code);
489//        result.put("version", version);
490//        
491//        return result;
492//    }
493//    
494//    private boolean _isModifiable(ObjetMaquette objetMaquette, String code, ExportReport report) throws IOException
495//    {
496//        // If the object is not editable, return false
497//        if (!objetMaquette.getModifiable())
498//        {
499//            return false;
500//        }
501//        
502//        // The object is editable, now we check if it is linked to this Program
503//        List<FormationRef> parentPrograms = objetMaquette.getFormationsParentes();
504//        if (parentPrograms != null && parentPrograms.size() >= 1)
505//        {
506//            FormationRef parentProgram = parentPrograms.get(0);
507//            
508//            // If it is already linked to the Program, return true
509//            if (report.getCodeParentProgram().equals(parentProgram.getCode()) && report.getVersionParentProgram() == parentProgram.getVersion())
510//            {
511//                return true;
512//            }
513//        }
514//        
515//        // If the object is "mutualise" or orphan in Pégase then it can be linked to the Program
516//        if (objetMaquette.getMutualise() || _isOrphan(code))
517//        {
518//            return true;
519//        }
520//        
521//        return false;
522//    }
523//    
524//    private boolean _isOrphan(String code) throws IOException
525//    {
526//        PagedObjetMaquette pagedObjetMaquette;
527//        try
528//        {
529//            // Try to get the objetMaquette for the code wanted and that are isolated
530//            pagedObjetMaquette = _pegaseApiManager.getObjetsMaquetteApi().lireListeObjetsMaquette(_structureCode, null, null, null, code, null, null, null, true, null, null, null, null, null, null, null, null, null, null);
531//            
532//            List<ObjetMaquette> objetsMaquette = pagedObjetMaquette.getItems();
533//
534//            return objetsMaquette.size() >= 1;
535//        }
536//        catch (ApiException e)
537//        {
538//            getLogger().info("L'élément de code de synchronisation Pégase {} n'a pas pu être trouvé dans Pégase, nous ne pouvons donc pas vérifier si l'élément est isolé.", e);
539//        }
540//        
541//        return false;
542//    }
543//    
544//    private Enfant _createPegaseChild(Content child, String pegaseId)
545//    {
546//        Enfant pegaseChild = new Enfant();
547//        
548//        pegaseChild.setDetails(
549//            new EnfantDetails()
550//                .libelle(child.getTitle())
551//        );
552//        
553//        pegaseChild.setRef(
554//            new Ref()
555//                .id(pegaseId)
556//                .code(child.getValue(__PEGASE_SYNC_CODE))
557//        );
558//        
559//        return pegaseChild;
560//    }
561//    
562//    private Enfant _createChild(Content content, ExportReport report)
563//    {
564//        boolean success = true;
565//        try
566//        {
567//            String childPegaseId = _createPegaseInstance(content, report);
568//            return _createPegaseChild(content, childPegaseId);
569//        }
570//        catch (Exception ex)
571//        {
572//            success = false;
573//            getLogger().error("Erreur lors de l'export de l'élément {}", content.getTitle(), ex);
574//            return null;
575//        }
576//        finally
577//        {
578//            if (success)
579//            {
580//                report.addElementExported(content);
581//            }
582//        }
583//    }
584//    
585//    private String _createPegaseInstance(Content content, ExportReport report) throws PegaseExportException, IOException
586//    {
587//        // Conteneur : semestre, année -> OTT ou Groupement
588//        if (content instanceof Container)
589//        {
590//            return _createOTTOrGroupFromContainer((Container) content, report);
591//        }
592//        
593//        // Parcours -> OO
594//        if (content instanceof SubProgram)
595//        {
596//            return _createOOFromSubProgram((SubProgram) content, report);
597//        }
598//        
599//        // ELP -> OP
600//        if (content instanceof Course)
601//        {
602//            return _createOPFromCourse((Course) content, report);
603//        }
604//        
605//        // liste d'ELP -> Groupement
606//        if (content instanceof CourseList)
607//        {
608//            return _createGroupFromCourseList((CourseList) content, report);
609//        }
610//        
611//        return null;
612//    }
613//    
614//    private Map<String, Enfant> _createAllChildren(Map<String, Enfant> children, List<ProgramItem> programItem, ExportReport report)
615//    {
616//        for (ProgramItem childContent : programItem)
617//        {
618//            Enfant containerChild = _createChild((Content) childContent, report);
619//            
620//            // If the child was created, add it to the list of children to attach
621//            if (containerChild != null)
622//            {
623//                children.put(containerChild.getRef().getId(), containerChild);
624//            }
625//        }
626//        
627//        return children;
628//    }
629//
630//    private void _attachAllChildren(Content content, String pegaseId, Map<String, Enfant> children, ExportReport report) throws IOException
631//    {
632//        List<Enfant> childrenAlreadyAttached;
633//        try
634//        {
635//            // Get the children already attached to the programItem
636//            childrenAlreadyAttached = _pegaseApiManager.getObjetsMaquetteApi().lireEnfants(_structureCode, pegaseId);
637//            
638//            // If there are children already attached and the option trustAmetys is checked
639//            if (childrenAlreadyAttached != null && _trustAmetys)
640//            {
641//                // For every child already attached
642//                for (Enfant child : childrenAlreadyAttached)
643//                {
644//                    // Try to detach it
645//                    try
646//                    {
647//                        _pegaseApiManager.getObjetsMaquetteApi().detacherEnfant(_structureCode, pegaseId, child.getRef().getId());
648//                    }
649//                    catch (ApiException e)
650//                    {
651//                        report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR, content);
652//                        getLogger().warn("L'enfant de code Pégase {} de l'élément {} n'a pas pu être détaché dans Pégase", child.getRef().getCode(), content.getTitle(), e);
653//                    }
654//                }
655//            }
656//            
657//            // If the option trustAmetys is not checked
658//            else if (childrenAlreadyAttached != null)
659//            {
660//                // For every child already attached
661//                for (Enfant childAlreadyAttached : childrenAlreadyAttached)
662//                {
663//                    // Remove it from the list of children to attach
664//                    children.remove(childAlreadyAttached.getRef().getId());
665//                }
666//            }
667//            
668//            List<Enfant> childrenToAttach = List.copyOf(children.values());
669//            
670//            // If there are children that need to be attached
671//            if (!childrenToAttach.isEmpty())
672//            {
673//                // Try to attach them
674//                try
675//                {
676//                    _pegaseApiManager.getObjetsMaquetteApi().attacherEnfant(_structureCode, pegaseId, childrenToAttach);
677//                }
678//                catch (ApiException ex)
679//                {
680//                    report.updateExportReport(ExportStatus.WARN, ProblemTypes.LINKS_MISSING, content);
681//                    
682//                    String childrenFailedToAttach = "";
683//                    
684//                    for (Enfant child : childrenToAttach)
685//                    {
686//                        childrenFailedToAttach += child.getRef().getCode() + ",";
687//                    }
688//                    
689//                    getLogger().warn("Une erreur est survenue lors de l'attachement des enfants ({}) à l'élément ({}) dans Pégase", childrenFailedToAttach, content.getTitle(), ex);
690//                }
691//            }
692//        }
693//        catch (ApiException e)
694//        {
695//            report.updateExportReport(ExportStatus.WARN, ProblemTypes.API_ERROR, content);
696//            
697//            getLogger().warn("Les liens avec les enfants de l'élément {} n'ont pas pu être traités car les enfants depuis Pégase n'ont pas pu être récupérés.", content.getTitle(), e);
698//        }
699//    }
700//    
701//    private void _attachAllChildrenGroupementCase(Content content, String pegaseId, Map<String, Enfant> children, ExportReport report) throws IOException
702//    {
703//        // If the list of children that need to be attached is empty, throw an Exception
704//        if (children.isEmpty())
705//        {
706//            report.updateExportReport(ExportStatus.ERROR, ProblemTypes.GROUPEMENT_WITHOUT_CHILDREN, content);
707//            
708//            getLogger().warn("Aucuns des enfants de la liste d'elp ou le conteneur {}, devant être exporté en groupement, n'ont pu être exportés, les enfants de ce groupement resterons donc inchangés ", content.getTitle());
709//        }
710//        else
711//        {
712//            List<Enfant> childenAlreadyAttached;
713//            try
714//            {
715//                // Get the children already attached
716//                childenAlreadyAttached = _pegaseApiManager.getObjetsMaquetteApi().lireEnfants(_structureCode, pegaseId);
717//                List<String> childrenAttachedInTheEnd = List.copyOf(children.keySet());
718//                
719//                // If there are children already attached
720//                if (childenAlreadyAttached != null)
721//                {
722//                    // For every child already attached
723//                    for (Enfant childAlreadyAttached : childenAlreadyAttached)
724//                    {
725//                        // Remove it from the list of children to attach
726//                        children.remove(childAlreadyAttached.getRef().getId());
727//                    }
728//                }
729//                
730//                List<Enfant> childrenToAttach = List.copyOf(children.values());
731//                
732//                // If there are children to attach, try to attach them
733//                if (!childrenToAttach.isEmpty())
734//                {
735//                    try
736//                    {
737//                        _pegaseApiManager.getObjetsMaquetteApi().attacherEnfant(_structureCode, pegaseId, childrenToAttach);
738//                    }
739//                    catch (ApiException ex)
740//                    {
741//                        report.updateExportReport(ExportStatus.WARN, ProblemTypes.LINKS_MISSING, content);
742//                        
743//                        if (getLogger().isWarnEnabled())
744//                        {
745//                            getLogger().warn("Une erreur est survenue lors de l'attachement des enfants ({}) à l'élément ({}) dans Pégase",
746//                                childrenToAttach.stream()
747//                                    .map(Enfant::getRef)
748//                                    .map(Ref::getCode)
749//                                    .distinct()
750//                                    .collect(Collectors.joining(", ")),
751//                                    content.getTitle(),
752//                                ex
753//                            );
754//                        }
755//                    }
756//                }
757//                
758//                // If the option trustAmetys is checked, try to detach the other children (the children that were already attached to the content
759//                if (_trustAmetys && childenAlreadyAttached != null)
760//                {
761//                    // For every child that was already there
762//                    for (Enfant child : childenAlreadyAttached)
763//                    {
764//                        String childId = child.getRef().getId();
765//                        
766//                        // If it was not part of the children that needed to be attached, try to detach it
767//                        if (!childrenAttachedInTheEnd.contains(childId))
768//                        {
769//                            try
770//                            {
771//                                _pegaseApiManager.getObjetsMaquetteApi().detacherEnfant(_structureCode, pegaseId, child.getRef().getId());
772//                            }
773//                            catch (ApiException e)
774//                            {
775//                                report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR, content);
776//
777//                                getLogger().warn("L'enfant de code Pégase {} de l'élément {} n'a pas pu être détaché dans Pégase", child.getRef().getCode(), content.getTitle(), e);
778//                            }
779//                        }
780//                    }
781//                }
782//            }
783//            catch (ApiException e)
784//            {
785//                report.updateExportReport(ExportStatus.WARN, ProblemTypes.LINKS_MISSING, content);
786//
787//                getLogger().warn("Les liens avec les enfants de l'élément ({}) n'ont pas pu être traités car les enfants depuis Pégase n'ont pas pu être récupérés.", content.getTitle(), e);
788//            }
789//        }
790//    }
791//    
792//    private ObjetFormation _createObjetFormation(Content content, String type, ExportReport report) throws PegaseExportException, IOException
793//    {
794//        // Create the ObjetFormation
795//        ObjetFormation objetFormation = new ObjetFormation();
796//        
797//        String code = content.getValue(__PEGASE_SYNC_CODE);
798//        String label = content.getTitle();
799//        
800//        objetFormation.setCode(code);
801//        
802//        objetFormation.setLibelle(StringUtils.truncate(label, 50)); // le libellé court doit faire moins de 50 caractères
803//        objetFormation.setLibelleLong(StringUtils.truncate(label, 150)); // le libellé long doit faire moins de 150 caractères
804//        
805//        ObjetFormationType ob = new ObjetFormationType();
806//        ob.setCode(type);
807//        objetFormation.setType(ob);
808//
809//        objetFormation.setMutualise(true);
810//        
811//        if (content.hasValue("ects"))
812//        {
813//            Double ects = null;
814//            if (content instanceof AbstractProgram)
815//            {
816//                ects = _getContentValue(content, AbstractProgram.ECTS)
817//                    .map(c -> c.<String>getValue(OdfReferenceTableEntry.CODE))
818//                    .map(Double::parseDouble)
819//                    .orElse(null);
820//            }
821//            else
822//            {
823//                ects = content.getValue("ects");
824//            }
825//            
826//            if (ects != null)
827//            {
828//                objetFormation.putChampsAdditionnelsItem("ECTS", new ValeurNum().valeur(ects));
829//            }
830//        }
831//        
832//        Object desc = null;
833//        if (content.hasValue("description"))
834//        {
835//            desc = content.getValue("description");
836//        }
837//        else if (content.hasValue("presentation"))
838//        {
839//            desc = content.getValue("presentation");
840//        }
841//
842//        if (desc != null)
843//        {
844//            RichText descRichText = (RichText) desc;
845//            String description = _richTextHelper.richTextToString(descRichText);
846//            objetFormation.setDescription(StringUtils.truncate(description, 2000)); // la description doit faire moins de 2000 caractères
847//        }
848//
849//        // Check if the object already exists
850//        ObjetMaquette objetMaquette = _getObjetMaquetteIfAlreadyExists(code);
851//        if (objetMaquette != null)
852//        {
853//            // If it already exist, check if it can be edited
854//            if (_isModifiable(objetMaquette, code, report))
855//            {
856//                String id = objetMaquette.getId();
857//                objetFormation.setId(id);
858//                
859//                // Edit the already existing object
860//                try
861//                {
862//                    objetFormation = _pegaseApiManager.getObjetsFormationApi().modifierObjetFormation(_structureCode, id, objetFormation);
863//                    return objetFormation;
864//                }
865//                catch (ApiException e)
866//                {
867//                    report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_NOT_EXPORTED);
868//
869//                    throw new PegaseExportException("L'élément " + content.getTitle() + " n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e);
870//                }
871//            }
872//            
873//            report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_ALREADY_EXIST);
874//
875//            throw new PegaseExportException("Erreur lors de l'export de " + label + "Un élément avec le code " + code + " existe déjà et n'est pas mutualisable ou modifiable");
876//        }
877//        
878//        // If it did not already exist, create the object
879//        try
880//        {
881//            objetFormation = _pegaseApiManager.getObjetsFormationApi().creerObjetFormation(_structureCode, objetFormation);
882//            
883//            return objetFormation;
884//        }
885//        catch (ApiException e)
886//        {
887//            report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_NOT_EXPORTED);
888//
889//            throw new PegaseExportException("L'élément " + content.getTitle() + " n'a pas pu être exporté dû à un problème rencontré avec Pégase", e);
890//        }
891//    }
892//    
893//    private Formation _createProgram(Program program, ExportReport report) throws PegaseExportException, IOException
894//    {
895//        Formation pegaseProgram = new Formation();
896//        
897//        String codeAndVersion = program.getValue(__PEGASE_SYNC_CODE);
898//        
899//        Map<String, Object> dataCodeAndVersion = _getCodeAndVersion(codeAndVersion);
900//        String code = (String) dataCodeAndVersion.get("code");
901//        BigDecimal version = new BigDecimal((String) dataCodeAndVersion.get("version"));
902//        
903//        pegaseProgram.setCode(code);
904//
905//        pegaseProgram.setLibelle(StringUtils.truncate(program.getTitle(), 50)); // le libellé court doit faire moins de 50 caractères
906//        pegaseProgram.setLibelleLong(StringUtils.truncate(program.getTitle(), 150)); // le libellé court doit faire moins de 150 caractères
907//
908//        _getContentValue(program, AbstractProgram.ECTS)
909//            .map(c -> c.<String>getValue(OdfReferenceTableEntry.CODE))
910//            .map(Double::parseDouble)
911//            .ifPresent(pegaseProgram::setEcts);
912//
913//        pegaseProgram.setTypeFormation(new FormationTypeFormation().code(_getPegaseCodeOrCodeOfAttribute(program, AbstractProgram.EDUCATION_KIND)));
914//        
915//        // If the Program is of education kind "diplomante", add the additional fields
916//        if (__CODE_FORMATION_DIPLOMANTE.equals(pegaseProgram.getTypeFormation().getCode()))
917//        {
918//            _fieldsIfDiplomante(program, pegaseProgram);
919//        }
920//        
921//        return _createOrEditProgram(code, version, pegaseProgram, report);
922//    }
923//    
924//    private void _fieldsIfDiplomante(Program program, Formation pegaseProgram)
925//    {
926//        Content degree = _getContentValue(program, AbstractProgram.DEGREE).orElse(null);
927//        
928//        // Degree -> typeDiplome
929//        pegaseProgram.setTypeDiplome(_getPegaseCodeOrCode(degree));
930//        
931//        // degreeNature -> natureDiplome
932//        Optional.ofNullable(degree)
933//            .map(d -> d.<String>getValue("degreeNature"))
934//            .ifPresent(pegaseProgram::setNatureDiplome);
935//        
936//        // Cursus
937//        Optional.ofNullable(degree)
938//            .map(d -> d.<String>getValue("cursus"))
939//            .ifPresent(pegaseProgram::setCursus);
940//        
941//        // educationLevel -> niveauFormation
942//        pegaseProgram.setNiveauFormation(_getPegaseCodeOrCodeOfAttribute(program, AbstractProgram.LEVEL));
943//        
944//        // RncpLevel -> niveauDiplome
945//        String rncpLevelValue = _getContentValues(program, AbstractProgram.RNCP_LEVEL)
946//            .map(this::_getPegaseCodeOrCode)
947//            .collect(Collectors.joining(","));
948//        pegaseProgram.setNiveauDiplome(rncpLevelValue);
949//        
950//        // Domain
951//        if (((ElementDefinition) program.getDefinition(AbstractProgram.DOMAIN)).isMultiple())
952//        {
953//            _getContentValues(program, AbstractProgram.DOMAIN)
954//                .findFirst()
955//                .map(this::_getPegaseCodeOrCode)
956//                .ifPresent(pegaseProgram::setDomaineFormation);
957//        }
958//        else
959//        {
960//            pegaseProgram.setDomaineFormation(_getPegaseCodeOrCodeOfAttribute(program, AbstractProgram.DOMAIN));
961//        }
962//        
963//        // ProgramFields -> champFormation
964//        String programFieldsValue = _getContentValues(program, AbstractProgram.PROGRAM_FIELD)
965//            .map(this::_getPegaseCodeOrCode)
966//            .collect(Collectors.joining(","));
967//        if (StringUtils.isNotBlank(programFieldsValue))
968//        {
969//            pegaseProgram.setChampFormation(programFieldsValue);
970//        }
971//
972//        pegaseProgram.setMention(_getPegaseCodeOrCodeOfAttribute(program, AbstractProgram.MENTION));
973//    }
974//    
975//    private Formation _createOrEditProgram(String code, BigDecimal version, Formation pegaseProgram, ExportReport report) throws PegaseExportException, IOException
976//    {
977//        // Check if the Program already exist in this version
978//        ObjetMaquette objetMaquette = _getObjetMaquetteIfAlreadyExists(code, version);
979//        
980//        // If no version is requested
981//        if (version == null)
982//        {
983//            // If no program with this code was found in Pegase, create a new Program
984//            if (objetMaquette == null)
985//            {
986//                try
987//                {
988//                    return _pegaseApiManager.getFormationsApi().creerFormation(_structureCode, pegaseProgram);
989//                }
990//                catch (ApiException e)
991//                {
992//                    report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR);
993//
994//                    throw new PegaseExportException("La formation n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e);
995//                }
996//            }
997//            
998//            // If a program was found, try to edit it
999//            String id = objetMaquette.getId();
1000//            pegaseProgram.setId(id);
1001//          
1002//            try
1003//            {
1004//                return _pegaseApiManager.getFormationsApi().modifierFormation(_structureCode, id, pegaseProgram);
1005//            }
1006//            catch (ApiException e)
1007//            {
1008//                report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR);
1009//                
1010//                throw new PegaseExportException("La formation n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e);
1011//            }
1012//        }
1013//        
1014//        // If a version was requested
1015//        
1016//        // If a program already exist in this version, try to edit it
1017//        if (objetMaquette != null)
1018//        {
1019//            try
1020//            {
1021//                String id = objetMaquette.getId();
1022//                
1023//                pegaseProgram.setId(id);
1024//                
1025//                return _pegaseApiManager.getFormationsApi().modifierFormation(_structureCode, id, pegaseProgram);
1026//            }
1027//            catch (ApiException e)
1028//            {
1029//                report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR);
1030//
1031//                throw new PegaseExportException("La formation n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e);
1032//            }
1033//        }
1034//        
1035//        // If no program was found in Pegase with this code and version
1036//        // Check if the program exist in another version
1037//        objetMaquette = _getObjetMaquetteIfAlreadyExists(code);
1038//      
1039//        // If the program exist in another version
1040//        if (objetMaquette != null)
1041//        {
1042//            try
1043//            {
1044//                // Generate a new version of the Pegase Program
1045//                Formation newVersionProgram = _pegaseApiManager.getFormationsApi().generer(_structureCode, objetMaquette.getId());
1046//              
1047//                String id = newVersionProgram.getId();
1048//                pegaseProgram.setId(id);
1049//                
1050//                // Edit the new Program created
1051//                return _pegaseApiManager.getFormationsApi().modifierFormation(_structureCode, id, pegaseProgram);
1052//            }
1053//            catch (ApiException e)
1054//            {
1055//                report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR);
1056//                
1057//                throw new PegaseExportException("La formation n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e);
1058//            }
1059//        }
1060//        
1061//        // If no program was found for this code at all
1062//        else
1063//        {
1064//            try
1065//            {
1066//                // Create the program in Pegase
1067//                return _pegaseApiManager.getFormationsApi().creerFormation(_structureCode, pegaseProgram);
1068//            }
1069//            catch (ApiException e)
1070//            {
1071//                report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR);
1072//
1073//                throw new PegaseExportException("La formation n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e);
1074//            }
1075//        }
1076//    }
1077//    
1078//    private String _createOTTOrGroupFromContainer(Container container, ExportReport report) throws PegaseExportException, IOException
1079//    {
1080//        String type = null;
1081//        
1082//        String childNatureCode = getContainerNatureCode(container);
1083//        boolean isYear = "annee".equals(childNatureCode);
1084//        boolean isSemester = "semestre".equals(childNatureCode);
1085//        
1086//        // If it is a container of nature : semester of year, export it as an OTT of type semester or year
1087//        if (isYear || isSemester)
1088//        {
1089//            type = isYear ? "ANNEE" : "SEMESTRE";
1090//            
1091//            ObjetFormation objetFormationCreated = _createObjetFormation(container, type, report);
1092//            String pegaseId = objetFormationCreated.getId();
1093//
1094//            Map<String, Enfant> containerChildren = new HashMap<>();
1095//
1096//            // Create the children
1097//            containerChildren = _createAllChildren(containerChildren, _odfHelper.getChildProgramItems(container), report);
1098//            
1099//            // Attach the children that were created
1100//            _attachAllChildren(container, pegaseId, containerChildren, report);
1101//            
1102//            return pegaseId;
1103//        }
1104//        
1105//        // If it is a container without a nature, export it as a group
1106//        return _createGroupFromContainer(container, report);
1107//    }
1108//
1109//    private String _createGroupFromContainer(Container container, ExportReport report) throws PegaseExportException, IOException
1110//    {
1111//        Map<String, Enfant> coursesChild = new HashMap<>();
1112//        Groupement pegaseGroup = _createGroupFromContent(container);
1113//
1114//        // Create the children
1115//        coursesChild = _createAllChildren(coursesChild, _odfHelper.getChildProgramItems(container), report);
1116//        
1117//        pegaseGroup.setEnfants(List.copyOf(coursesChild.keySet()));
1118//        
1119//        // Create the group
1120//        Groupement groupementCreated = _createGroup(pegaseGroup, report);
1121//        String pegaseId = groupementCreated.getId();
1122//        
1123//        // Attach the children to the group
1124//        _attachAllChildrenGroupementCase(container, pegaseId, coursesChild, report);
1125//        
1126//        return pegaseId;
1127//    }
1128//    
1129//    private Groupement _createGroup(Groupement pegaseGroup, ExportReport report) throws PegaseExportException, IOException
1130//    {
1131//        String code = pegaseGroup.getCode();
1132//        ObjetMaquette objetMaquette = _getObjetMaquetteIfAlreadyExists(code);
1133//        Groupement pegaseGroupCreated;
1134//        
1135//        // Check if the object already exists
1136//        if (objetMaquette != null)
1137//        {
1138//            // If it already exist, check if it can be edited
1139//            if (_isModifiable(objetMaquette, code, report))
1140//            {
1141//                String id = objetMaquette.getId();
1142//                pegaseGroup.setId(id);
1143//        
1144//                // Edit the already existing object
1145//                try
1146//                {
1147//                    return _pegaseApiManager.getGroupementsApi().modifierGroupement(_structureCode, id, pegaseGroup);
1148//                }
1149//                catch (ApiException e)
1150//                {
1151//                    report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_NOT_EXPORTED);
1152//                    
1153//                    throw new PegaseExportException("Le groupement " + pegaseGroup.getLibelle() + " n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e);
1154//                }
1155//            }
1156//            
1157//            report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_ALREADY_EXIST);
1158//
1159//            throw new PegaseExportException("Un élément avec ce code existe déjà et n'est pas mutualisable ou modifiable");
1160//        }
1161//        
1162//        // If it did not already exist, create the object
1163//        try
1164//        {
1165//            pegaseGroupCreated = _pegaseApiManager.getGroupementsApi().creerGroupement(_structureCode, pegaseGroup);
1166//            
1167//            if (pegaseGroupCreated != null)
1168//            {
1169//                return pegaseGroupCreated;
1170//            }
1171//        }
1172//        catch (ApiException e)
1173//        {
1174//            report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_NOT_EXPORTED);
1175//            
1176//            throw new PegaseExportException("Le groupement " + pegaseGroup.getLibelle() + " n'a pas pu être exporté dû à un problème rencontré avec Pégase", e);
1177//        }
1178//        
1179//        return null;
1180//    }
1181//
1182//    private String _createOOFromSubProgram(SubProgram subProgram, ExportReport report) throws PegaseExportException, IOException
1183//    {
1184//        ObjetFormation objetFormationCreated = _createObjetFormation(subProgram, "PARCOURS-TYPE", report);
1185//        String pegaseId = objetFormationCreated.getId();
1186//
1187//        Map<String, Enfant> containerChildren = new HashMap<>();
1188//
1189//        // Create the children
1190//        containerChildren = _createAllChildren(containerChildren, _odfHelper.getChildProgramItems(subProgram), report);
1191//
1192//        // Attach the children
1193//        _attachAllChildren(subProgram, pegaseId, containerChildren, report);
1194//        
1195//        return pegaseId;
1196//    }
1197//    
1198//    private String _createOPFromCourse(Course course, ExportReport report) throws PegaseExportException, IOException
1199//    {
1200//        // Get the nature of the course
1201//        String type = _getPegaseCodeOrCodeOfAttribute(course, Course.COURSE_TYPE);
1202//        
1203//        // Create the course in Pegase
1204//        ObjetFormation objetFormationCreated = _createObjetFormation(course, type, report);
1205//        String pegaseId = objetFormationCreated.getId();
1206//        Map<String, Enfant> containerChildren = new HashMap<>();
1207//
1208//        // Create the children
1209//        containerChildren = _createAllChildren(containerChildren, _odfHelper.getChildProgramItems(course), report);
1210//
1211//        // Attach the children
1212//        _attachAllChildren(course, pegaseId, containerChildren, report);
1213//
1214//        return pegaseId;
1215//    }
1216//    
1217//    private Groupement _createGroupFromContent(Content content)
1218//    {
1219//        Groupement pegaseGroup = new Groupement();
1220//        String code = content.getValue(__PEGASE_SYNC_CODE);
1221//        
1222//        pegaseGroup.setStructure(_structureCode);
1223//        pegaseGroup.setCode(code);
1224//        pegaseGroup.setLibelle(StringUtils.truncate(content.getTitle(), 50)); // le libellé est limité à 50 caractères
1225//        pegaseGroup.setPlageDeChoix(false);
1226//        pegaseGroup.setMutualise(true);
1227//        pegaseGroup.setEnfants(List.of());
1228//        
1229//        return pegaseGroup;
1230//    }
1231//    
1232//    private String _createGroupFromCourseList(CourseList courseList, ExportReport report) throws PegaseExportException, IOException
1233//    {
1234//        Map<String, Enfant> coursesChild = new HashMap<>();
1235//        Groupement pegaseGroup = _createGroupFromContent(courseList);
1236//        
1237//        coursesChild = _createAllChildren(coursesChild, _odfHelper.getChildProgramItems(courseList), report);
1238//        
1239//        pegaseGroup.setEnfants(List.copyOf(coursesChild.keySet()));
1240//        
1241//        Groupement pegaseGroupCreated = _createGroup(pegaseGroup, report);
1242//        
1243//        String pegaseId = pegaseGroupCreated.getId();
1244//
1245//        _attachAllChildrenGroupementCase(courseList, pegaseId, coursesChild, report);
1246//        
1247//        return pegaseId;
1248//    }
1249
1250    /**
1251     * Create a program in Pegase
1252     * @param program the program to export
1253     * @param report the Pegase export report
1254     */
1255    @Override
1256    public void createProgram(Program program, ExportReport report)
1257    {
1258//        if (!_isActive)
1259//        {
1260//            throw new UnsupportedOperationException("Pégase is not active in the configuration, you cannot import or synchronize a program in Pégase.");
1261//        }
1262//        
1263//        int nbTotal = _getEveryElements(program).size();
1264//        
1265//        report.setNbTotal(nbTotal);
1266//        
1267//        Formation pegaseProgramCreated;
1268//        try
1269//        {
1270//            // Create the Program in Pegase
1271//            pegaseProgramCreated = _createProgram(program, report);
1272//            report.addElementExported(program);
1273//            
1274//            // Get the Id of the created formation from Pegase that is going to be used to attach the children to the program
1275//            String pegaseProgramId = pegaseProgramCreated.getId();
1276//            
1277//            String codeParentProgram = pegaseProgramCreated.getCode();
1278//            int versionParentProgram = 1;
1279//            
1280//            if (codeParentProgram.contains("/"))
1281//            {
1282//                String[] codeAndVersionTab = codeParentProgram.split("/");
1283//                if (codeAndVersionTab.length == 2)
1284//                {
1285//                    codeParentProgram = codeAndVersionTab[0];
1286//                    versionParentProgram = Integer.parseInt(codeAndVersionTab[1]);
1287//                }
1288//            }
1289//            
1290//            report.setCodeAndVersion(codeParentProgram, versionParentProgram);
1291//            
1292//            // Get the children of the Ametys program
1293//            List<ProgramPart> children = program.getProgramPartChildren();
1294//            Map<String, Enfant> childrenToLink = new HashMap<>();
1295//            
1296//            for (ProgramPart child : children)
1297//            {
1298//                // Create the pegase instance of the child
1299//                Enfant enfant = _createChild((Content) child, report);
1300//                
1301//                // Add the Enfant (created from the Pegase Id of the child) to the list of "Enfant" to link, if it is not already attached
1302//                if (enfant != null)
1303//                {
1304//                    childrenToLink.put(enfant.getRef().getId(), enfant);
1305//                }
1306//            }
1307//            
1308//            _attachAllChildren(program, pegaseProgramId, childrenToLink, report);
1309//            
1310//        }
1311//        catch (IOException e)
1312//        {
1313//            report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR);
1314//            getLogger().error("Le jeton d'authentification à Pégase n'a pas pu être récupéré", e);
1315//        }
1316//        catch (PegaseExportException e)
1317//        {
1318//            report.updateStatus(ExportStatus.ERROR);
1319//            getLogger().error("Une erreur est survenue lors de l'export de la formation '{}' ({}) dans Pégase", program.getTitle(), program.getId(), e);
1320//        }
1321    }
1322//    
1323//    private Set<ProgramItem> _getEveryElements(ProgramItem program)
1324//    {
1325//        Set<ProgramItem> elementNotExported = new HashSet<>();
1326//        elementNotExported.add(program);
1327//        
1328//        for (ProgramItem child : _odfHelper.getChildProgramItems(program))
1329//        {
1330//            elementNotExported.addAll(_getEveryElements(child));
1331//        }
1332//        
1333//        return elementNotExported;
1334//    }
1335}