Challenge Overview
Project Overview
Our partner is developing a state-of-the-art tablet based sales and order processing tool. Their sales team will be managing client visits, tasks, calendars, notifications, and order processing all through this tool. The platform is the Apple iPad. Want to learn Swift? Great - why not get paid for it, we need your help! There will be a long series of challenges over the coming weeks leading to the final product, so get involved now!
Challenge Summary
The purpose of this challenge is to extend our existing Swift application to make use of the UI prototypes that were built in the previous challenges. These are wide reaching changes to the app, updating links and picklists throughout the application.
Detail
Update Account Info and Create Account Forms With New Metadata Fields
The /Global/Metadata service has been updated with new fields that have picklists in Salesforce. Modify the following fields in the Account Info and Create Account forms such that they feature the following fields as picklists, with values taken from the stored Metadata keys:
-
"Account.Competitor_1__c"
-
Incumbent Rental 1
-
-
"Account.Competitor_2__c"
-
Incumbent Rental 2
-
-
"Account.Incumbent_DP__c"
-
Incumbent DP
-
-
"Account.Program_Type_1__c"
-
Program Type
-
-
"Account.Sales_Stage__c"
-
Sales Stage
-
Only on Create Account
-
-
"Account.Status__c"
-
Status
-
Only on Create Account
-
Additionally for the Country Field, change that to a picklist with values “US” and “Canada”. If the user selects “US” provide the current list of US States in the State picklist. If the user selects “Canada” populate that picklist with Canadian Provinces. Do this on both Create Account and Edit Account Info.
On the Create New Account screen remove the Other Picklist, and the Other Incumbent Name fields. Slide the other fields up to fill the now empty space.
Update Opportunity Create and Edit Forms on the Account Screen With New Metadata Fields
As above, new fields have been specified for Opportunity. Ensure that the edit and create forms for Opportunities feature the following fields:
-
"Opportunity.Close_Reason__c"
-
Close Reason
-
-
"Opportunity.Competitors__c"
-
Competitor(s)
-
-
"Opportunity.Primary_Customer_Promise__c"
-
Primary Customer Promise Factor
-
-
"Opportunity.Type"
-
Type
-
-
"Opportunity.Who_Won__c"
-
Who Won?
-
Also, change Probability to a Picklist with the following possible values:
-
25
-
50
-
75
-
90
-
100
Update Picklists on Meeting and To-Do Forms (Create and Edit)
No fields here are to be populated by metadata from the server. On the Meeting forms, edit the following fields to only show the following values:
-
Priority
-
High
-
Medium
-
Low
-
-
Show Time As
-
Busy
-
Out of Office
-
Available
-
-
Status
-
Cancelled
-
Not Started
-
Done
-
-
Subject
-
Discovery Meeting
-
Presentation Meeting
-
Closing/Negotiations Meeting
-
Sizing Meeting
-
Pre-Install Meeting
-
Update the following on the To-Do Forms
-
Priority
-
High
-
Medium
-
Low
-
-
Status
-
Cancelled
-
Not Started
-
Done
-
-
Subject
-
Call Back - Phone
-
Call Back - TCC
-
Email Follow-Up
-
Drop Information
-
Provide Sample
-
Discovery Prep
-
Email Recap
-
Set RSR Visit
-
Prepare Samples
-
Credit Application
-
Submit Emblem
-
Soil Evaluation
-
Contact Segment Expert
-
Additional Discovery Prep
-
Create Pricing-PMod / Presentation
-
Update Pricing-PMod / Presentation
-
Invite GK Attendees
-
Update Account Next Steps Modal Picklists to Use Values from Metadata Service
Entirely new with this API update, the /Global/Metadata content now supports some custom picklist values for the Account Next Steps modal screen. With those you’ll use a different list depending on the phase the account is in. The format for the keys of these is {AccordionPanel}.{Account.OpportunityStage}[.Event/Task]. Be sure that if the phase of these accounts change properly.
-
What Did You Do? Picklist
-
WDYD.Approach
-
WDYD.Discovery
-
WDYD.Install
-
WDYD.Present
-
-
What’s Next - Meeting Subject Picklist
-
WN.Approach.Event
-
WN.Discovery.Event
-
WN.Install.Event
-
WN.Present.Event
-
-
What’s Next - To-Do Subject Picklist
-
WN.Approach.Task
-
WN.Discovery.Task
-
WN.Install.Task
-
WN.Present.Task
-
-
No Path Forward Picklist
-
NPF.Approach
-
NPF.Discovery
-
NPF.Install
-
NPF.Present
-
In addition to enabling the picklists for these fields, you will need to remove the Type field on both the Meeting and To-Dos forms.
Retrieve Dynamic Links from /Global/StaticContent
You’ll want to modify the saveStaticValues function of CompassNotificationManager.swift to save all of the different values returned in the newly modified service. The details in this section should help you understand how to use the JSON returned:
-
Label
-
Text Field
-
The text that will display for this link option.
-
-
URL
-
Text Field
-
This text will be used for navigation. If this is a Content Item, this should just be the ID of that ContentDocument Item. If this is a Salesforce Link, it should be the relative path in Salesforce that will be navigated to from the Front Door URL. Otherwise, put a full URL to the item. i.e. http://www.google.com
-
-
Tag
-
Text Field
-
This text represents the tags used in our Guided Enablement content search. The latest Items with this tag will be returned to show in a quick menu. If this field is defined, the URL field will be ignored, and the configuration will be interpreted to be a Collateral Section. Should display like the example in Sales Tools on the current Seller Home Page
-
Item 1
-
Item 2
-
Item 3
-
Show All
-
-
When “Show All” is clicked, direct the user to Global Search with the Category pre-set as Content, and subCategory set to the Tag field.
-
-
items
-
This is an array of Content items of this tag.
-
ID - the Salesforce Content ID for downloading and presenting, as how Core Values workes now.
-
Title - The text that should display in the Popover
-
-
If this array is empty, don’t display a popover and instead direct the user to the Global Search with the Category pre-set as Content and subCategory set to the Tag field.
-
-
isContentDocument
-
Indicates that the supplied URL is for a ContentDocument object in Salesforce Content.
-
-
isSalesforcePath
-
Indicates that the supplied URL is a Salesforce path that requires the user's active authentication with the frondoor protocol.
-
-
isSellerVisible
-
Indicates whether this URL should be rendered for Sellers or just Sales Managers.
-
If the item is “isSalesforce” use the URL with the Frontdoor protocol to open a webview pointed at that Salesforce URL.
If the item is “isContent” the item should be downloaded like Core Values currently does and presented in the same manner.
Example JSON:
{
"salesTools": [
{
"url": null,
"tag": "GKDirect",
"name": "gkDirectSystems",
"label": "GK Direct Systems",
"items": [{"title" : "Content Title",
"id" : "069R00000009nNwIAI" }],
"isSellerVisible": null,
"isSalesforce": null,
"isContent": null
},
{
"url": null,
"tag": "CompetitiveCollateral",
"name": "competitiveCollateral",
"label": "Competitive Collateral",
"items": [],
"isSellerVisible": null,
"isSalesforce": null,
"isContent": null
},
{
"url": null,
"tag": "ProductCollateral",
"name": "productsCollateral",
"label": "Products Collateral",
"items": [],
"isSellerVisible": null,
"isSalesforce": null,
"isContent": null
},
{
"url": null,
"tag": "SegmentsCollateral",
"name": "segmentsCollateral",
"label": "Segments Collateral",
"items": [],
"isSellerVisible": null,
"isSalesforce": null,
"isContent": null
},
{
"url": null,
"tag": "Form",
"name": "forms",
"label": "Forms",
"items": [],
"isSellerVisible": null,
"isSalesforce": null,
"isContent": null
},
{
"url": null,
"tag": "ServiceAgreements",
"name": "serviceAgreements",
"label": "Service Agreements",
"items": [],
"isSellerVisible": null,
"isSalesforce": null,
"isContent": null
},
{
"url": null,
"tag": "Videos",
"name": "videos",
"label": "Videos",
"items": [],
"isSellerVisible": null,
"isSalesforce": null,
"isContent": null
},
{
"url": null,
"tag": "GKRental",
"name": "gkRentalSystems",
"label": "GKrental",
"items": [],
"isSellerVisible": null,
"isSalesforce": null,
"isContent": null
}
],
"reports": [
{
"url": "home/home.jsp",
"tag": null,
"name": "headCountReport",
"label": "Head Count Report",
"items": [],
"isSellerVisible": true,
"isSalesforce": true,
"isContent": false
},
{
"url": "/00O/o",
"tag": null,
"name": "createAdhocReport",
"label": "Create Ad-hoc Report",
"items": [],
"isSellerVisible": true,
"isSalesforce": true,
"isContent": false
},
{
"url": "/home/home.jsp",
"tag": null,
"name": "soeReports",
"label": "SOE Reports",
"items": [],
"isSellerVisible": true,
"isSalesforce": true,
"isContent": false
},
{
"url": "home/home.jsp",
"tag": null,
"name": "directPurchaseReports",
"label": "Direct Purchase Reports",
"items": [],
"isSellerVisible": true,
"isSalesforce": true,
"isContent": false
},
{
"url": "home/home.jsp",
"tag": null,
"name": "proSalesReport",
"label": "Pro-Sales Report",
"items": [],
"isSellerVisible": true,
"isSalesforce": true,
"isContent": false
},
{
"url": "home/home.jsp",
"tag": null,
"name": "turnoverReport",
"label": "Turnover Report",
"items": [],
"isSellerVisible": true,
"isSalesforce": true,
"isContent": false
},
{
"url": "http://drive.google.com",
"tag": null,
"name": "bridgePaymentReport",
"label": "Bridge Payment Report",
"items": [],
"isSellerVisible": true,
"isSalesforce": true,
"isContent": false
},
{
"url": "http://drive.google.com",
"tag": null,
"name": "salesCorrectionLog",
"label": "Sales Correction Log",
"items": [],
"isSellerVisible": true,
"isSalesforce": false,
"isContent": false
},
{
"url": "home/home.jsp",
"tag": null,
"name": "payReports",
"label": "Pay Reports",
"items": [],
"isSellerVisible": true,
"isSalesforce": true,
"isContent": false
},
{
"url": "home/home.jsp",
"tag": null,
"name": "Salesforce.com Reports",
"label": "Salesforce.com Reports",
"items": [],
"isSellerVisible": true,
"isSalesforce": true,
"isContent": false
},
{
"url": "http://drive.google.com",
"tag": null,
"name": "CORReport",
"label": "COR Report",
"items": [],
"isSellerVisible": true,
"isSalesforce": false,
"isContent": false
}
],
"other": [
{
"url": "069R0000000NeiOIAS",
"tag": null,
"name": "customerPromise",
"label": "Our Promise",
"items": [],
"isSellerVisible": true,
"isSalesforce": false,
"isContent": true
},
{
"url": "069R0000000NeiIIAS",
"tag": null,
"name": "coreValues",
"label": "Core Values",
"items": [],
"isSellerVisible": true,
"isSalesforce": false,
"isContent": true
}
],
"mgmtTools": [
{
"url": null,
"tag": "OnBoarding",
"name": "onBoarding",
"label": "On Boarding",
"items": [],
"isSellerVisible": null,
"isSalesforce": null,
"isContent": null
},
{
"url": "/00O/o",
"tag": null,
"name": "KPIDashboard",
"label": "KPI Dashboard",
"items": [],
"isSellerVisible": true,
"isSalesforce": true,
"isContent": false
},
{
"url": "/00O/o",
"tag": null,
"name": "nationalAccountDatabase",
"label": "Nat. Acct Database",
"items": [],
"isSellerVisible": true,
"isSalesforce": true,
"isContent": false
},
{
"url": null,
"tag": "TeamTraining",
"name": "teamTraining",
"label": "Team Training",
"items": [],
"isSellerVisible": null,
"isSalesforce": null,
"isContent": null
},
{
"url": null,
"tag": "Recruiting",
"name": "recruiting",
"label": "Recruiting",
"items": [],
"isSellerVisible": null,
"isSalesforce": null,
"isContent": null
}
],
"message": "SUCCESS",
"isSuccess": true,
"gk": [
{
"url": "http://gks098116.gkservices.com/psp/HRPROD/?cmd=login&errorPg=ckreq&languageCd=ENG",
"tag": null,
"name": "peopleSoft",
"label": "PeopleSoft",
"items": [],
"isSellerVisible": true,
"isSalesforce": false,
"isContent": false
},
{
"url": "http://www.example.com",
"tag": null,
"name": "itHelp",
"label": "IT Help",
"items": [],
"isSellerVisible": true,
"isSalesforce": false,
"isContent": false
},
{
"url": "www.runzheimer.com",
"tag": null,
"name": "mileage",
"label": "Mileage",
"items": [],
"isSellerVisible": true,
"isSalesforce": false,
"isContent": false
},
{
"url": "https://gkservices.service-now.com/ess/home.do",
"tag": null,
"name": "serviceNow",
"label": "Service Now",
"items": [],
"isSellerVisible": true,
"isSalesforce": false,
"isContent": false
},
{
"url": "http://www.gksystems.com",
"tag": null,
"name": "gkWebsite",
"label": "G&K Website",
"items": [],
"isSellerVisible": true,
"isSalesforce": false,
"isContent": false
},
{
"url": "http://www.example.com",
"tag": null,
"name": "hrInTouch",
"label": "HR In Touch",
"items": [],
"isSellerVisible": true,
"isSalesforce": false,
"isContent": false
}
],
"contests": [{
"url": "http://www.example.com",
"tag": null,
"name": "hrInTouch",
"label": "HR In Touch",
"items": [],
"isSellerVisible": true,
"isSalesforce": false,
"isContent": false
}]
}
Render the Dynamic Links
All objects under the “salesTools” array in the returned JSON should be rendered in the Sales Tools panel of the Seller Home Page. Replace all of the example values with the ones here. Not all items from the example will be returned. This is expected.
All objects under the “mgmtTools” array in the returned JSON should be rendered in the MGMT Tools panel of the Sales Manager Home Page. With the exemption of Coaching Tools, all example values should be replaced. Coaching Tools should remain as it is.
All objects under the “gk” array in the returned JSON should be rendered as subitems in the GK item in the Global Menu. All example values should be replaced with what is here, with the exception of Logout of Compass, which should remain as the last option.
All objects under the “reports” array in the returned JSON should be rendered in the “Analytics” section of the Sales Manager Home Page. All values here should be replaced with what is here.
If no objects are returned for “contests” do not show that menu item in the Global Menu. If one object is returned, navigate directly to that object. If multiple objects are returned, display a popover with all of those objects.
For the “other” array, these values will represent links that will not be a submenu, but instead their own free-standing button within the app. Currently this corresponds to Core Vaues and Customer Promise. Store these values and the IDs in such a way that the system can access the ID and download the content whenever Core Values and Our Promise are pressed. The names of these objects are coreValues and customerPromse respectively. Please modify the functions that call these values so that they are operating with the new data model.
General Guideline
- All usage of API results should be null-safe. When populating objects from the JSON results if fields are missing, ensure that all usages appropriately handle the optional values.
- For all service calls, if an error occurs dispatch a “ServiceErrorOccurred” event through NSNotificationCenter.defaultCenter() with relevant text about the error.
Environment Setup
GIT: The project will use a code repository at Github, please see additional details and participant responsibilities under Submission Guidelines.
Xcode: All code development should be done in Xcode 6.1.1 and tested in the simulator.
Framework: Code should be developed with the Cocoa Touch framework using Swift and must compile against iOS SDK 8.1 with a deployment target of iOS 7.0.
Get Started
- Request access to the project in the challenge forums
- Fork this project: git@github.com:cloudspokes/UNI-mobile.git
- Checkout this branch: https://github.com/cloudspokes/UNI-mobile/tree/workstream6-integration2
- Write and submit your code as a zip file
Use the following credentials to log into the Compass application:
Username: uni1@topcoder.com
Password: community123
** Note: You need to set the login location to "Sandbox" in the iPad (or simulator settings). This is under regular IOS settings (in the Compass app section).
Final Submission Guidelines
Submission Guidelines
Submission Guidelines
- Cocoa Touch framework Xcode 6.1.1 project with well commented code
- Code must compile against iOS SDK 8.1 with a deployment target of iOS 7.0
- Upload all source projects as a zip
- After submission phase has completed, make a pull request targeting this branch
- Provide documentation of any special configuration required to run your code.
GIT Guidelines and Requirements
All code for this project will be maintained at Github. Challenge participants will have to request read-only access to the repository during the challenge and are expected to fork and do their coding on the challenge branch. Once contest submission closes, the project owner will update the code in the challenge branch to reflect the current state of development. The winner of the challenge will then be required to update their fork to the current state of the development repository and will be responsible for handling merge conflicts when updating their fork. They will then create a pull request.