Skip to content

Commit

Permalink
Merge pull request dimagi#86 from tstalka/GS_prof
Browse files Browse the repository at this point in the history
243857: GS profitability
  • Loading branch information
tstalka authored Mar 7, 2017
2 parents 5a4acc7 + 457afad commit 9b50b39
Show file tree
Hide file tree
Showing 15 changed files with 540 additions and 230 deletions.
2 changes: 1 addition & 1 deletion src/classes/BatchCalculateEVDiffSch.cls
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Calculates NetDiff for Closed opps in last month (Pipeline Snapshot wasn't created).
*/
public class BatchCalculateEVDiffSch implements Schedulable{
public class BatchCalculateEVDiffSch implements Schedulable {

public void execute(SchedulableContext sc) {
Database.executeBatch(new BatchCalculateEVDiff(Date.today().toStartOfMonth().addDays(-1)));
Expand Down
224 changes: 159 additions & 65 deletions src/classes/ContractSnapshotTest.cls

Large diffs are not rendered by default.

62 changes: 62 additions & 0 deletions src/classes/ForPeriodCalcSnapshotBatch.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Calculates for period fields in Pipeline Snapshot custom object.
*/
public class ForPeriodCalcSnapshotBatch implements Database.Batchable<Pipeline_Snapshot__c>, Database.Stateful {

private Boolean forTotal;

public ForPeriodCalcSnapshotBatch(Boolean forTotal){
this.forTotal = forTotal;
}

public List<Pipeline_Snapshot__c> start(Database.BatchableContext context) {
List<Pipeline_Snapshot__c> snaps = new List<Pipeline_Snapshot__c>();
if (this.forTotal == false) {
snaps = [SELECT Id, Contract__c, Work_Completed__c, Services_Spend__c, Expense_Travel_Spend__c, Product_Spend__c, Total_Calculated_Costs__c, GS_Services_Completed__c,
GS_Services_Completed_Handover__c, GS_Net_Income_to_Date__c, GS_Net_Income_to_Date_Handover__c,
Work_Completed_for_Period__c, Expense_Travel_Spend_for_Period__c, GS_Net_Income_for_Period__c, GS_Net_Income_for_Period_by_Handover__c,
GS_Services_Handover_Completed_for_Per__c, GS_Services_Completed_for_Period__c, Product_Spend_for_Period__c, Services_Spend_for_Period__c,
Total_Calculated_Costs_for_Period__c, Month_Date__c
FROM Pipeline_Snapshot__c WHERE CreatedDate >= YESTERDAY AND Stage__c != 'Total' AND Source_Type__c = 'Contract'];
} else {
snaps = [SELECT Id, Contract__c, Work_Completed__c, Services_Spend__c, Expense_Travel_Spend__c, Product_Spend__c, Total_Calculated_Costs__c, GS_Services_Completed__c,
GS_Services_Completed_Handover__c, GS_Net_Income_to_Date__c, GS_Net_Income_to_Date_Handover__c,
Work_Completed_for_Period__c, Expense_Travel_Spend_for_Period__c, GS_Net_Income_for_Period__c, GS_Net_Income_for_Period_by_Handover__c,
GS_Services_Handover_Completed_for_Per__c, GS_Services_Completed_for_Period__c, Product_Spend_for_Period__c, Services_Spend_for_Period__c,
Total_Calculated_Costs_for_Period__c, Month_Date__c
FROM Pipeline_Snapshot__c WHERE CreatedDate >= YESTERDAY AND Stage__c = 'Total' AND Source_Type__c = 'Contract'];
}
System.debug('snaps ' + snaps.size());
return snaps;
}

public void execute(Database.BatchableContext context, List<Pipeline_Snapshot__c> snapshots) {
System.debug('snapshots: ' + snapshots.size());
List<Pipeline_Snapshot__c> toUpdate = new List<Pipeline_Snapshot__c>();
try {
Map<Id, Pipeline_Snapshot__c> oldSnapshots = SnapshotHelper.getOldSnapshots(snapshots, forTotal);
for (Pipeline_Snapshot__c sn : snapshots) {
Pipeline_Snapshot__c oldSn = new Pipeline_Snapshot__c();
if (sn.Contract__c != null && oldSnapshots.containsKey(sn.Contract__c)) {
oldSn = oldSnapshots.get(sn.Contract__c);
}
sn = SnapshotHelper.calculateForPeriod(sn, oldSn);
toUpdate.add(sn);
}
update toUpdate;
} catch(Exception ex) {
System.debug('ERROR:' + ex);
if (!Test.isRunningTest()) {
BatchDefaultSettings__c settings = BatchDefaultSettings__c.getOrgDefaults();
EmailHelper.sendEmailFromException(settings.Error_Emails__c.split(','), 'For Period calculation error', 'Period calculation error', ex);
}
}
}

public void finish(Database.BatchableContext context) {
if (this.forTotal == false) {
Database.executeBatch(new ForPeriodCalcSnapshotBatch(true), 50);
}
}

}
5 changes: 5 additions & 0 deletions src/classes/ForPeriodCalcSnapshotBatch.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>36.0</apiVersion>
<status>Active</status>
</ApexClass>
205 changes: 91 additions & 114 deletions src/classes/GSOverallCalculationBatch.cls
Original file line number Diff line number Diff line change
@@ -1,159 +1,136 @@
/**
* Calculates GS Quality for Overall Status and for Customer Satisfaction in PRO Snapshots.
*/
public without sharing class GSOverallCalculationBatch implements Database.Batchable<Project_Report_Out__c>, Database.Stateful {
public without sharing class GSOverallCalculationBatch implements Database.Batchable<Business_Unit__c>, Database.Stateful {

private List<Business_Unit__c> businessUnits;
private Business_Unit__c currentUnit;

private Double gsOverall;
private Double gsSatisfaction;
private Double gsBudget;
private Date startDate;
private Date endDate;
private Date currentDate;
private Double gsTotalOverall;
private Double gsTotalSatisfaction;
private Double gsTotalBudget;
private Date currentDate;
private Date cycleStartDate;
private Contract_Statistic__c contractStats;

public GSOverallCalculationBatch(List<Business_Unit__c> businessUnits) {
this.businessUnits = businessUnits;
if (this.businessUnits.size() > 0) {
this.currentUnit = this.businessUnits.get(0);
this.businessUnits.remove(0);
}
this.gsOverall = 0;
this.gsSatisfaction = 0;
this.gsBudget = 0;

public GSOverallCalculationBatch() {
this.currentDate = Date.today();
this.gsTotalOverall = 0;
this.gsTotalSatisfaction = 0;
this.gsTotalBudget = 0;
this.currentDate = Date.today();
this.contractStats = new Contract_Statistic__c();
}

public GSOverallCalculationBatch(List<Business_Unit__c> businessUnits, Contract_Statistic__c contractStats, Date currentDate,
Double gsTotalOverall, Double gsTotalSatisfaction, Double gsTotalBudget) {
this.businessUnits = businessUnits;
if (this.businessUnits.size() > 0) {
this.currentUnit = this.businessUnits.get(0);
this.businessUnits.remove(0);
}
this.gsOverall = 0;
this.gsSatisfaction = 0;
this.gsBudget = 0;
this.gsTotalOverall = gsTotalOverall;
this.gsTotalSatisfaction = gsTotalSatisfaction;
this.gsTotalBudget = gsTotalBudget;
public GSOverallCalculationBatch(Date currentDate) {
this.currentDate = currentDate;
this.contractStats = contractStats;
this.gsTotalOverall = 0;
this.gsTotalSatisfaction = 0;
this.gsTotalBudget = 0;
}

public List<Project_Report_Out__c> start(Database.BatchableContext BC) {
public List<Business_Unit__c> start(Database.BatchableContext BC) {
List<Date> thursDayList = PROHelper.GetAllThursDayOfMonth(this.currentDate.year(), this.currentDate.month());
List<Date> thursDayListLastMonth = PROHelper.GetAllThursDayOfMonth(this.currentDate.addMonths(-1).year(), this.currentDate.addMonths(-1).month());
List<Date> thursDayListNextMonth = PROHelper.GetAllThursDayOfMonth(this.currentDate.addMonths(1).year(), this.currentDate.addMonths(1).month());
Date startDate;
Date endDate;

if (this.currentDate < thursDayList[1]) {
startDate = thursDayListLastMonth[3];
endDate = thursDayList[1];
this.startDate = thursDayListLastMonth[3];
this.endDate = thursDayList[1];
} else if (this.currentDate < thursDayList[3]) {
startDate = thursDayList[1];
endDate = thursDayList[3];
this.startDate = thursDayList[1];
this.endDate = thursDayList[3];
} else {
startDate = thursDayList[3];
endDate = thursDayListNextMonth[1];
this.startDate = thursDayList[3];
this.endDate = thursDayListNextMonth[1];
}
System.debug('Start date : ' + startDate);
System.debug('End date : ' + endDate);

this.cycleStartDate = startDate;

if (this.currentUnit == null) {
return new List<Project_Report_Out__c>();
}
return [SELECT Id, Contract__c, Report_Out_Date__c, Contract_Snapshot__c, Contract_Snapshot__r.Project_Quality_Overall_Status__c,
Contract_Snapshot__r.Customer_Satisfaction_of_services__c, Contract_Snapshot__r.GS_Execution_Budget__c
FROM Project_Report_Out__c WHERE Contract__r.Prime_Contracting_Business_Unit__c =: this.currentUnit.Id AND Contract_Snapshot__c != ''
AND Report_Out_Date__c >=: startDate AND Report_Out_Date__c <: endDate];
return [SELECT Id, Name FROM Business_Unit__c];
}

public void execute(Database.BatchableContext BC, List<Project_Report_Out__c> scope) {
public void execute(Database.BatchableContext BC, List<Business_Unit__c> scope) {
try {
System.debug('scope ; ' + scope.size());
for (Project_Report_Out__c pro : scope) {
System.debug(pro.Report_Out_Date__c);
this.gsOverall += pro.Contract_Snapshot__r.Project_Quality_Overall_Status__c != null ? pro.Contract_Snapshot__r.Project_Quality_Overall_Status__c : 0;
this.gsSatisfaction += pro.Contract_Snapshot__r.Customer_Satisfaction_of_services__c != null ? pro.Contract_Snapshot__r.Customer_Satisfaction_of_services__c : 0;
this.gsBudget += pro.Contract_Snapshot__r.GS_Execution_Budget__c != null ? pro.Contract_Snapshot__r.GS_Execution_Budget__c : 0;
Map<Id, String> buMapping = new Map<Id, String>();
for (Business_Unit__c bu : scope) {
buMapping.put(bu.Id, bu.Name);
}
} catch (Exception ex) {
System.debug('Error : ' + ex);
if (!Test.isRunningTest()) {
BatchDefaultSettings__c settings = BatchDefaultSettings__c.getOrgDefaults();
EmailHelper.sendEmailFromException(settings.Error_Emails__c.split(','), 'GS Quality calculation error', 'GS Quality calculation error', ex);
}
}
}

public void finish(Database.BatchableContext BC) {
try {
System.debug('this.gsOverall : ' + this.gsOverall);
System.debug('this.gsSatisfaction : ' + this.gsSatisfaction);
System.debug('this.gsBudget : ' + this.gsBudget);
this.gsTotalOverall += this.gsOverall;
this.gsTotalSatisfaction += this.gsSatisfaction;
this.gsTotalBudget += this.gsBudget;

if (this.gsBudget == 0) {
this.gsOverall = 0;
this.gsSatisfaction = 0;
} else {
this.gsOverall = 100 * (this.gsOverall / this.gsBudget);
this.gsSatisfaction = 100 * (this.gsSatisfaction / this.gsBudget);
}
AggregateResult[] groupedResults = [SELECT Contract__r.Prime_Contracting_Business_Unit__c, SUM(Project_Quality_Overall_Status__c), SUM(Customer_Satisfaction_of_services__c),
SUM(GS_Execution_Budget__c), SUM(GS_Revenue__c)
FROM PRO_Contract_Snapshot__c WHERE Contract__c != null AND Snapshot_Date__c >=: this.startDate AND Snapshot_Date__c <: this.endDate
GROUP BY Contract__r.Prime_Contracting_Business_Unit__c];

String qualityField = (this.currentUnit.Name + '_GS_Overall_Status__c').toLowerCase();
String customerField = (this.currentUnit.Name + '_GS_Customer_Sat__c').toLowerCase();
Sobject sobj = (Sobject) this.contractStats;
if (hasSObjectField(qualityField, sobj) && hasSObjectField(customerField, sobj)) {
sobj.put(qualityField, this.gsOverall);
sobj.put(customerField, this.gsSatisfaction);
} else {
System.debug('cannot find field with name : ' + qualityField + ' ' + customerField);
if (!Test.isRunningTest()) {
EmailHelper.sendEmail(BatchDefaultSettings__c.getOrgDefaults().Error_Emails__c.split(','), 'Cannot find sObject field for GS Quality',
'Cannot find fields: ' + qualityField + ', ' + customerField);
Sobject sobj = (Sobject) new Contract_Statistic__c(PRO_Cycle_Date__c = this.startDate , DLAC_GS_Customer_Sat__c = 0, DLAC_GS_Overall_Status__c = 0, DSA_GS_Customer_Sat__c = 0,
DSA_GS_Overall_Status__c = 0, DSI_GS_Customer_Sat__c = 0, DSI_GS_Overall_Status__c = 0, DTZ_GS_Customer_Sat__c = 0, DTZ_GS_Overall_Status__c = 0,
DWA_GS_Customer_Sat__c = 0, DWA_GS_Overall_Status__c = 0, Inc_GS_Customer_Sat__c = 0, Inc_GS_Overall_Status__c = 0, Myanmar_GS_Customer_Sat__c = 0,
Myanmar_GS_Overall_Status__c = 0, GS_Quality_Total_Customer_Satisfaction__c = 0, GS_Quality_Total_Overall_Status__c = 0, DLAC_GS_Revenue__c = 0,
DSA_GS_Revenue__c = 0, DSI_GS_Revenue__c = 0, DTZ_GS_Revenue__c = 0, DWA_GS_Revenue__c = 0, Inc_GS_Revenue__c = 0, Myanmar_GS_Revenue__c = 0);

System.debug('groupedResults'+ groupedResults);
for (AggregateResult result : groupedResults) {
Id buId = (Id) result.get('Prime_Contracting_Business_Unit__c');
if (buId == null) {
continue;
}

Double gsOverall = (Double) result.get('expr0');
Double gsSatisfaction = (Double) result.get('expr1');
Double gsBudget = (Double) result.get('expr2');
Double gsRevenue = (Double) result.get('expr3');

this.gsTotalOverall += gsOverall != null ? gsOverall : 0;
this.gsTotalSatisfaction += gsSatisfaction != null ? gsSatisfaction : 0;
this.gsTotalBudget += gsBudget != null ? gsBudget : 0;

if (gsBudget == null || gsBudget == 0 || gsOverall == null || gsSatisfaction == null) {
gsOverall = 0;
gsSatisfaction = 0;
} else {
gsOverall = 100 * (gsOverall / gsBudget);
gsSatisfaction = 100 * (gsSatisfaction / gsBudget);
}

if (gsRevenue == null) {
gsRevenue = 0;
}

String buName = buMapping.get(buId);
String qualityField = (buName + '_GS_Overall_Status__c').toLowerCase();
String customerField = (buName + '_GS_Customer_Sat__c').toLowerCase();
String revenueField = (buName + '_GS_Revenue__c').toLowerCase();
if (hasSObjectField(qualityField, sobj) && hasSObjectField(customerField, sobj)) {
sobj.put(qualityField, gsOverall);
sobj.put(customerField, gsSatisfaction);
sobj.put(revenueField, gsRevenue);
} else {
System.debug('Cannot find field with name : ' + qualityField + ' ' + customerField);
if (!Test.isRunningTest()) {
EmailHelper.sendEmail(BatchDefaultSettings__c.getOrgDefaults().Error_Emails__c.split(','), 'Cannot find sObject field for GS Quality',
'Cannot find fields: ' + qualityField + ', ' + customerField + ', ' + revenueField);
}
}
}
} catch (Exception ex) {
System.debug('Error : ' + ex);
if (!Test.isRunningTest()) {
BatchDefaultSettings__c settings = BatchDefaultSettings__c.getOrgDefaults();
EmailHelper.sendEmailFromException(settings.Error_Emails__c.split(','), 'GS Quality calculation error', 'GS Quality calculation error', ex);
}
}

if (this.businessUnits.size() > 0) {
GSOverallCalculationBatch overallBatch = new GSOverallCalculationBatch(this.businessUnits, this.contractStats, this.currentDate, this.gsTotalOverall,
this.gsTotalSatisfaction, this.gsTotalBudget);
Database.executeBatch(overallBatch);
} else {
if (this.gsTotalBudget != 0) {
this.gsTotalSatisfaction = 100 * (this.gsTotalSatisfaction / this.gsTotalBudget);
this.gsTotalOverall = 100 * (this.gsTotalOverall / this.gsTotalBudget);
} else {
this.gsTotalSatisfaction = 0;
this.gsTotalOverall = 0;
}
this.contractStats.PRO_Cycle_Date__c = this.cycleStartDate;
this.contractStats.GS_Quality_Total_Overall_Status__c = this.gsTotalOverall;
this.contractStats.GS_Quality_Total_Customer_Satisfaction__c = this.gsTotalSatisfaction;
insert this.contractStats;

Contract_Statistic__c contractStats = (Contract_Statistic__c) sobj;
contractStats.GS_Quality_Total_Overall_Status__c = this.gsTotalOverall;
contractStats.GS_Quality_Total_Customer_Satisfaction__c = this.gsTotalSatisfaction;
insert contractStats;

} catch (Exception ex) {
System.debug('Error : ' + ex);
if (!Test.isRunningTest()) {
BatchDefaultSettings__c settings = BatchDefaultSettings__c.getOrgDefaults();
EmailHelper.sendEmailFromException(settings.Error_Emails__c.split(','), 'GS Quality calculation error', 'GS Quality calculation error', ex);
}
}
}

public void finish(Database.BatchableContext BC) {
}

private Boolean hasSObjectField(String fieldName, SObject so) {
return so.getSobjectType().getDescribe().fields.getMap().keySet().contains(fieldName);
}
Expand Down
3 changes: 2 additions & 1 deletion src/classes/GSOverallCalculationScheduler.cls
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
public without sharing class GSOverallCalculationScheduler implements Schedulable {

public void execute(SchedulableContext sc) {
Database.executeBatch(new ForPeriodCalcSnapshotBatch(false));
Date currentDate = Date.today();
List<Date> thursDayList = PROHelper.GetAllThursDayOfMonth(currentDate.year(), currentDate.month());
List<Date> thursDayListLastMonth = PROHelper.GetAllThursDayOfMonth(currentDate.addMonths(-1).year(), currentDate.addMonths(-1).month());
Expand All @@ -19,7 +20,7 @@ public without sharing class GSOverallCalculationScheduler implements Schedulabl
}

if (currentDate == endDate.addDays(-1)) {
GSOverallCalculationBatch overallBatch = new GSOverallCalculationBatch([SELECT Id, Name FROM Business_Unit__c]);
GSOverallCalculationBatch overallBatch = new GSOverallCalculationBatch();
Database.executeBatch(overallBatch);
}
}
Expand Down
Loading

0 comments on commit 9b50b39

Please sign in to comment.