TestDataFactory
/**
* @name TestDataFactory
* @description Contains methods to construct and/or validate commonly used records
**/
public with sharing class TestDataFactory {
public static List<Product2> prods;
public static List<PricebookEntry> entries;
public static List<Order> orders;
public static List<OrderItem> orderItems;
/**
* @name ConstructCollaborationGroup
* @description
**/
public static CollaborationGroup ConstructCollaborationGroup(){
//ToDo: Ensure this method returns a single Chatter CollaborationGroup
// whose Name starts with 'TEST' followed by the INVENTORY_ANNOUNCEMENTS constant
// and configured so anyone can join, see and post updates.
CollaborationGroup ChatterGroup = new CollaborationGroup(
Name = 'TEST'+Constants.INVENTORY_ANNOUNCEMENTS,
CollaborationType = 'Public',
IsArchived = false,
IsAutoArchiveDisabled = true
);
return ChatterGroup;
}
/**
* @name CreateProducts
* @description Constructs a list of Product2 records for unit tests
**/
public static list<Product2> ConstructProducts(Integer cnt){
//ToDo: Ensure this method returns a list, of size cnt, of uniquely named Product2 records
// with all the required fields populated
// and IsActive = true
// an Initial Inventory set to 10
// and iterating through the product family picklist values throughout the list.
list<Product2> products=new list<Product2>();
list<Schema.PicklistEntry> pEntries = Constants.PRODUCT_FAMILY;
Integer pVal = 0;
for(Integer i=0;i<cnt;i++){
Product2 pd2=new Product2();
pd2.Name='Product-'+i;
pd2.IsActive = true;
pd2.Initial_Inventory__c = 10;
if(pVal == 4){
pVal = 0;
}
pd2.Family = pEntries.get(pVal).getValue();
pVal++;
products.add(pd2);
}
return products;
}
/**
* @name CreatePricebookEntries
* @description Constructs a list of PricebookEntry records for unit tests
**/
public static list<PriceBookEntry> ConstructPricebookEntries(List<Product2> prods){
//ToDo: Ensure this method returns a corresponding list of PricebookEntries records
// related to the provided Products
// with all the required fields populated
// and IsActive = true
// and belonging to the standard Pricebook
list<PriceBookEntry> entries=new list<PriceBookEntry>();
for(Product2 pd2: prods){
PriceBookEntry pbe=new PriceBookEntry();
pbe.isActive = true;
pbe.UnitPrice = 100;
pbe.Product2Id = pd2.id;
pbe.PriceBook2Id = Constants.STANDARD_PRICEBOOK_ID;
entries.add(pbe);
}
return entries;
}
/**
* @name CreateAccounts
* @description Constructs a list of Account records for unit tests
**/
public static list<Account> ConstructAccounts(Integer cnt){
//ToDo: Ensure this method returns a list of size cnt of uniquely named Account records
// with all of the required fields populated.
list<Account> accounts=new list<Account>();
for(Integer i=0;i<cnt;i++){
Account ac=new Account();
ac.Name = 'Account'+i;
accounts.add(ac);
}
return accounts;
}
/**
* @name CreateContacts
* @description Constructs a list of Contacxt records for unit tests
**/
public static list<Contact> ConstructContacts(Integer cnt, List<Account> accts){
//ToDo: Ensure this method returns a list, of size cnt, of uniquely named Contact records
// related to the provided Accounts
// with all of the required fields populated.
list<Contact> conts=new list<Contact>();
for(Integer i=0;i<cnt;i++){
contact con=new contact();
con.LastName = 'Contact'+i;
con.AccountId = accts.get(i).id;
conts.add(con);
}
return conts;
}
/**
* @name CreateOrders
* @description Constructs a list of Order records for unit tests
**/
public static list<Order> ConstructOrders(Integer cnt, List<Account> accts){
//ToDo: Ensure this method returns a list of size cnt of uniquely named Order records
// related to the provided Accounts
// with all of the required fields populated.
list<Order> orders=new list<Order>();
for(Integer i=0;i<cnt;i++){
Order ord=new Order();
ord.Name = 'Order'+i;
ord.AccountId = accts.get(i).Id;
ord.EffectiveDate = Date.Today();
ord.Status = Constants.DRAFT_ORDER_STATUS;
ord.Pricebook2Id = Constants.STANDARD_PRICEBOOK_ID;
orders.add(ord);
}
return orders;
}
/**
* @name CreateOrderItems
* @description Constructs a list of OrderItem records for unit tests
**/
public static list<OrderItem> ConstructOrderItems(integer cnt, list<pricebookentry> pbes, list<order> ords){
//ToDo: Ensure this method returns a list of size cnt of OrderItem records
// related to the provided Pricebook Entries
// and related to the provided Orders
// with all of the required fields populated.
// Hint: Use the DEFAULT_ROWS constant for Quantity as it will be used in the next challenge
list<OrderItem> orderItems=new list<OrderItem>();
for(Integer i=0;i<cnt;i++){
OrderItem oItem=new OrderItem();
oItem.OrderId = ords.get(i).Id;
oItem.PriceBookEntryId = pbes.get(i).Id;
oItem.Quantity = Constants.DEFAULT_ROWS;
oItem.UnitPrice = (Decimal)10;
orderItems.add(oItem);
}
return orderItems;
}
public static void VerifyQuantityOrdered(Product2 originalProduct, Product2 updatedProduct, Integer qtyOrdered){
//updatedProduct.Quantity_Ordered__c ==originalProduct.Quantity_Ordered__c +qtyOrdered;
system.AssertEquals(updatedProduct.Quantity_Ordered__c,originalProduct.Quantity_Ordered__c +qtyOrdered);
}
/**
* @name SetupTestData
* @description Inserts accounts, contacts, Products, PricebookEntries, Orders, and OrderItems.
**/
public static void InsertTestData(Integer cnt){
//ToDo: Ensure this method calls each of the construct methods
// and inserts the results for use as test data.
list<Account> accounts = ConstructAccounts(cnt);
Insert accounts;
list<Contact> contacts = ConstructContacts(cnt, accounts);
insert contacts;
prods= ConstructProducts(cnt);
insert prods;
entries = ConstructPricebookEntries(prods);
insert entries;
orders = ConstructOrders(cnt, accounts);
insert orders;
orderItems = ConstructOrderItems(cnt, entries, orders);
insert orderItems;
}
}
OrderHelper
public without sharing class OrderHelper {
public static void AfterUpdate(List<Order> newList, List<Order> oldList){
Set<Id> orderIds = new Set<Id>();
for ( Integer i=0; i< newList.size(); i++ ){
if ( newList[i].Status == Constants.ACTIVATED_ORDER_STATUS && oldList[i].Status == Constants.DRAFT_ORDER_STATUS ){
orderIds.add(newList[i].Id);
}
}
RollUpOrderItems(orderIds);
}
public static void RollUpOrderItems(Set<Id> activatedOrderIds){
Map<Id, Product2> productMap = new Map<Id, Product2>();
for(OrderItem orderLine : [SELECT Id, Product2Id, Product2.Quantity_Ordered__c, Quantity, Order.ActivatedDate
FROM OrderItem WHERE OrderId IN : activatedOrderIds]){
if(!productMap.containsKey(orderLine.Product2Id))
productMap.put(orderLine.Product2Id, new Product2(Id =orderLine.Product2Id, Quantity_Ordered__c=0));
}
for(AggregateResult ag : [SELECT Sum(Quantity), Product2Id FROM OrderItem WHERE Product2Id IN : productMap.keySet() Group By Product2Id]){
Id product2Id = (Id)ag.get('Product2Id');
Product2 prod = productMap.get(product2Id);
prod.Quantity_Ordered__c = (Decimal)ag.get('expr0');
productMap.put(product2Id , prod);
}
try {
if(productMap.values() != null && productMap.values().size() > 0){
update productMap.values();
}
}catch ( Exception e ){
System.debug('#### Exception Executed : '+e.getStackTraceString());
}
}
}
OrderExtension
/**
* @name OrderExtension
* @description This class is provided for you to facilitate the Super Badge
**/
public class OrderExtension {
public Order orderRecord {get;set;}
public List<OrderItem> orderItemList {get;set;}
public String selectedFamily {get;set;}
public List<chartHelper.chartData> pieData {get;set;}
public Decimal total {get;set;}
public Map<Id,OrderItem> orderItemMap;
ApexPages.StandardSetController standardSetController;
public OrderExtension(ApexPages.StandardController standardController){
orderRecord = (Order)standardController.getRecord();
orderItemMap = new Map<id,OrderItem>();
if ( orderRecord.Id != null ){
orderRecord = queryOrderRecord(orderRecord.Id);
}
resetSsc();
total = 0;
for (OrderItem oi : orderRecord.OrderItems) {
orderItemMap.put(oi.Product2Id, oi);
if (oi.Quantity > 0) {
if (null == pieData) {
pieData = new List<ChartHelper.ChartData>();
}
pieData.add(new chartHelper.ChartData(oi.Product2.Name, oi.Quantity * oi.UnitPrice));
total += oi.UnitPrice * oi.Quantity;
}
}
PopulateOrderItems();
}
void resetSsc() {
String query = 'SELECT Name, Product2.Family, Product2.Name, Product2Id, UnitPrice, Product2.Quantity_Remaining__c'
+ ' FROM PricebookEntry WHERE IsActive = TRUE';
if (selectedFamily != null && selectedFamily != Constants.SELECT_ONE) {
query += ' AND Product2.Family = \'' + selectedFamily + '\'';
}
query += ' ORDER BY Name';
standardSetController = new ApexPages.StandardSetController(Database.getQueryLocator(query));
standardSetController.setPageSize(Constants.DEFAULT_ROWS);
}
//ToDo: Implement your own method to populate orderItemList
// that you will call after pagination and/or family selection
void PopulateOrderItems() {
orderItemList = new List<OrderItem>();
for (SObject obj : standardSetController.getRecords()) {
PricebookEntry pbe = (PricebookEntry)obj;
if (orderItemMap.containsKey(pbe.Product2Id)) {
orderItemList.add(orderItemMap.get(pbe.Product2Id));
} else {
orderItemList.add(new OrderItem(
PricebookEntryId=pbe.Id,
Product2Id=pbe.Product2Id,
UnitPrice=pbe.UnitPrice,
Quantity=0,
Product2=pbe.Product2
));
}
}
}
/**
* @name OnFieldChange
* @description
**/
public void OnFieldChange(){
//ToDo: Implement logic to store the values changed on the page
for (OrderItem oi : orderItemList) {
orderItemMap.put(oi.Product2Id, oi);
}
// and populate pieData
pieData = null;
total = 0;
for (OrderItem oi : orderItemMap.values()) {
if (oi.Quantity > 0) {
if (null == pieData) {
pieData = new List<chartHelper.ChartData>();
}
pieData.add(new chartHelper.ChartData(oi.Product2.Name, oi.Quantity * oi.UnitPrice));
// and populate total
total += oi.UnitPrice * oi.Quantity;
}
}
}
/**
* @name SelectFamily
* @description
**/
public void SelectFamily(){
//ToDo: Implement logic to filter based on the selected product family
resetSsc();
PopulateOrderItems();
}
/**
* @name Save
* @description
**/
public void Save(){
//ToDo: Implement logic to save the Order and populated OrderItems
System.Savepoint sp = Database.setSavepoint();
try {
if (null == orderRecord.Pricebook2Id) {
orderRecord.Pricebook2Id = Constants.STANDARD_PRICEBOOK_ID;
}
upsert orderRecord;
List<OrderItem> orderItemsToUpsert = new List<OrderItem>();
List<OrderItem> orderItemsToDelete = new List<OrderItem>();
for (OrderItem oi : orderItemList) {
if (oi.Quantity > 0) {
if (null == oi.OrderId) {
oi.OrderId = orderRecord.Id;
}
orderItemsToUpsert.add(oi);
} else if (oi.Id != null) {
orderItemsToDelete.add(oi);
}
}
upsert orderItemsToUpsert;
delete orderItemsToDelete;
} catch (Exception e) {
Database.rollback(sp);
apexPages.addMessage(new ApexPages.message(ApexPages.Severity.INFO,Constants.ERROR_MESSAGE));
}
}
/**
* @name First
* @description
**/
public void First(){
standardSetController.first();
PopulateOrderItems();
}
/**
* @name Next
* @description
**/
public void Next(){
standardSetController.next();
PopulateOrderItems();
}
/**
* @name Previous
* @description
**/
public void Previous(){
standardSetController.previous();
PopulateOrderItems();
}
/**
* @name Last
* @description
**/
public void Last(){
standardSetController.last();
PopulateOrderItems();
}
/**
* @name GetHasPrevious
* @description
**/
public Boolean GetHasPrevious(){
return standardSetController.getHasPrevious();
}
/**
* @name GetHasNext
* @description
**/
public Boolean GetHasNext(){
return standardSetController.getHasNext();
}
/**
* @name GetTotalPages
* @description
**/
public Integer GetTotalPages(){
return (Integer)Math.ceil(standardSetController.getResultSize() / (Decimal)Constants.DEFAULT_ROWS);
}
/**
* @name GetPageNumber
* @description
**/
public Integer GetPageNumber(){
return standardSetController.getPageNumber();
}
/**
* @name GetFamilyOptions
* @description
**/
public List<SelectOption> GetFamilyOptions() {
List<SelectOption> options = new List<SelectOption>{
new SelectOption(Constants.SELECT_ONE, Constants.SELECT_ONE)
};
for (Schema.PicklistEntry ple : Constants.PRODUCT_FAMILY) {
options.add(new SelectOption(ple.getValue(), ple.getLabel()));
}
return options;
}
/**
* @name QueryOrderRecord
* @description
**/
public static Order QueryOrderRecord(Id orderId){
return [
SELECT Id, AccountId, EffectiveDate, Name, Status, Pricebook2Id,
(
SELECT Id, OrderId, Quantity, UnitPrice, PricebookEntryId, Product2Id,
Product2.Name, Product2.Family, Product2.Quantity_Remaining__c
FROM OrderItems
)
FROM Order
WHERE Id = :orderId
];
}
}
Happy Coding !!!