Starbucks Codebatch

You might also like

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 3

/*

*
* JIRA: LSB2BTECH-2268
* Author: Lipton Abillar (Simplus)
* Date: July 2023
* Description: Batch class for updating the Licensee Account records
Self_Report_Self_Invoice__c field
*
*/

public class LicenseeSelfInvoiceBatch implements Database.Batchable<sObject> {


// Query Logic:
// All 'Licensee' record type Accounts, sorted by CreatedDate
// Fields: Id, Active_Alternates__c, Self_Report_Self_Invoice__c
// Subquery: All related Store records with Status__c = Open to the Public
private final String queryString = 'SELECT Id, Active_Alternates__c,
Self_Report_Self_Invoice__c, Royalty_Start__c, Royalty_End__c,
Automatic_Royalty_Opt_Out__c, (SELECT Id, Open_Date__c FROM LicensedStores__r WHERE
Status__c = \'Open to the Public\') FROM Account WHERE RecordType.DeveloperName
= \'Licensee\' ORDER BY CreatedDate ASC';

private Date royaltyStart;

public LicenseeSelfInvoiceBatch() {
Date today = Date.today();
royaltyStart = today.day() == 1 ? today :
today.addMonths(1).toStartOfMonth();
}

// Filter Stores
// 1. Stores that are Live in Connect
// 2. Stores that opened recently but still in Build
private Map<Id, String> getStoreConnectMap (Set<Id> storeIds, Integer
daysAfterStoreOpening) {
Map<Id, String> result = new Map<Id, String>();

if (storeIds.isEmpty()) {
return result;
}

for (Store__c store : [SELECT Id, Open_Date__c, (SELECT Id,


Connect_Stage__c FROM Connect__r WHERE Connect_Stage__c = '4. Live' OR
Connect_Stage__c = '3. Build' ORDER BY Connect_Stage__c DESC) FROM Store__c]) {
if (!store.Connect__r.isEmpty()) {
if (store.Connect__r[0].Connect_Stage__c == '4. Live') {
result.put(store.Id, 'Live');
} else if (!validateOpenDate(store.Open_Date__c,
daysAfterStoreOpening)) {
result.put(store.Id, 'Build');
}
}
}

return result;
}

public Boolean validateOpenDate(Date open_date, Integer addDays) {


Date endDate = open_date?.addDays(addDays);
return Date.today() > endDate;
}

public Database.Querylocator start(Database.BatchableContext bc){


return Database.getQuerylocator(queryString);
}

// The batch job executes and operates on one batch of records


public void execute(Database.BatchableContext bc, List<Account> scope){
List<Account> licenseeSelfInvoiceFalse = new List<Account>();
List<Account> licenseeSelfInvoiceTrue = new List<Account>();
Set<Id> storeIds = new Set<Id>();

Connect_Accounting_Setting__mdt settings = [SELECT


Days_after_Store_Opening__c FROM Connect_Accounting_Setting__mdt WHERE
DeveloperName = 'Connect_Accounting_Setting' LIMIT 1];
Integer daysAfterStoreOpening =
settings.Days_after_Store_Opening__c.intValue();

// Need to get the related Store -> Connect records


for (Account acc : scope) {
for (Store__c store : acc.LicensedStores__r) {
storeIds.add(store.Id);
}
}
Map<Id, String> validStores = getStoreConnectMap(storeIds,
daysAfterStoreOpening);

for (Account acc : scope) {


// All criteria must be met:
// 1. Check if Licensee has at least 1 related Store record with
Status__c = Open to the Public
// 2. All related Stores (Status__c = Open to the Public) should have
at least one Connect with Connect_Stage__c = '4. Live'
// 3. Licensee account should have Active_Alternates__c == 0
// 4. (new) Licensee not opt out of Royalty

Boolean isValid = false;


Boolean isLive = true;
// Checks if atleast 1 store has no live on Connect
if (!acc.LicensedStores__r.isEmpty()) {
for (Store__c store : acc.LicensedStores__r) {
if (!validStores.containsKey(store.Id)) continue; // Skip
stores that are not in the filtered Store Map
isValid = true;

if (validStores.get(store.Id) == 'Build') {
isLive = false;
}
}
}

if (isValid && acc.Active_Alternates__c == 0 && !


acc.Automatic_Royalty_Opt_Out__c) {
// Only add to the list if Self_Report_Self_Invoice__c is not False
to avoid unnecessary updates
if (isLive) {
if (acc.Self_Report_Self_Invoice__c) {
acc.Self_Report_Self_Invoice__c = false;
licenseeSelfInvoiceFalse.add(acc);
} else if (acc.Royalty_Start__c == null && acc.Royalty_End__c
== null) { // this logic is for new Licensee records that are already in Royalty
acc.Royalty_Start__c = royaltyStart; // If today's date is
the 1st day of the Month, use the today's date, otherwise, use the first day of the
next month
acc.Royalty_End__c = Date.newInstance(2999, 12, 31); //
2999-12-31
licenseeSelfInvoiceFalse.add(acc);
}
}
} else if (!acc.Self_Report_Self_Invoice__c){ // Check if
Self_Report_Self_Invoice__c is False before adding to the list to avoid unnecessary
updates
acc.Self_Report_Self_Invoice__c = true;
licenseeSelfInvoiceTrue.add(acc);
}
}

// Check if at least one of the Lists is not empty


// Combine both lists to avoid multiple DMLs
if (!licenseeSelfInvoiceFalse.isEmpty() || !
licenseeSelfInvoiceTrue.isEmpty()) {
licenseeSelfInvoiceFalse.addAll(licenseeSelfInvoiceTrue);
update licenseeSelfInvoiceFalse;
}
}

// The batch job finishes


public void finish(Database.BatchableContext bc){

}
}

You might also like