TicketCreationBrouillonDaemon.java
/*
* Copyright (c) 2002-2025, City of Paris
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright notice
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* License 1.0
*/
package fr.paris.lutece.plugins.workflow.modules.ticketing.service.daemon;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.text.MessageFormat;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import fr.paris.lutece.api.user.User;
import fr.paris.lutece.plugins.genericattributes.business.ResponseHome;
import fr.paris.lutece.plugins.ticketing.business.address.TicketAddress;
import fr.paris.lutece.plugins.ticketing.business.category.TicketCategory;
import fr.paris.lutece.plugins.ticketing.business.category.TicketCategoryHome;
import fr.paris.lutece.plugins.ticketing.business.channel.Channel;
import fr.paris.lutece.plugins.ticketing.business.channel.ChannelHome;
import fr.paris.lutece.plugins.ticketing.business.erreurscannerstrois.ErreurScannerStrois;
import fr.paris.lutece.plugins.ticketing.business.erreurscannerstrois.ErreurScannerStroisHome;
import fr.paris.lutece.plugins.ticketing.business.profilstrois.Profilstrois;
import fr.paris.lutece.plugins.ticketing.business.quartier.Quartier;
import fr.paris.lutece.plugins.ticketing.business.quartier.QuartierHome;
import fr.paris.lutece.plugins.ticketing.business.referentielscanner.ReferentielScanner;
import fr.paris.lutece.plugins.ticketing.business.referentielscanner.ReferentielScannerHome;
import fr.paris.lutece.plugins.ticketing.business.search.IndexerActionHome;
import fr.paris.lutece.plugins.ticketing.business.ticket.Ticket;
import fr.paris.lutece.plugins.ticketing.business.ticket.TicketHome;
import fr.paris.lutece.plugins.ticketing.business.ticketpj.TicketPj;
import fr.paris.lutece.plugins.ticketing.business.ticketpj.TicketPjHome;
import fr.paris.lutece.plugins.ticketing.service.TicketInitService;
import fr.paris.lutece.plugins.ticketing.service.TicketTransfertPjService;
import fr.paris.lutece.plugins.ticketing.service.strois.StockageService;
import fr.paris.lutece.plugins.ticketing.service.util.FileUtils;
import fr.paris.lutece.plugins.ticketing.service.util.PluginConfigurationService;
import fr.paris.lutece.plugins.ticketing.web.TicketingConstants;
import fr.paris.lutece.plugins.ticketing.web.workflow.WorkflowCapableJspBean;
import fr.paris.lutece.plugins.workflow.modules.ticketing.service.WorkflowTicketingPlugin;
import fr.paris.lutece.portal.business.file.File;
import fr.paris.lutece.portal.business.file.FileHome;
import fr.paris.lutece.portal.business.user.AdminUserHome;
import fr.paris.lutece.portal.service.daemon.Daemon;
import fr.paris.lutece.portal.service.i18n.I18nService;
import fr.paris.lutece.portal.service.mail.MailService;
import fr.paris.lutece.portal.service.plugin.Plugin;
import fr.paris.lutece.portal.service.spring.SpringContextService;
import fr.paris.lutece.portal.service.util.AppException;
import fr.paris.lutece.portal.service.util.AppLogService;
import fr.paris.lutece.portal.service.util.AppPropertiesService;
import fr.paris.lutece.portal.service.workflow.WorkflowService;
import fr.paris.lutece.util.sql.TransactionManager;
import io.minio.Result;
import io.minio.errors.MinioException;
import io.minio.messages.Item;
/**
* Daemon used to Pj Migration Tickets
*/
public class TicketCreationBrouillonDaemon extends Daemon
{
// Services
private static WorkflowService _workflowService = WorkflowService.getInstance( );
private static final String PROPERTY_CHANNEL_SCAN_NAME = "ticketing.channelScan.name";
private static final String PROPERTY_ID_ADMIN_USER_FOR_DRAFT_DAEMON = "ticketing.draft.daemon.admin.user.id";
private static final String PROPERTY_EMAIL_SENDER_FOR_DRAFT_DAEMON = "ticketing.draft.daemon.email.sender";
private static final String MENTION_A_PRECISER = "A préciser";
private static final String DAEMON_INSERTION_ERROR_MAIL_SUBJECT = "module.workflow.ticketing.daemon.creationBrouillonDaemon.error.mail.insertion.subject";
private static final String DAEMON_INSERTION_ERROR_MAIL_BODY = "module.workflow.ticketing.daemon.creationBrouillonDaemon.error.mail.insertion.body";
private static final String DAEMON_SUPPRESSION_ERROR_MAIL_SUBJECT = "module.workflow.ticketing.daemon.creationBrouillonDaemon.error.mail.suppression.subject";
private static final String DAEMON_SUPPRESSION_ERROR_MAIL_BODY = "module.workflow.ticketing.daemon.creationBrouillonDaemon.error.mail.suppression.body";
private static final String DAEMON_ALERT_MAIL_ERROR_RECIPIENT = PluginConfigurationService.getString( PluginConfigurationService.PROPERTY_ALERT_MAIL_ERROR_RECIPIENT,
"DSTISTINBSUNparticipationcitoyenne@paris.fr" );
private static Plugin _plugin = WorkflowTicketingPlugin.getPlugin( );
private final StockageService _stockageS3DaemonMinio = new StockageService( Profilstrois.PROFIL_MINIO_DAEMON_NAME );
private final StockageService _stockageS3ScannerDaemonNetapp = new StockageService( Profilstrois.PROFIL_NETAPP_COURRIER_SCANNER_DAEMON_NAME );
/**
* Statut "Supprimé"
*/
private int _nIdStateDeleted = AppPropertiesService.getPropertyInt( "workflow.ticketing.state.id.deleted", TicketingConstants.PROPERTY_UNSET_INT );
private String _strchannelScanName = AppPropertiesService.getProperty( PROPERTY_CHANNEL_SCAN_NAME );
private String _strAdminUserId = AppPropertiesService.getProperty( PROPERTY_ID_ADMIN_USER_FOR_DRAFT_DAEMON );
private String _strEmailSender = AppPropertiesService.getProperty( PROPERTY_EMAIL_SENDER_FOR_DRAFT_DAEMON );
private static final int MAX_FILES_BY_DOSSIERS3 = PluginConfigurationService.getInt( PluginConfigurationService.PROPERTY_MAX_FILES_BY_DOSSIERS3_FOR_DRAFT_CREATION, 10 );
private List<String> _erreurPathsList = new ArrayList<>( );
private String _destination = "";
private List<ReferentielScanner> _referentielScannerList = new ArrayList<>( );
TicketInitService _ticketInitService = SpringContextService.getBean( TicketInitService.BEAN_NAME );
// Errors
private static final String ERROR_RESOURCE_NOT_FOUND = "Resource not found";
private static Locale _local = I18nService.getDefaultLocale( );
/**
* Constructor
*/
public TicketCreationBrouillonDaemon( )
{
super( );
}
/**
* {@inheritDoc}
*/
@Override
public void run( )
{
StringJoiner sb = new StringJoiner( "\n\r" );
_destination = FileUtils.cheminDepotFichierUsager( TicketingConstants.CODE_APPLI );
_referentielScannerList = ReferentielScannerHome.getReferentielScannersList( );
sb.add( "Début de la création des brouillons" );
purgeDeletedTicketOrDraft( sb );
cleanErrorRegistered( );
createBrouillonProcess( sb );
sb.add( "Fin de la création des brouillons" );
setLastRunLogs( sb.toString( ) );
}
// Purge ticket ou brouillon au statut supprimé
private void purgeDeletedTicketOrDraft( StringJoiner sb )
{
// commencer par récupérer les tickets au status supprimé
List<Integer> listResourceDeletedId = _workflowService.getResourceIdListByIdState( _nIdStateDeleted, Ticket.TICKET_RESOURCE_TYPE );
if ( !listResourceDeletedId.isEmpty( ) )
{
for ( Integer idTicket : listResourceDeletedId )
{
Ticket ticket = TicketHome.findByPrimaryKey( idTicket );
if ( null != ticket )
{
deleteDraftAndAttchement( ticket );
}
}
}
}
// tenter de supprimer les erreurs de suppression connue
private void cleanErrorRegistered( )
{
List<ErreurScannerStrois> erreurList = ErreurScannerStroisHome.getErreurScannerStroisList( );
List<ErreurScannerStrois> erreurInsertion = erreurList.stream( ).filter( e -> e.getPbInsertion( ) ).collect( Collectors.toList( ) );
List<ErreurScannerStrois> erreurSuppression = erreurList.stream( ).filter( e -> !e.getPbInsertion( ) ).collect( Collectors.toList( ) );
tryToDeleteAgainPJAboutErreurPath( erreurSuppression );
tryToInsertAgain( erreurInsertion );
}
private void tryToInsertAgain( List<ErreurScannerStrois> erreurInsertion )
{
for ( ErreurScannerStrois erreur : erreurInsertion )
{
if ( _stockageS3ScannerDaemonNetapp.isObjectExistWithStockageService( _stockageS3ScannerDaemonNetapp, erreur.getPath( ) ) )
{
if ( !erreur.isOverSize( ) )
{
int idCoreFile = 0;
List<Integer> idFileList = new ArrayList<>( );
java.sql.Timestamp timestampDate = new java.sql.Timestamp( new Date( ).getTime( ) );
String fileName = StringUtils.substringAfterLast( erreur.getPath( ), "/" );
String[] scannerDossier = erreur.getPath( ).split( "/" );
List<ReferentielScanner> scannerFilter = _referentielScannerList.stream( ).filter( s -> s.getDossierStrois( ).equals( scannerDossier[0] ) ).collect( Collectors.toList( ) );
idCoreFile = TicketPjHome.insertPjFromScannerAndGetIdCoreFile( fileName, timestampDate );
if ( idCoreFile != 0 )
{
idFileList.add( idCoreFile );
createDraftTryAgain( scannerFilter.get( 0 ), idFileList, erreur.getPath( ), _destination, erreur );
} else
{
sendMail( erreur.getPath( ), _destination, true, false );
}
}
} else
{
ErreurScannerStroisHome.removeByFilePath( erreur.getPath( ) );
}
}
}
private void createDraftTryAgain( ReferentielScanner scanner, List<Integer> idFileList, String filepath, String destination, ErreurScannerStrois erreur )
{
boolean insertionSuccess = false;
Ticket ticket = createDraftDefault( scanner.getIdCategory( ) );
List<ErreurScannerStrois> erreurList = ErreurScannerStroisHome.getErreurScannerStroisList( );
_erreurPathsList = erreurList.stream( ).map( e -> e.getPath( ) ).collect( Collectors.toList( ) );
int idResponseCreated = 0;
try
{
TransactionManager.beginTransaction( _plugin );
int idTicketPj = insertTicketPjScanner( idFileList, ticket, true );
byte[] file = _stockageS3ScannerDaemonNetapp.loadFileFromS3Serveur( filepath );
String technicalName = createTechnicalFileName( idFileList.get( 0 ), ticket.getId( ) );
String fileSolenS3Path = _stockageS3DaemonMinio.saveFileToS3Server( file, destination + technicalName );
insertionSuccess = _stockageS3DaemonMinio.isObjectExistWithStockageService( _stockageS3DaemonMinio, fileSolenS3Path );
if ( !insertionSuccess )
{
TicketHome.deleteCoreFile( idFileList );
ResponseHome.remove( idResponseCreated );
TicketHome.remove( ticket.getId( ) );
TicketInitService.doRemoveWorkFlowResource( ticket.getId( ) );
sendMail( filepath, destination, erreur.getPbInsertion( ), erreur.isOverSize( ) );
} else
{
idResponseCreated = TicketPjHome.insertResponseAndGetIdCoreFile( idFileList.get( 0 ) );
TicketHome.insertTicketResponse( ticket.getId( ), idResponseCreated );
if ( idTicketPj != 0 )
{
TicketPj pj = TicketPjHome.findByPrimaryKey( idTicketPj );
pj.setTechnicalName( technicalName );
pj.setUrlTicketing( fileSolenS3Path );
pj.setStockageTicketing( 1 );
pj.setIdResponse( idResponseCreated );
TicketPjHome.update( pj );
}
// suppression S3 courrier postal / scanner
removeFromS3scanner( filepath, _stockageS3ScannerDaemonNetapp, destination );
ErreurScannerStroisHome.removeByFilePath( erreur.getPath( ) );
// Immediate indexation of the Ticket
WorkflowCapableJspBean.immediateTicketIndexing( ticket.getId( ) );
}
} catch ( Exception e )
{
TransactionManager.rollBack( _plugin );
AppLogService.error( e );
TicketHome.deleteCoreFile( idFileList );
ResponseHome.remove( idResponseCreated );
TicketHome.remove( ticket.getId( ) );
TicketInitService.doRemoveWorkFlowResource( ticket.getId( ) );
if ( !insertionSuccess )
{
sendMail( filepath, destination, erreur.getPbInsertion( ), erreur.isOverSize( ) );
}
}
TransactionManager.commitTransaction( _plugin );
}
/**
* Create a ticket draft if file exist from a postal mail
*
* @param sb
* the logs
*/
private void createBrouillonProcess( StringJoiner sb )
{
List<ErreurScannerStrois> erreurList = ErreurScannerStroisHome.getErreurScannerStroisList( );
_erreurPathsList = erreurList.stream( ).map( e -> e.getPath( ) ).collect( Collectors.toList( ) );
sb.add( "Nombre de fichiers maximum par dossier S3 : " + MAX_FILES_BY_DOSSIERS3 );
for ( ReferentielScanner scanner : _referentielScannerList )
{
Iterable<Result<Item>> filesForDossierS3List = null;
// Appel récupération des fichiers du dossierS3 avec prefix du dossier du scanner
filesForDossierS3List = _stockageS3ScannerDaemonNetapp.findAllFileInPrefix( _stockageS3ScannerDaemonNetapp, scanner.getDossierStrois( ) );
if ( null != filesForDossierS3List )
{
int n = 1;
for ( Result<Item> result : filesForDossierS3List )
{
// nombre de fichier max hors erreurs existantes
if ( n <= MAX_FILES_BY_DOSSIERS3 )
{
n = createBrouillonFromPJScanner( n, result, scanner, sb );
}
}
}
}
}
private int createBrouillonFromPJScanner( int n, Result<Item> result, ReferentielScanner scanner, StringJoiner sb )
{
int iteration = n;
String filepath = "";
try
{
TransactionManager.beginTransaction( _plugin );
filepath = result.get( ).objectName( );
long sizeFile = result.get( ).size( );
String fileName = StringUtils.substringAfterLast( filepath, "/" );
String extension = StringUtils.substringAfterLast( fileName, "." );
// pas de nom de fichier cas de test winscp uniquement
if ( !fileName.isEmpty( ) )
{
// recherche d'erreurs anciennes
boolean isAnOldErreurPath = _erreurPathsList.contains( filepath );
if ( !isAnOldErreurPath )
{
if ( extension.equals( "exe" ) )
{
removeFromS3scanner( filepath, _stockageS3ScannerDaemonNetapp, _destination );
sb.add( "suppression fichier avec extension non autorisée : " + filepath );
} else if ( sizeFile == 0 )
{
removeFromS3scanner( filepath, _stockageS3ScannerDaemonNetapp, _destination );
sb.add( "suppression fichier de taille 0 : " + filepath );
} else if ( sizeFile > 10000000 )
{
addScannerS3Erreur( filepath, _destination, true, true );
} else
{
// insertion minio SOLEN
createDraft( scanner, filepath, _destination, result );
}
} else
{
iteration--;
}
} else
{
iteration--;
}
} catch ( MinioException | IllegalArgumentException | NoSuchAlgorithmException | IOException | InvalidKeyException e )
{
TransactionManager.rollBack( _plugin );
AppLogService.error( e );
addScannerS3Erreur( filepath, _destination, true, false );
}
TransactionManager.commitTransaction( _plugin );
iteration++;
return iteration;
}
private void createDraft( ReferentielScanner scanner, String filepath, String destination, Result<Item> result )
{
boolean insertionSuccess = false;
List<Integer> idFileList = new ArrayList<>( );
int idCoreFile = 0;
// creation du ticket avec les valeurs par defaut
Ticket ticket = createDraftDefault( scanner.getIdCategory( ) );
int idResponseCreated = 0;
try
{
TransactionManager.beginTransaction( _plugin );
ZonedDateTime zoneDateModified = result.get( ).lastModified( );
Date dateModified = java.util.Date.from( zoneDateModified.toInstant( ) );
java.sql.Timestamp timestampDate = new java.sql.Timestamp( dateModified.getTime( ) );
String fileName = StringUtils.substringAfterLast( filepath, "/" );
idCoreFile = TicketPjHome.insertPjFromScannerAndGetIdCoreFile( fileName, timestampDate );
if ( idCoreFile != 0 )
{
idFileList.add( idCoreFile );
int idTicketPj = insertTicketPjScanner( idFileList, ticket, true );
byte[] file = _stockageS3ScannerDaemonNetapp.loadFileFromS3Serveur( filepath );
String technicalName = createTechnicalFileName( idFileList.get( 0 ), ticket.getId( ) );
String fileSolenS3Path = _stockageS3DaemonMinio.saveFileToS3Server( file, destination + technicalName );
insertionSuccess = _stockageS3DaemonMinio.isObjectExistWithStockageService( _stockageS3DaemonMinio, fileSolenS3Path );
if ( !insertionSuccess )
{
TicketHome.deleteCoreFile( idFileList );
ResponseHome.remove( idResponseCreated );
TicketInitService.doRemoveWorkFlowResource( ticket.getId( ) );
addScannerS3Erreur( filepath, destination, true, false );
sendMail( filepath, destination, true, false );
} else
{
idResponseCreated = TicketPjHome.insertResponseAndGetIdCoreFile( idFileList.get( 0 ) );
TicketHome.insertTicketResponse( ticket.getId( ), idResponseCreated );
if ( idTicketPj != 0 )
{
TicketPj pj = TicketPjHome.findByPrimaryKey( idTicketPj );
pj.setTechnicalName( technicalName );
pj.setUrlTicketing( fileSolenS3Path );
pj.setStockageTicketing( 1 );
pj.setIdResponse( idResponseCreated );
TicketPjHome.update( pj );
}
// suppression S3 courrier postal / scanner
removeFromS3scanner( filepath, _stockageS3ScannerDaemonNetapp, destination );
// Immediate indexation of the Ticket
WorkflowCapableJspBean.immediateTicketIndexing( ticket.getId( ) );
}
}
else
{
addScannerS3Erreur( filepath, destination, true, false );
sendMail( filepath, destination, true, false );
}
} catch ( Exception e )
{
TransactionManager.rollBack( _plugin );
AppLogService.error( e );
TicketHome.deleteCoreFile( idFileList );
ResponseHome.remove( idResponseCreated );
TicketHome.remove( ticket.getId( ) );
idFileList.remove( Integer.valueOf( idCoreFile ) );
addScannerS3Erreur( filepath, destination, true, false );
}
TransactionManager.commitTransaction( _plugin );
}
private void removeFromS3scanner( String filepath, StockageService stockageS3ScannerDaemonMinio, String destination )
{
boolean suppressionSuccess = stockageS3ScannerDaemonMinio.deleteFileOnS3Serveur( filepath );
if ( !suppressionSuccess )
{
addScannerS3Erreur( filepath, destination, false, false );
}
}
private void sendMail( String filepath, String destination, boolean isInsertionProblem, boolean isFileOvreSize )
{
String message = "";
String subject = "";
if ( isInsertionProblem )
{
subject = MessageFormat.format( I18nService.getLocalizedString( DAEMON_INSERTION_ERROR_MAIL_SUBJECT, Locale.FRENCH ), AppPropertiesService.getProperty( "lutece.env.name" ) );
message = MessageFormat.format( I18nService.getLocalizedString( DAEMON_INSERTION_ERROR_MAIL_BODY, Locale.FRENCH ), AppPropertiesService.getProperty( "strois.url.netapp.scanner" ),
filepath, AppPropertiesService.getProperty( "strois.url.minio" ), destination );
if(isFileOvreSize)
{
message += "<br> le fichier dépasse les 10 Mo autorisés";
}
} else
{
subject = MessageFormat.format( I18nService.getLocalizedString( DAEMON_SUPPRESSION_ERROR_MAIL_SUBJECT, _local ), AppPropertiesService.getProperty( "lutece.env.name" ) );
message = MessageFormat.format( I18nService.getLocalizedString( DAEMON_SUPPRESSION_ERROR_MAIL_BODY, Locale.FRENCH ), AppPropertiesService.getProperty( "strois.url.netapp.scanner" ),
filepath );
}
String fromSenderName = "CreationBrouillonDaemon";
String fromSenderEmail = _strEmailSender;
MailService.sendMailHtml( DAEMON_ALERT_MAIL_ERROR_RECIPIENT, fromSenderName, fromSenderEmail, subject, message );
}
private void deleteDraftAndAttchement( Ticket ticket )
{
try
{
TransactionManager.beginTransaction( _plugin );
deleteDraftAttachmentTicket( ticket );
WorkflowCapableJspBean.doRemoveWorkFlowResource( ticket.getId( ) );
IndexerActionHome.removeByIdTicket( ticket.getId( ) );
TicketHome.remove( ticket.getId( ) );
} catch ( Exception e )
{
TransactionManager.rollBack( _plugin );
AppLogService.error( e );
}
TransactionManager.commitTransaction( _plugin );
}
/**
* Find attachment for usager
*
* @param ticket
* the ticket to clean
* @param usager
* boolean true if the attachement is from usager
*
*/
private Map<Integer, Integer> findDraftAttachment( Ticket ticket, boolean usager )
{
return TicketPjHome.getIdFileToDeleteAndStockage( ticket.getId( ), usager );
}
/**
* Delete attachemant for a ticket core_file and core_physical_fle
*
* @param ticket
* the ticket to delete
*/
private void deleteDraftAttachment( Map<Integer, Integer> coreFileAndIdStockage )
{
if ( !coreFileAndIdStockage.isEmpty( ) )
{
for ( Entry<Integer, Integer> entry : coreFileAndIdStockage.entrySet( ) )
{
TicketPj pj = TicketPjHome.findByIdFile( entry.getKey( ) );
if ( pj.getStockageTicketing( ) == 1 )
{
_stockageS3DaemonMinio.deleteFileOnS3Serveur( pj.getUrlTicketing( ) );
FileHome.remove( entry.getKey( ) );
TicketPjHome.remove( pj.getId( ) );
}
}
}
}
/**
* Delete Draft attachement
*
* @param ticket
* the ticket to delete
*/
private void deleteDraftAttachmentTicket( Ticket ticket )
{
Map<Integer, Integer> usagerAttachment = findDraftAttachment( ticket, true );
deleteDraftAttachment( usagerAttachment );
}
/**
* Create Draft attachement
*
* @param sb
*/
private Ticket createDraftDefault( int idCategory )
{
Ticket ticket = new Ticket( );
try
{
TransactionManager.beginTransaction( _plugin );
TicketInitService ticketInitService = SpringContextService.getBean( TicketInitService.BEAN_NAME );
TicketCategory category = TicketCategoryHome.findByPrimaryKey( idCategory );
TicketAddress address = new TicketAddress( );
Optional<Quartier> optQuartier = QuartierHome.findByPrimaryKey( 1 );
Quartier quartier = optQuartier.orElseThrow( ( ) -> new AppException( ERROR_RESOURCE_NOT_FOUND ) );
address.setAddress( MENTION_A_PRECISER );
address.setPostalCode( "00" );
address.setCity( MENTION_A_PRECISER );
address.setQuartier( quartier );
ticket.setTicketCategory( category );
ticket.setIdUserTitle( 0 );
ticket.setUserTitle( "" );
ticket.setFirstname( MENTION_A_PRECISER );
ticket.setLastname( MENTION_A_PRECISER );
ticket.setEmail( "" );
ticket.setTicketComment( MENTION_A_PRECISER );
ticket.setTicketAddress( address );
ticket.setDateUpdate( new Timestamp( new Date( ).getTime( ) ) );
ticket.setDateCreate( new Timestamp( new Date( ).getTime( ) ) );
ticket.setIdContactMode( 2 );
Channel channel = ChannelHome.findByName( _strchannelScanName );
ticket.setChannel( channel );
TicketHome.create( ticket );
User user = AdminUserHome.findByPrimaryKey( Integer.parseInt( _strAdminUserId ) );
ticketInitService.doProcessNextWorkflowActionInit( ticket, null, _local, user );
TransactionManager.commitTransaction( _plugin );
} catch ( Exception e )
{
TransactionManager.rollBack( _plugin );
AppLogService.error( e );
}
return ticket;
}
/**
* Insert pj in ticketing_ticket_pj with id file list from scanner and get the id
*
* @param idFileList
* the id file list
* @param ticket
* the ticket
* @param isUsagerPj
* true if the pj is from usager otherwise false
* @return the id pj
*/
private int insertTicketPjScanner( List<Integer> idFileList, Ticket ticket, boolean isUsagerPj )
{
int idPj = 0;
if ( ( null != idFileList ) && !idFileList.isEmpty( ) )
{
for ( Integer idFile : idFileList )
{
TicketPj pj = new TicketPj( );
pj.setIdTicket( ticket.getId( ) );
pj.setIdFile( idFile );
pj.setUrlTicketing( "" );
pj.setStockageTicketing( -1 );
pj.setUsager( isUsagerPj );
idPj = TicketPjHome.createPjAndGetId( pj );
}
}
return idPj;
}
/**
* Update the name of file in core_file
*
* @param idFileList
* the id file list
* @param ticket
* the ticket
*/
private String createTechnicalFileName( int idFile, int idTicket )
{
String newNameForS3 = "";
File file = FileHome.findByPrimaryKey( idFile );
if ( null != file )
{
newNameForS3 = TicketTransfertPjService.nomDepotFichierUsager( idTicket, file.getTitle( ) );
}
return newNameForS3;
}
// Gestion des erreurs
/**
* Insert a record in table ticketing_erreur_scanner_strois
*
* @param filepath
* the
* @param isInsertion
* true if it is an insertion error
*/
private void addScannerS3Erreur( String filepath, String destination, boolean isInsertion,
boolean isFileOverSize )
{
List<ErreurScannerStrois> erreursTotalesList = ErreurScannerStroisHome.getErreurScannerStroisList( );
List<String> erreursTotalesPathsList = erreursTotalesList.stream( ).map( e -> e.getPath( ) ).collect( Collectors.toList( ) );
if ( !erreursTotalesPathsList.contains( filepath ) )
{
ErreurScannerStrois erreurSuppression = new ErreurScannerStrois( );
erreurSuppression.setPath( filepath );
erreurSuppression.setFileName( StringUtils.substringAfterLast( filepath, "/" ) );
erreurSuppression.setDateErreur( new Timestamp( new java.util.Date( ).getTime( ) ) );
erreurSuppression.setPbInsertion( isInsertion );
erreurSuppression.setIsOverSize( isFileOverSize );
ErreurScannerStroisHome.create( erreurSuppression );
sendMail( filepath, destination, isInsertion, isFileOverSize );
}
}
/**
* Try to delete the path on s3 courier postal which recorded on error table
*
* @param erreurPathsSuppression
* the list of the path in erreur for suppression
*/
private void tryToDeleteAgainPJAboutErreurPath( List<ErreurScannerStrois> erreurPathsSuppression )
{
for ( ErreurScannerStrois erreur : erreurPathsSuppression )
{
boolean suppressionOk = _stockageS3ScannerDaemonNetapp.deleteFileOnS3Serveur( erreur.getPath( ) );
if ( suppressionOk )
{
ErreurScannerStroisHome.removeByFilePath( erreur.getPath( ) );
}
}
}
}