001/*
002 *  Copyright 2019 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 */
016package org.ametys.plugins.odfsync.apogee.ws;
017
018import java.math.BigDecimal;
019import java.rmi.RemoteException;
020import java.time.LocalDate;
021import java.util.List;
022import java.util.stream.Stream;
023
024import org.apache.avalon.framework.component.Component;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.avalon.framework.service.Serviceable;
028import org.apache.commons.lang3.StringUtils;
029
030import org.ametys.cms.data.ContentDataHelper;
031import org.ametys.cms.data.ContentValue;
032import org.ametys.cms.repository.Content;
033import org.ametys.odf.ProgramItem;
034import org.ametys.odf.course.Course;
035import org.ametys.odf.courselist.CourseList;
036import org.ametys.odf.orgunit.OrgUnit;
037import org.ametys.odf.program.AbstractProgram;
038import org.ametys.odf.program.Container;
039import org.ametys.odf.program.SubProgram;
040import org.ametys.plugins.odfsync.apogee.ws.structure.AbstractApogeeStructure;
041import org.ametys.plugins.repository.AmetysObjectResolver;
042import org.ametys.runtime.config.Config;
043import org.ametys.runtime.plugin.component.AbstractLogEnabled;
044
045import gouv.education.apogee.commun.client.ws.creationse.CreationSEMetierServiceInterface;
046import gouv.education.apogee.commun.client.ws.creationse.CreationSEMetierServiceInterfaceServiceLocator;
047import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.CentreInsPedagogiDTO;
048import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.CentreInsPedagogiDTO2;
049import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.CmpHabiliteeVdiDTO;
050import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.ComposanteCGEDTO;
051import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.DiplomeDTO;
052import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.ElementPedagogiDTO4;
053import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.ElementPedagogiDTO6;
054import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.EtapeDTO;
055import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.LienVetElpLseDTO;
056import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.ListeElementPedagogiDTO3;
057import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.Nullable2Int;
058import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.Nullable3Int;
059import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.NullableDecimal;
060import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.NullableInt;
061import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.RegimeDTO;
062import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.VdiFractionnerVetDTO;
063import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.VersionDiplomeDTO;
064import gouv.education.apogee.commun.transverse.dto.offreformation.creerse.VersionEtapeDTO;
065
066
067/**
068 * The component to create ODF element in Apogee
069 * In most cases :
070 * DIP / VDI (diplome / version de diplome) : it is a program
071 * ETP / VET (etape / version d'etape) : it is a subprogram or a container of type year
072 * LSE (liste d'elements) : it is a course list 
073 * ELP (element pedagogique) : it is a course or a container of type semester
074 */
075public class ApogeeWS extends AbstractLogEnabled implements Serviceable, Component
076{
077    /** Avalon ROLE */
078    public static final String ROLE = ApogeeWS.class.getName();
079    
080    /** The ametys object resolver */
081    protected AmetysObjectResolver _resolver;
082    
083    public void service(ServiceManager manager) throws ServiceException
084    {
085        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
086    }
087    
088    /** 
089     * Get the service to create element in Apogee
090     * @return the service
091     * @throws javax.xml.rpc.ServiceException if an error occurred getting the service
092     */
093    public CreationSEMetierServiceInterface getCreationService() throws javax.xml.rpc.ServiceException
094    {
095        String wsURL = Config.getInstance().getValue("apogee.ws.url");
096        CreationSEMetierServiceInterfaceServiceLocator locator = new CreationSEMetierServiceInterfaceServiceLocator();
097        locator.setCreationSEMetierEndpointAddress(wsURL); // TODO user and mdp ????
098        
099        return locator.getCreationSEMetier();
100    }
101    
102    /**
103     * Create a Apogee DIP from a content
104     * @param content the content
105     * @param title the DIP title. Can be null, in this case we take the content title
106     * @param codDip the code DIP
107     * @throws RemoteException if a web service error occurred
108     * @throws javax.xml.rpc.ServiceException if an error occurred getting the service
109     */
110    public void createDIP(Content content, String title, String codDip) throws RemoteException, javax.xml.rpc.ServiceException
111    {
112        createDIP(content, title, codDip, getCreationService());
113    }
114    
115    /**
116     * Create a Apogee DIP from a content
117     * @param content the content
118     * @param title the DIP title. Can be null, in this case we take the content title
119     * @param codDip the code DIP
120     * @param creationSEMetierServiceInterface the service to create element in Apogee
121     * @throws RemoteException if a web service error occurred
122     */
123    public void createDIP(Content content, String title, String codDip, CreationSEMetierServiceInterface creationSEMetierServiceInterface) throws RemoteException
124    {
125        // Code diplome
126        String computedTitle = StringUtils.isNotBlank(title) ? title : content.getTitle();
127        
128        // codDip='Code diplôme (obligatoire)' "
129        // libDip='Libellé long diplôme (non obligatoire)' "
130        // licDip='Libellé court diplôme (obligatoire)' "
131        // codNdi='Code nature diplôme (obligatoire)'" 
132        // codCycle='Code cycle SISE (obligatoire)'" 
133        // codTypDip='Code type diplôme (obligatoire)'"
134        DiplomeDTO dip = new DiplomeDTO();
135        dip.setCodDip(codDip);
136        dip.setLibDip(computedTitle);
137        dip.setLicDip(StringUtils.substring(computedTitle, 0, 24)); // need to cut to 25 max
138        
139        String educationKindId = ContentDataHelper.getContentIdFromContentData(content, AbstractProgram.EDUCATION_KIND);
140        Content educationKindContent = _resolver.resolveById(educationKindId);
141        dip.setCodNdi(educationKindContent.getValue(AbstractApogeeStructure.CODE_APOGEE_ATTRIBUTE_NAME));
142
143        dip.setCodCycle(content.getValue("cycleApogee/codeApogee"));
144
145        String degreeCodeId = ContentDataHelper.getContentIdFromContentData(content, AbstractProgram.DEGREE);
146        Content degreeContent = _resolver.resolveById(degreeCodeId);
147        dip.setCodTypDip(degreeContent.getValue(AbstractApogeeStructure.CODE_APOGEE_ATTRIBUTE_NAME));
148        
149        creationSEMetierServiceInterface.creerDIP(dip);
150    }
151    
152    /**
153     * Create a Apogee VDI from a content
154     * @param content the content
155     * @param title the VDI title. Can be null, in this case we take the content title
156     * @param codDip the code of the diplome in Apogee
157     * @param versionDIP the version of the diplome in Apogee
158     * @throws RemoteException if a web service error occurred
159     * @throws javax.xml.rpc.ServiceException if an error occurred getting the service
160     */
161    public void createVDI(Content content, String title, String codDip, Long versionDIP) throws RemoteException, javax.xml.rpc.ServiceException
162    {
163        createVDI(content, title, codDip, versionDIP, getCreationService());
164    }
165    
166    /**
167     * Create a Apogee VDI from a content
168     * @param content the content
169     * @param title the VDI title. Can be null, in this case we take the content title
170     * @param codDip the code of the diplome in Apogee
171     * @param versionDIP the version of the diplome in Apogee
172     * @param creationSEMetierServiceInterface the service to create element in Apogee
173     * @throws RemoteException if a web service error occurred
174     */
175    public void createVDI(Content content, String title, String codDip, Long versionDIP, CreationSEMetierServiceInterface creationSEMetierServiceInterface) throws RemoteException
176    {
177        String computedTitle = StringUtils.isNotBlank(title) ? title : content.getTitle();
178        
179        // codDip='Code diplôme (obligatoire)' "
180        // codVersionDip='Code version diplôme (obligatoire)' "
181        // licVersionDip='Libellé court version diplôme (non obligatoire)' " 
182        // debutRecrutement='Année universitaire début recrutement (obligatoire)' "
183        // finRecrutement='Année universitaire fin recrutement (obligatoire)' "
184        // debutValidation='Année universitaire début validation (obligatoire)' "
185        // finValidation='Année universitaire fin validation (obligatoire)' "
186        // listComposantesHabilitees='Code composante 1,Code composante 2,... (obligatoire)' "
187        VersionDiplomeDTO vdi = new VersionDiplomeDTO();
188        vdi.setCodDip(codDip);
189        
190        vdi.setCodVersionDip(new NullableInt(versionDIP.intValue()));
191        vdi.setLicVersionDip(StringUtils.substring(computedTitle, 0, 24));
192        
193        LocalDate startRecruitmentDate = content.getValue("start-date-recruitment");
194        LocalDate endRecruitmentDate = content.getValue("end-date-recruitment");
195        vdi.setDebutRecrutement(String.valueOf(startRecruitmentDate.getYear()));
196        vdi.setFinRecrutement(String.valueOf(endRecruitmentDate.getYear()));
197        
198        LocalDate startValidationDate = content.getValue("start-date-validation");
199        LocalDate endValidationDate = content.getValue("end-date-validation");
200        vdi.setDebutValidation(String.valueOf(startValidationDate.getYear()));
201        vdi.setFinValidation(String.valueOf(endValidationDate.getYear()));
202        
203        // Create tab of orgUnits VDI
204        CmpHabiliteeVdiDTO[] tabCmpHabiliteeVDIs = ContentDataHelper.getContentIdsListFromMultipleContentData(content, ProgramItem.ORG_UNITS_REFERENCES)
205                    .stream()
206                    .map(id -> _getOrgUnitById(id))
207                    .filter(o -> o != null)
208                    .map(o -> _createCmpHabiliteeVdiDTO(o))
209                    .toArray(CmpHabiliteeVdiDTO[]::new);
210        vdi.setListComposantesHabilitees(tabCmpHabiliteeVDIs);
211        
212        creationSEMetierServiceInterface.creerVDI(vdi);
213    }
214    
215    /**
216     * Create a Apogee ETP from a content
217     * @param content the content
218     * @param title the ETP title. Can be null, in this case we take the content title
219     * @param codETP the code ETP
220     * @throws RemoteException if a web service error occurred
221     * @throws javax.xml.rpc.ServiceException if an error occurred getting the service
222     */
223    public void createETP(Content content, String title, String codETP) throws RemoteException, javax.xml.rpc.ServiceException
224    {
225        createETP(content, title, codETP, getCreationService());
226    }
227    
228    /**
229     * Create a Apogee ETP from a content
230     * @param content the content
231     * @param title the ETP title. Can be null, in this case we take the content title
232     * @param codETP the code ETP
233     * @param creationSEMetierServiceInterface the service to create element in Apogee
234     * @throws RemoteException if a web service error occurred
235     */
236    public void createETP(Content content, String title, String codETP, CreationSEMetierServiceInterface creationSEMetierServiceInterface) throws RemoteException
237    {
238        String computedTitle = StringUtils.isNotBlank(title) ? title : content.getTitle();
239        
240        // codEtp='Code étape (obligatoire)' "
241        // licEtp='Libellé court étape (obligatoire)' "
242        // libEtp='Libellé long étape (non obligatoire)' "
243        // codCycle='Code cycle SISE (obligatoire)' " 
244        // listComposantesCGE='[Code composante 1 (obligatoire),Code CGE 1 (obligatoire),capacité accueil 1 (non obligatoire)];[Code composante 2 (obligatoire),Code CGE 2 (obligatoire),capacité accueil 2 (non obligatoire)];... (obligatoire)' " 
245        EtapeDTO etp = new EtapeDTO();
246        etp.setCodEtp(codETP);
247        etp.setLicEtp(StringUtils.substring(computedTitle, 0, 24)); // need to cut to 25 max
248        etp.setLibEtp(computedTitle);
249        
250        etp.setCodCycle(content.getValue("cycleApogee/codeApogee"));
251        
252        if (content instanceof SubProgram subProgram) 
253        {
254            // Create tab of orgUnits CGE
255            ComposanteCGEDTO[] tabComp = subProgram.getOrgUnits()
256                        .stream()
257                        .map(id -> _getOrgUnitById(id))
258                        .filter(o -> o != null)
259                        .map(o -> _createComposanteCGEDTO(o))
260                        .toArray(ComposanteCGEDTO[]::new);
261            etp.setListComposantesCGE(tabComp);
262        }
263        else if (content instanceof Container)
264        {
265            ContentValue value = content.getValue("orgUnit");
266            ComposanteCGEDTO[] tabComp = new ComposanteCGEDTO[1];
267            tabComp[0] = _createComposanteCGEDTO((OrgUnit) value.getContent());
268            etp.setListComposantesCGE(tabComp);
269        }
270        
271        creationSEMetierServiceInterface.creerETP(etp);
272    }
273    
274    /**
275     * Create a Apogee VET from a content
276     * @param content the content
277     * @param title the VET title. Can be null, in this case we take the content title
278     * @param codETP the ETP code in Apogee
279     * @param versionETP the version ETP in Apogee
280     * @throws RemoteException if a web service error occurred
281     * @throws javax.xml.rpc.ServiceException if an error occurred getting the service
282     */
283    public void createVET(Content content, String title, String codETP, Long versionETP) throws RemoteException, javax.xml.rpc.ServiceException
284    {
285        createVET(content, title, codETP, versionETP, getCreationService());
286    }
287    
288    /**
289     * Create a Apogee VET from a content
290     * @param content the content
291     * @param title the VET title. Can be null, in this case we take the content title
292     * @param codETP the ETP code in Apogee
293     * @param versionETP the version ETP in Apogee
294     * @param creationSEMetierServiceInterface the service to create element in Apogee
295     * @throws RemoteException if a web service error occurred
296     */
297    public void createVET(Content content, String title, String codETP, Long versionETP, CreationSEMetierServiceInterface creationSEMetierServiceInterface) throws RemoteException
298    {
299        String computedTitle = StringUtils.isNotBlank(title) ? title : content.getTitle();
300        
301        // codEtp='Code étape (obligatoire)' "
302        // codVersionEtp='Code version étape (obligatoire)' "
303        // libWeb='Libellé web version étape (non obligatoire)' "
304        // codDureeEtp='Code durée étape' (obligatoire)' " 
305        // codComposante='Code composante organisatrice (obligatoire)' " 
306        // listRegimes='Code régime 1,Code régime 2,... (obligatoire)' "
307        // listCIP='[Code centre d'inscription pédagogique 1 (obligatoire),Témoin IA avant IP 1 (non obligatoire),Témoin inscription automatique aux éléments obligatoires 1 (non obligatoire)];[Code centre d'inscription pédagogique 2 (obligatoire),Témoin ...];... (obligatoire)' "
308        VersionEtapeDTO vet = new VersionEtapeDTO();
309        vet.setCodEtp(codETP);
310        vet.setCodVersionEtp(new NullableInt(versionETP.intValue()));
311        vet.setLibWeb(computedTitle);
312        
313        vet.setCodDureeEtp(content.getValue("duration-apogee/codeApogee"));
314
315        if (content instanceof SubProgram subProgram) // TODO prendre orgunit principale
316        {
317            String orgUnitId = subProgram.getOrgUnits().get(0);
318            OrgUnit orgUnit = _getOrgUnitById(orgUnitId);
319            vet.setCodComposante(orgUnit.getValue(AbstractApogeeStructure.CODE_APOGEE_ATTRIBUTE_NAME));
320        }
321        else if (content instanceof Container)
322        {
323            ContentValue value = content.getValue("orgUnit");
324            vet.setCodComposante(value.getContent().getValue(AbstractApogeeStructure.CODE_APOGEE_ATTRIBUTE_NAME));
325        }
326        
327        // Create tab of regime
328        String[] inscriptionTypes = content.getValue("inscription-types/codeApogee", true);
329        RegimeDTO[] tabRegimes = Stream.of(inscriptionTypes)
330                    .map(it -> _createRegime(it))
331                    .toArray(RegimeDTO[]::new);
332        vet.setListRegimes(tabRegimes);
333
334        // Create tab of CIP
335        String[] cips = content.getValue("cips/codeApogee", true);
336        CentreInsPedagogiDTO2[] tabCIP = Stream.of(cips)
337                    .map(cip -> _createCIPVET(cip))
338                    .toArray(CentreInsPedagogiDTO2[]::new);
339        vet.setListCIP(tabCIP);
340
341        creationSEMetierServiceInterface.creerVET(vet);
342    }
343    
344    /**
345     * Create in Apogee the link between a DIP and a ETP
346     * @param codDIP the DIP code in Apogee
347     * @param versionDIP the DIP version in Apogee
348     * @param codETP the ETP code in Apogee
349     * @param versionETP the ETP version in Apogee
350     * @throws RemoteException if a web service error occurred
351     * @throws javax.xml.rpc.ServiceException if an error occurred getting the service
352     */
353    public void createLinkDIPETP(String codDIP, Long versionDIP, String codETP, Long versionETP) throws RemoteException, javax.xml.rpc.ServiceException
354    {
355        createLinkDIPETP(codDIP, versionDIP, codETP, versionETP, getCreationService());
356    }
357    
358    /**
359     * Create in Apogee the link between a DIP and a ETP
360     * @param codDIP the DIP code in Apogee
361     * @param versionDIP the DIP version in Apogee
362     * @param codETP the ETP code in Apogee
363     * @param versionETP the ETP version in Apogee
364     * @param creationSEMetierServiceInterface the service to create element in Apogee
365     * @throws RemoteException if a web service error occurred
366     */
367    public void createLinkDIPETP(String codDIP, Long versionDIP, String codETP, Long versionETP, CreationSEMetierServiceInterface creationSEMetierServiceInterface) throws RemoteException
368    {
369        // codDip='Code diplôme (obligatoire)' "
370        // codVersionDip='Code version diplôme (obligatoire)' "
371        // codEtp='Code étape (obligatoire)' "
372        // codVersionEtp='Code version étape (obligatoire)'" 
373        // anMinEtpDip='Année minimale étape pour diplôme (obligatoire)' " 
374        // anMaxEtpDip='Année maximale étape pour diplôme (obligatoire)' "
375        VdiFractionnerVetDTO lien = new VdiFractionnerVetDTO();
376        lien.setCodDip(codDIP);     
377        lien.setCodVersionDip(new Nullable3Int(versionDIP.intValue()));
378        lien.setCodEtp(codETP);
379        lien.setCodVersionEtp(new Nullable3Int(versionETP.intValue()));
380        lien.setAnMinEtpDip(new NullableInt("1")); //TODO
381        lien.setAnMaxEtpDip(new NullableInt("2")); //TODO
382
383        creationSEMetierServiceInterface.creerLienVetVdi(lien);
384    }
385    
386    /**
387     * Create in Apogee the link between a ETP and a LSE or ELP
388     * @param codETP the ETP code in Apogee. Can be null if codELP is set.
389     * @param versionETP the ETP version in Apogee. Can be null if codELP is set.
390     * @param codLSE the LSE code in Apogee.
391     * @param codELP the ELP version in Apogee. Can be null if codETP and versionETP is set.
392     * @param nbELP the number of ELP. Can be null if the LSE is mandatory or optional.
393     * @param ectsMin the min number of ects. Can be null if the LSE is mandatory or optional.
394     * @param ectsMax the max number of ects. Can be null if the LSE is mandatory or optional.
395     * @throws RemoteException if a web service error occurred
396     * @throws javax.xml.rpc.ServiceException if an error occurred getting the service
397     */
398    public void createLinkETPELPLSE(String codETP, Long versionETP, String codLSE, String codELP, Long nbELP, Double ectsMin, Double ectsMax) throws RemoteException, javax.xml.rpc.ServiceException
399    {
400        createLinkETPELPLSE(codETP, versionETP, codLSE, codELP, nbELP, ectsMin, ectsMax, getCreationService());
401    }
402    
403    /**
404     * Create in Apogee the link between a ETP and a LSE or ELP
405     * @param codETP the ETP code in Apogee. Can be null if codELP is set.
406     * @param versionETP the ETP version in Apogee. Can be null if codELP is set.
407     * @param codLSE the LSE code in Apogee.
408     * @param codELP the ELP version in Apogee. Can be null if codETP and versionETP is set.
409     * @param nbELP the number of ELP. Can be null if the LSE is mandatory or optional.
410     * @param ectsMin the min number of ects. Can be null if the LSE is mandatory or optional.
411     * @param ectsMax the max number of ects. Can be null if the LSE is mandatory or optional.
412     * @param creationSEMetierServiceInterface the service to create element in Apogee
413     * @throws RemoteException if a web service error occurred
414     */
415    public void createLinkETPELPLSE(String codETP, Long versionETP, String codLSE, String codELP, Long nbELP, Double ectsMin, Double ectsMax, CreationSEMetierServiceInterface creationSEMetierServiceInterface) throws RemoteException
416    {
417        // codElp='Code élément pédagogique (obligatoire)' "
418        // codEtp='Code étape (obligatoire)'" 
419        // codVersionEtp='Code version étape (obligatoire)'"
420        // codListeElp='Code Liste d'éléments pédagogiques (obligatoire)'"
421        // nbrMinElp='Nombre minimum d'éléments à choisir dans la liste'" 
422        // nbrMaxElp='Nombre maximum d'éléments à choisir dans la liste'"
423        // nbrMinCredits='Nombre minimum de crédits ECTS à choisir dans la liste'"
424        // nbrMaxCredits='Nombre maximum de crédits ECTS à choisir dans la liste'" 
425        
426        LienVetElpLseDTO lien = new LienVetElpLseDTO();
427        if (StringUtils.isNotBlank(codETP))
428        {
429            lien.setCodEtp(codETP);
430        }
431        
432        if (versionETP != null)
433        {
434            lien.setCodVersionEtp(new Nullable3Int(versionETP.intValue()));
435        }
436        else
437        {
438            lien.setCodVersionEtp(new Nullable3Int());
439        }
440
441        lien.setCodListeElp(codLSE);
442        lien.setCodElp(codELP);
443        
444        if (nbELP != null)
445        {
446            lien.setNbrMinElp(new Nullable2Int(nbELP.intValue()));
447            lien.setNbrMaxElp(new Nullable2Int(nbELP.intValue()));
448            
449            lien.setNbrMinCredits(new NullableDecimal(new BigDecimal(ectsMin)));
450            lien.setNbrMaxCredits(new NullableDecimal(new BigDecimal(ectsMax)));
451        }
452        creationSEMetierServiceInterface.creerLienVetElpLse(lien);
453    }
454    
455    /**
456     * Create a Apogee LSE from a course list
457     * @param courseList the course list
458     * @param title the LSE title. Can be null, in this case we take the content title
459     * @param codLSE the code LSE
460     * @throws RemoteException if a web service error occurred
461     * @throws javax.xml.rpc.ServiceException if an error occurred getting the service
462     */
463    public void createLSE(CourseList courseList, String title, String codLSE) throws RemoteException, javax.xml.rpc.ServiceException
464    {
465        createLSE(courseList, title, codLSE, getCreationService());
466    }
467    
468    /**
469     * Create a Apogee LSE from a course list
470     * @param courseList the course list
471     * @param title the LSE title. Can be null, in this case we take the content title
472     * @param codLSE the code LSE
473     * @param creationSEMetierServiceInterface the service to create element in Apogee
474     * @throws RemoteException if a web service error occurred
475     */
476    public void createLSE(CourseList courseList, String title, String codLSE, CreationSEMetierServiceInterface creationSEMetierServiceInterface) throws RemoteException
477    {
478        String computedTitle = StringUtils.isNotBlank(title) ? title : courseList.getTitle();
479        
480        // Création du tableau d'ELP
481        int i = 0;
482        List<Course> courses = courseList.getCourses();
483        ElementPedagogiDTO4[] tabELP = new ElementPedagogiDTO4[courses.size()];
484        for (Course course : courses) 
485        {
486            tabELP[i] = new ElementPedagogiDTO4(course.getValue(AbstractApogeeStructure.CODE_APOGEE_ATTRIBUTE_NAME));
487            i++;
488        }
489
490        // codListeElp='Code Liste d'éléments pédagogiques (obligatoire)' "
491        // typListeElp='Code type de liste (obligatoire)' "
492        // libCourtListeElp='Libellé court liste d'éléments pédagogiques (obligatoire)'" 
493        // libListeElp='Libelle long liste d'éléments pédagogiques (obligatoire)'" 
494        // listElementPedagogi='Code élément pédagogique,Code élément pédagogique 2,Code élément pédagogique 3,... (au moins 1 codElp, obligatoire)'" 
495        ListeElementPedagogiDTO3 lse = new ListeElementPedagogiDTO3();
496        lse.setCodListeElp(codLSE);
497        
498        String choiceTypeAmetys = courseList.getValue("choiceType");
499        String typList = "O";
500        if (choiceTypeAmetys.equals("MANDATORY"))
501        {
502            typList = "F";
503        }
504        else if (choiceTypeAmetys.equals("CHOICE"))
505        {
506            typList = "X";
507        }
508        lse.setTypListeElp(typList);
509        lse.setLibCourtListeElp(StringUtils.substring(computedTitle, 0, 24));
510        lse.setLibListeElp(computedTitle);
511        lse.setListElementPedagogi(tabELP);
512        
513        creationSEMetierServiceInterface.creerLSE(lse);
514    }
515    
516    /**
517     * Create a Apogee mandatory LSE with his ELP 
518     * @param titleLSE the title of the LSE
519     * @param codLSE the code of the LSE
520     * @param codELP the code of the ELP
521     * @throws RemoteException if a web service error occurred
522     * @throws javax.xml.rpc.ServiceException if an error occurred getting the service
523     */
524    public void createMandatoryLSE(String titleLSE, String codLSE, String codELP) throws RemoteException, javax.xml.rpc.ServiceException
525    {
526        createMandatoryLSE(titleLSE, codLSE, codELP, getCreationService());
527    }
528    
529    /**
530     * Create a Apogee mandatory LSE with his ELP 
531     * @param titleLSE the title of the LSE
532     * @param codLSE the code of the LSE
533     * @param codELP the code of the ELP
534     * @param creationSEMetierServiceInterface the service to create element in Apogee
535     * @throws RemoteException if a web service error occurred
536     */
537    public void createMandatoryLSE(String titleLSE, String codLSE, String codELP, CreationSEMetierServiceInterface creationSEMetierServiceInterface) throws RemoteException
538    {
539        // Création du tableau d'ELP
540        ElementPedagogiDTO4[] tabELP = new ElementPedagogiDTO4[1];
541        tabELP[0] = new ElementPedagogiDTO4(codELP);
542
543        // codListeElp='Code Liste d'éléments pédagogiques (obligatoire)' "
544        // typListeElp='Code type de liste (obligatoire)' "
545        // libCourtListeElp='Libellé court liste d'éléments pédagogiques (obligatoire)'" 
546        // libListeElp='Libelle long liste d'éléments pédagogiques (obligatoire)'" 
547        // listElementPedagogi='Code élément pédagogique,Code élément pédagogique 2,Code élément pédagogique 3,... (au moins 1 codElp, obligatoire)'" 
548        ListeElementPedagogiDTO3 lse = new ListeElementPedagogiDTO3();
549        lse.setCodListeElp(codLSE);
550        
551        lse.setTypListeElp("F");
552        lse.setLibCourtListeElp(StringUtils.substring(titleLSE, 0, 24));
553        lse.setLibListeElp(titleLSE);
554        lse.setListElementPedagogi(tabELP);
555        
556        creationSEMetierServiceInterface.creerLSE(lse);
557    }
558    
559    /**
560     * Create a Apogee ELP from a content
561     * @param content the content
562     * @param title the ELP title. Can be null, in this case we take the content title
563     * @param codELP the code ELP
564     * @throws RemoteException if a web service error occurred
565     * @throws javax.xml.rpc.ServiceException if an error occurred getting the service
566     */
567    public void createELP(Content content, String title, String codELP) throws RemoteException, javax.xml.rpc.ServiceException
568    {
569        createELP(content, title, codELP, getCreationService());
570    }
571    
572    /**
573     * Create a Apogee ELP from a content
574     * @param content the content
575     * @param title the ELP title. Can be null, in this case we take the content title
576     * @param codELP the code ELP
577     * @param creationSEMetierServiceInterface the service to create element in Apogee
578     * @throws RemoteException if a web service error occurred
579     */
580    public void createELP(Content content, String title, String codELP, CreationSEMetierServiceInterface creationSEMetierServiceInterface) throws RemoteException
581    {
582        String computedTitle = StringUtils.isNotBlank(title) ? title : content.getTitle();
583        
584        // Create the ELP DTO
585        // codElp='Code élément pédagogique (obligatoire)' "
586        // libCourtElp='Libellé court élément pédagogique pédagogiques (obligatoire)'" 
587        // libElp='Libelle long élément pédagogique (obligatoire)'"
588        // codNatureElp='Code de la nature ELP' (obligatoire)"
589        // codComposante='Code composante' (obligatoire)" 
590        // listCentreInsPedagogi='Code CIP 1,Code CIP 2,Code CIP 3, ... (au moins 1 codCip, obligatoire)'" 
591        ElementPedagogiDTO6 elp = new ElementPedagogiDTO6();
592        elp.setCodElp(codELP);
593        elp.setLibElp(computedTitle);
594        elp.setLibCourtElp(StringUtils.substring(computedTitle, 0, 24));
595        
596        if (content instanceof Container)
597        {
598            ContentValue value = content.getValue("nature");
599            elp.setCodNatureElp(value.getContent().getValue(AbstractApogeeStructure.CODE_APOGEE_ATTRIBUTE_NAME));
600        }
601        else if (content instanceof Course)
602        {
603            ContentValue value = content.getValue("courseType");
604            elp.setCodNatureElp(value.getContent().getValue(AbstractApogeeStructure.CODE_APOGEE_ATTRIBUTE_NAME));
605        }
606        
607        if (content instanceof Course) // TODO prendre orgunit principale
608        {
609            String orgUnitId = ((Course) content).getOrgUnits().get(0);
610            OrgUnit orgUnit = _getOrgUnitById(orgUnitId);
611            elp.setCodComposante(orgUnit.getValue(AbstractApogeeStructure.CODE_APOGEE_ATTRIBUTE_NAME));
612        }
613        else if (content instanceof Container)
614        {
615            ContentValue value = content.getValue("orgUnit");
616            elp.setCodComposante(value.getContent().getValue(AbstractApogeeStructure.CODE_APOGEE_ATTRIBUTE_NAME));
617        }
618        
619        // Create tab of CIP
620        String[] cips = content.getValue("cips/codeApogee", true);
621        CentreInsPedagogiDTO[] tabCIP = Stream.of(cips)
622                    .map(cip -> _createCIPELP(cip))
623                    .toArray(CentreInsPedagogiDTO[]::new);
624        elp.setListCentreInsPedagogi(tabCIP);
625        
626        creationSEMetierServiceInterface.creerELP_v2(elp);
627    }
628    
629    /**
630     * Get orgUnit content from id
631     * @param orgUnitId the orgUnit id
632     * @return the orgUnit content
633     */
634    private OrgUnit _getOrgUnitById(String orgUnitId)
635    {
636        try
637        {
638            OrgUnit orgUnit = _resolver.resolveById(orgUnitId);
639            return orgUnit;
640        }
641        catch (Exception e) 
642        {
643            getLogger().warn("Can't get orgunit from id " + orgUnitId, e);
644            return null;
645        }
646    }
647    
648    /**
649     * Create CIP object for VET Apogee
650     * @param code the code of the CIP
651     * @return the CIP object
652     */
653    private CentreInsPedagogiDTO2 _createCIPVET(String code)
654    {
655        CentreInsPedagogiDTO2 cip = new CentreInsPedagogiDTO2();
656        cip.setCodCIP(code);
657        
658        return cip;
659    }
660    
661    /**
662     * Create CIP object for ELP Apogee
663     * @param code the code of the CIP
664     * @return the CIP object
665     */
666    private CentreInsPedagogiDTO _createCIPELP(String code)
667    {
668        return new CentreInsPedagogiDTO(code);
669    }
670    
671    /**
672     * Create Regime object for Apogee
673     * @param code the code of the regime
674     * @return the Regime object
675     */
676    private RegimeDTO _createRegime(String code)
677    {
678        RegimeDTO regime = new RegimeDTO();
679        regime.setCodRegime(code);
680        
681        return regime;
682    }
683    
684    /**
685     * Create the orgUnit CGE for Apogee
686     * @param orgUnit the Ametys orgUnit
687     * @return the orgUnit CGE
688     */
689    private ComposanteCGEDTO _createComposanteCGEDTO(OrgUnit orgUnit)
690    {
691        ComposanteCGEDTO comp = new ComposanteCGEDTO();
692        comp.setCodComposante(orgUnit.getValue(AbstractApogeeStructure.CODE_APOGEE_ATTRIBUTE_NAME));
693        comp.setCodCGE(orgUnit.getValue("codeCGE"));
694        
695        return comp;
696    }
697    
698    /**
699     * Create the orgUnit VDI for Apogee
700     * @param orgUnit the Ametys orgUnit
701     * @return the orgUnit VDI
702     */
703    private CmpHabiliteeVdiDTO _createCmpHabiliteeVdiDTO(OrgUnit orgUnit)
704    {
705        CmpHabiliteeVdiDTO comp = new CmpHabiliteeVdiDTO();
706        comp.setCodComposanteHabilitee(orgUnit.getValue(AbstractApogeeStructure.CODE_APOGEE_ATTRIBUTE_NAME));
707        
708        return comp;
709    }
710}