Loading
Configurar y mantener Ejecución de minorista
Índice de materias
Seleccionar filtros

          No hay resultados
          No hay resultados
          Estas son algunas sugerencias de búsqueda

          Compruebe la ortografía de sus palabras clave.
          Utilice términos de búsqueda más generales.
          Seleccione menos filtros para ampliar su búsqueda.

          Buscar en toda la Ayuda de Salesforce
          Recomendar visitas empleando Apex

          Recomendar visitas empleando Apex

          Cree una clase de Apex para enumerar los establecimientos específicos para los que Einstein debe proporcionar recomendaciones de visitas. Luego puede crear un flujo y agregar la clase de Apex como un elemento Acción.

          Ediciones necesarias

          Disponible en Lightning Experience en Professional Edition, Unlimited Edition y Enterprise Edition con Consumer Goods Cloud activado.
          Importante
          Importante Para utilizar una acción de Apex en un flujo, solicite a su desarrollador anotar el método apropiado con @InvocableMethod.

          Este es el aspecto de una clase de Apex para filtrar establecimientos:

          global class BulkGetVisitRecommendations {
            @InvocableMethod(label='Bulk Get Visit Recommendations from Apex')
            global static List<Recommendation> getRecommendations(List<List<String>> inputList) {
               List<Recommendation> recommendations = new List<Recommendation>();
               if(inputList != null && inputList.size() > 0 ){
                   Recommendation recommendation = new Recommendation();
                   List<String> recommendedStoreIds = new List<String>();
                   List<String> reasonForRecommendations = new List<String>();
                   List<String> input = inputList.get(0);
                   //Last element in input is DateString
                   Date visitRecommendationTargetDate = Date.valueof(input.get(input.size()-1));
                   populateRecommendationsBasedOnCases(input,recommendedStoreIds,reasonForRecommendations);
                   populateRecommendationsBasedOnPromotions(input,visitRecommendationTargetDate,recommendedStoreIds,reasonForRecommendations);
                   populateRecommendationsBasedOnOutOfStockKPIs(input,visitRecommendationTargetDate,recommendedStoreIds,reasonForRecommendations);
                   recommendation.StoreIds = recommendedStoreIds;
                   recommendation.RecommendationReasons = reasonForRecommendations;
                   recommendations.add(recommendation);
               }
               return recommendations;
            }
          
            public static void populateRecommendationsBasedOnCases(List<String> storeIds,List<String> recommendedStoreIds,List<String> reasonForRecommendations) {
              List<RetailStore> stores = [select Id, PrimaryContactId from RetailStore where Id IN :storeIds AND PrimaryContactId != null];
              if(stores!=null){
                  //Check for open cases agianst primarycontact of store.
                  //System.debug('stores found ');
                  Map<String, String> StoreToprimaryContactMap = new Map<String,String>();
                  if(stores.size() > 0){
                    for(RetailStore store : stores){
                      StoreToPrimaryContactMap.put(store.Id,store.PrimaryContactId);
                    }
                
                      List<AggregateResult> casesForPrimaryContactOfStores = [Select contactId, max(createdDate) from Case where isClosed = false AND contactid in :StoreToPrimaryContactMap.values() group by contactId];
                      Map<String, DateTime> primaryContactToCaseCreationDateTimeMap = new Map<String,DateTime>();
                      if(casesForPrimaryContactOfStores != null && casesForPrimaryContactOfStores.size() > 0){
                        for(AggregateResult caseResult : casesForPrimaryContactOfStores){
                          Date caseDate = Date.valueOf(caseResult.get('expr0'));
                          DateTime caseDateTime = DateTime.newInstance(caseDate.year(),caseDate.month(),caseDate.day(),0,0,0);
                          primaryContactToCaseCreationDateTimeMap.put(String.valueof(caseResult.get('ContactId')),caseDateTime);
                        }
                      }
                       //Get latest Visit for PlaceId
                       List< AggregateResult > latestVisitsForStores = [Select PlaceId, max(PlannedVisitStartTime) FROM Visit where PlaceId in :StoreToPrimaryContactMap.keyset() group by PlaceId];
                          if(latestVisitsForStores !=null && latestVisitsForStores.size() > 0){
                             for(AggregateResult visit : latestVisitsForStores){
                               String storeId = String.valueof(visit.get('PlaceId'));
                               String primaryContactId = StoreToprimaryContactMap.get(storeId);
                               //System.debug('primaryContactId found '+primaryContactId+' latest Visit Date for store '+storeId+' is '+visit.get('expr0'));
                               DateTime caseCreationDateTime = primaryContactToCaseCreationDateTimeMap.get(primaryContactId);
                               if(DateTime.valueof(visit.get('expr0')) < caseCreationDateTime){
                                  // No visit is created after case is in open state.
                                  reasonForRecommendations.add('No visit created after the latest case logged against primary contact');
                                  recommendedStoreIds.add(storeId);
                               }
                             }
                             
                          }
                      }
                  }else{
                   System.debug('PrimaryContact is empty for all stores');
                  }
            }
          
            public static void populateRecommendationsBasedOnPromotions(List<String> storeIds, Date visitRecommendationTargetDate, List<String> recommendedStoreIds,List<String> reasonForRecommendations) {
              Integer noOfDaysToConsiderPromotion = 7;
              Date promoStartDate = visitRecommendationTargetDate.addDays(noOfDaysToConsiderPromotion);
              Date promoEndDate = visitRecommendationTargetDate.addDays(365);
              List<PromotionChannel> promotionchannels = [Select Id, RetailStoreId from PromotionChannel where RetailStoreId IN :storeIds AND startDate > :promoStartDate AND (endDate < :promoEndDate OR endDate = null)];
              if(promotionchannels != null){
                for(PromotionChannel promotionChannel : promotionchannels){
                  //upcoming promotion for store
                  //System.debug('promotionchannels for storeId - ' + promotionChannel.RetailStoreId+' is '+promotionchannel);
                  reasonForRecommendations.add('Upcoming Promotion for the store scheduled after '+noOfDaysToConsiderPromotion +' days');
                  recommendedStoreIds.add(promotionChannel.RetailStoreId);
                }
              }
            }
            
            public static void populateRecommendationsBasedOnOutOfStockKPIs(List<String> storeIds,Date visitRecommendationTargetDate,List<String> recommendedStoreIds,List<String> reasonForRecommendations) {
              Integer noOfVisitRecordsForStore = 5;
              Integer noofDaysStoreNotVisited = 14;
              Date actualVisitStartDateForStoreNotVisited = visitRecommendationTargetDate.addDays(-noofDaysStoreNotVisited);
                DateTime actualVisitStartDateTimeForStoreNotVisited = DateTime.newInstance(actualVisitStartDateForStoreNotVisited.year(),actualVisitStartDateForStoreNotVisited.month(),actualVisitStartDateForStoreNotVisited.day(),0,0,0);
                Integer noOfVisitsToCheckForOOS = 1;
                String outOfStock = 'OutOfStock';
                List<Visit> visitsExecuted = [SELECT Id,PlaceId FROM Visit WHERE PlaceId IN :storeIds AND ActualVisitStartTime != null AND ActualVisitStartTime > :actualVisitStartDateTimeForStoreNotVisited];
                List<String> storeIdsCopy = storeIds;
                if(visitsExecuted!= null && visitsExecuted.size() > 0){
                   // visit is already executed for the stores 
                    for (Visit visit : visitsExecuted) {
                      Integer index =storeIdsCopy.indexOf(visit.PlaceId);
                      if(index != -1)
                        storeIdsCopy.remove(index);
                    }
                }
                //System.debug('Visit is not executed for '+storeIdsCopy.size()+' stores');
                Map<String,String> visitIdToStoreIdMap = new Map<String,String>();
                List<String> filteredVisitIdsToCheckOutOfStockKPIS = new List<String>();
                Map<String, List<String>> storeIdToVisits = new Map<String,List<String>>();
                List<Visit> visits = [SELECT Id,PlaceId FROM Visit WHERE PlaceId IN :storeIdsCopy AND ActualVisitStartTime != null ORDER BY ActualVisitStartTime]; 
                  for (Visit visit : visits) {
                    String storeId = visit.PlaceId;
                    visitIdToStoreIdMap.put(visit.Id,storeId);
                    if (storeIdToVisits.get(storeId) == null){
                      List<String> newList = new List<String>();
                      newList.add(visit.Id);
                      storeIdToVisits.put(storeId, newList);
                      filteredVisitIdsToCheckOutOfStockKPIS.add(visit.Id);
                    }else{
                      // add visit id for store only if no. of visits for each store is less than configured #noOfVisitRecordsForStore
                      if(storeIdToVisits.get(storeId).size() <= noOfVisitRecordsForStore){
                         storeIdToVisits.get(storeId).add(visit.Id);
                         filteredVisitIdsToCheckOutOfStockKPIS.add(visit.Id);
                      }
                    }
                  }
                  Map<String,Integer> storeIdToOosKPICount = new Map<String,Integer>();
                  List<RetailVisitKpi> oosRetailVisitkpis= [SELECT Id, Assessmenttask.parentid FROM RetailVisitKpi WHERE Assessmenttask.parentid IN :filteredVisitIdsToCheckOutOfStockKPIS AND Type = :outOfStock AND TargetBooleanValue = 'True'];
                  for (RetailVisitKpi rvkpi : oosRetailVisitkpis) {
                      String visitId = rvkpi.Assessmenttask.parentid;
                      String storeId = visitIdToStoreIdMap.get(visitId);
                      Integer currentStoreIdOOSKPICount = storeIdToOosKPICount.get(storeId);
                      if(currentStoreIdOOSKPICount == null){
                        storeIdToOosKPICount.put(storeId,1);
                      }else{
                        Integer newStoreIdOOSKPICount = currentStoreIdOOSKPICount+1;
                        storeIdToOosKPICount.put(storeId,newStoreIdOOSKPICount);
                        //System.debug('OOS KPI count for '+storeId+' is '+newStoreIdOOSKPICount); 
                      }
                      if(storeIdToOosKPICount.get(storeId) == noOfVisitsToCheckForOOS){
                          reasonForRecommendations.add('Store is not visited in last '+noofDaysStoreNotVisited + ' days and there are atleast '+noOfVisitsToCheckForOOS+ ' Out of stock kpis in previous visits');
                          recommendedStoreIds.add(storeId);
                      }
                  }
            }
          
          
            global class Recommendation {
              @InvocableVariable
              global List<String> StoreIds;
              @InvocableVariable
              global List<String> RecommendationReasons;
            }
          
          }
           
          Cargando
          Salesforce Help | Article