diff --git a/README.md b/README.md index d8b04eb0..c30cf912 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ Links: - [Power of Us Hub group](https://powerofus.force.com/s/group/0F980000000CvlMCAS/community-project-outbound-funds) - [Install Outbound Funds](https://install.salesforce.org/products/outbound-funds) +## Latest Release + +Summer '21 šŸŒž ā›µ šŸŒŠ + **Important note about Funding Requests as of July 2019**: If you were an early adopter of the Outbound Funds package, the Funding Request object had a master-detail relationship with Funding Program when you installed it. However, various members of the community requested that this relationship be changed to a lookup to provide more flexibility. This change was made generally available with package version 1.15 as of 7/11/2019. To learn about updating to version 1.15, see the [Funding Request Object documentation](https://github.com/SalesforceFoundation/OutboundFundsModule/wiki/Funding-Request-Object). diff --git a/cumulusci.yml b/cumulusci.yml index 544120d0..8c9f9609 100644 --- a/cumulusci.yml +++ b/cumulusci.yml @@ -27,6 +27,7 @@ tasks: objects: - Requirement__c - Disbursement__c + - Review__c - Funding_Request__c - Funding_Program__c - Contact diff --git a/datasets/mapping.yml b/datasets/mapping.yml index 79fd9f81..409d8ee7 100644 --- a/datasets/mapping.yml +++ b/datasets/mapping.yml @@ -1,33 +1,87 @@ -Accounts: +Account: sf_object: Account + table: Account fields: - Name + - AccountNumber + - Site + - Type + - Industry + - AnnualRevenue + - Rating + - Phone + - Fax + - Website + - Ownership + - Sic + - TickerSymbol + - BillingStreet + - BillingCity + - BillingState + - BillingPostalCode + - BillingCountry + - ShippingStreet + - ShippingCity + - ShippingState + - ShippingPostalCode + - ShippingCountry + - Description + anchor_date: "2020-07-01" -Contacts: +Contact: sf_object: Contact + table: Contact + anchor_date: "2020-07-01" fields: - Salutation - FirstName - LastName + - Title - Email + - Department + - Birthdate + - LeadSource - Phone - - Title + - HomePhone + - OtherPhone + - Fax + - AssistantName + - AssistantPhone + - MailingStreet + - MailingCity + - MailingState + - MailingPostalCode + - MailingCountry + - OtherStreet + - OtherCity + - OtherState + - OtherPostalCode + - OtherCountry + - Description lookups: AccountId: + key_field: account_id table: Account + ReportsToId: + key_field: reports_to_id + table: Contact + after: Contact Funding Programs: sf_object: Funding_Program__c + anchor_date: "2020-07-01" fields: - Name - Description__c - End_Date__c - Start_Date__c - Status__c + - Top_Level__c - Total_Program_Amount__c Funding Requests: sf_object: Funding_Request__c + anchor_date: "2020-07-01" fields: - Name - Application_Date__c @@ -52,8 +106,24 @@ Funding Requests: FundingProgram__c: table: Funding_Program__c +Funding_Request_Role__c: + sf_object: Funding_Request_Role__c + table: Funding_Request_Role__c + anchor_date: "2020-07-01" + fields: + - Role__c + - Status__c + lookups: + Contact__c: + key_field: Contact__c + table: Contact + Funding_Request__c: + key_field: Funding_request__c + table: Funding_Request__c + Disbursements: sf_object: Disbursement__c + anchor_date: "2020-07-01" fields: - Amount__c - Disbursement_Date__c @@ -67,6 +137,7 @@ Disbursements: Requirements: sf_object: Requirement__c + anchor_date: "2020-07-01" fields: - Name - Completed_Date__c @@ -81,3 +152,16 @@ Requirements: table: Funding_Request__c Primary_Contact__c: table: Contact + +Reviews: + sf_object: Review__c + anchor_date: "2021-04-30" + fields: + - Name + - Comments__c + - DueDate__c + - Status__c + - SubmittedDate__c + lookups: + FundingRequest__c: + table: Funding_Request__c diff --git a/datasets/sample.sql b/datasets/sample.sql index 17636967..12d05c1c 100644 --- a/datasets/sample.sql +++ b/datasets/sample.sql @@ -2,211 +2,200 @@ BEGIN TRANSACTION; CREATE TABLE "Account" ( id INTEGER NOT NULL, "Name" VARCHAR(255), + "AccountNumber" VARCHAR(255), + "Site" VARCHAR(255), + "Type" VARCHAR(255), + "Industry" VARCHAR(255), + "AnnualRevenue" VARCHAR(255), + "Rating" VARCHAR(255), + "Phone" VARCHAR(255), + "Fax" VARCHAR(255), + "Website" VARCHAR(255), + "Ownership" VARCHAR(255), + "Sic" VARCHAR(255), + "TickerSymbol" VARCHAR(255), + "BillingStreet" VARCHAR(255), + "BillingCity" VARCHAR(255), + "BillingState" VARCHAR(255), + "BillingPostalCode" VARCHAR(255), + "BillingCountry" VARCHAR(255), + "ShippingStreet" VARCHAR(255), + "ShippingCity" VARCHAR(255), + "ShippingState" VARCHAR(255), + "ShippingPostalCode" VARCHAR(255), + "ShippingCountry" VARCHAR(255), + "Description" VARCHAR(255), PRIMARY KEY (id) ); -INSERT INTO "Account" VALUES(1,'Nonprofit B'); -INSERT INTO "Account" VALUES(2,'salesforce.com'); -INSERT INTO "Account" VALUES(3,'Nonprofit A'); -INSERT INTO "Account" VALUES(4,'Nonprofit C'); -INSERT INTO "Account" VALUES(5,'Bob Test'); -INSERT INTO "Account" VALUES(6,'Ken Test'); -INSERT INTO "Account" VALUES(7,'Lisa Test'); -INSERT INTO "Account" VALUES(8,'Nancy Carlson'); -INSERT INTO "Account" VALUES(9,'Operation Change the World'); -INSERT INTO "Account" VALUES(10,'Shelbyville College'); -INSERT INTO "Account" VALUES(11,'Wig Household'); -INSERT INTO "Account" VALUES(12,'Simpson Household'); -INSERT INTO "Account" VALUES(13,'Moeā€™s Tavern'); -INSERT INTO "Account" VALUES(14,'Springfield heights institute of technology'); -INSERT INTO "Account" VALUES(15,'Burns Co'); -INSERT INTO "Account" VALUES(16,'Shelbyville Elementary School'); -INSERT INTO "Account" VALUES(17,'Simpson Household'); -INSERT INTO "Account" VALUES(18,'Reily Household'); -INSERT INTO "Account" VALUES(19,'Flanders Family Foundation'); -INSERT INTO "Account" VALUES(20,'Flanders Household'); -INSERT INTO "Account" VALUES(21,'Large Manufacturing Corporation'); -INSERT INTO "Account" VALUES(22,'Duff Brewery'); -INSERT INTO "Account" VALUES(23,'Springfield Police Academy'); -INSERT INTO "Account" VALUES(24,'Lindberg Household'); -INSERT INTO "Account" VALUES(25,'Corkill Household'); -INSERT INTO "Account" VALUES(26,'Amin Household'); -INSERT INTO "Account" VALUES(27,'Contact Household'); -INSERT INTO "Account" VALUES(28,'Sample Organization'); -INSERT INTO "Account" VALUES(29,'Springfield Elementary'); -INSERT INTO "Account" VALUES(30,'Wiggum Household'); -INSERT INTO "Account" VALUES(31,'Global Media'); -INSERT INTO "Account" VALUES(32,'Acme'); +INSERT INTO "Account" VALUES(1,'Sample Account for Entitlements','','','','','','','','','','','','','','','','','','','','','','',''); +INSERT INTO "Account" VALUES(2,'Grantwood City Council','','','Customer - Direct','Government','','','970-555-9633','','','','','','445 North Peak Road','Grantwood','Colorado','80522','United States','','','','','',''); +INSERT INTO "Account" VALUES(3,'Takagawa Institute','','','Customer - Direct','Not For Profit','','','602-555-3542','','','','','','9833 Plateau Street','Phoenix','Arizona','85310','United States','','','','','',''); +INSERT INTO "Account" VALUES(4,'Outbound Funds Portal: Self-Registered','','','','','','','','','','','','','','','','','','','','','','','Account initially assigned to self-registered users for the Outbound Funds Portal Experiences Site'); +INSERT INTO "Account" VALUES(5,'Hillside Elementary','','','Customer - Direct','Education','','','719-555-9914','','','','','','713 S. 8th Street','Englewood','Colorado','80110','United States','','','','','',''); +INSERT INTO "Account" VALUES(6,'STEPS','','','Customer - Direct','Not For Profit','','','303-555-7541','','','','','','2920 Juniper Drive','Denver','Colorado','80230','United States','','','','','',''); CREATE TABLE "Contact" ( - id INTEGER NOT NULL, - "Salutation" VARCHAR(255), - "FirstName" VARCHAR(255), - "LastName" VARCHAR(255), - "Email" VARCHAR(255), - "Phone" VARCHAR(255), - "Title" VARCHAR(255), - "AccountId" VARCHAR(255), + id INTEGER NOT NULL, + "Salutation" VARCHAR(255), + "FirstName" VARCHAR(255), + "LastName" VARCHAR(255), + "Title" VARCHAR(255), + "Email" VARCHAR(255), + "Department" VARCHAR(255), + "Birthdate" VARCHAR(255), + "LeadSource" VARCHAR(255), + "Phone" VARCHAR(255), + "HomePhone" VARCHAR(255), + "OtherPhone" VARCHAR(255), + "Fax" VARCHAR(255), + "AssistantName" VARCHAR(255), + "AssistantPhone" VARCHAR(255), + "MailingStreet" VARCHAR(255), + "MailingCity" VARCHAR(255), + "MailingState" VARCHAR(255), + "MailingPostalCode" VARCHAR(255), + "MailingCountry" VARCHAR(255), + "OtherStreet" VARCHAR(255), + "OtherCity" VARCHAR(255), + "OtherState" VARCHAR(255), + "OtherPostalCode" VARCHAR(255), + "OtherCountry" VARCHAR(255), + "Description" VARCHAR(255), + account_id VARCHAR(255), + reports_to_id VARCHAR(255), PRIMARY KEY (id) ); -INSERT INTO "Contact" VALUES(1,'','Shari','Reily','','','','18'); -INSERT INTO "Contact" VALUES(2,'Mr.','Marc','Benioff','info@salesforce.com','(415) 901-7000','Executive Officer','2'); -INSERT INTO "Contact" VALUES(3,'Mr.','Ned','Flanders','test@test.com','','','20'); -INSERT INTO "Contact" VALUES(4,'Mr.','Todd','Flanders','','','','20'); -INSERT INTO "Contact" VALUES(5,'Mr.','Rod','Flanders','','','','20'); -INSERT INTO "Contact" VALUES(6,'Mr.','Duff','Man','','','The King Of Beers','22'); -INSERT INTO "Contact" VALUES(7,'Mr.','Clarence','Wiggum','chief@spinfieldpd.fake','911','Police Chief','23'); -INSERT INTO "Contact" VALUES(8,'','Nick','Lindberg','','','','24'); -INSERT INTO "Contact" VALUES(9,'','Bill','Corkill','','','','25'); -INSERT INTO "Contact" VALUES(10,'Ms.','Sarah','Amin','','','','26'); -INSERT INTO "Contact" VALUES(11,'','Sample','Contact','sample.contact@email.com','(202) 555-9654','CEO','27'); -INSERT INTO "Contact" VALUES(12,'','Seymour','Skinner','','','','29'); -INSERT INTO "Contact" VALUES(13,'Mr.','Ralph','Wiggum','','','','30'); -INSERT INTO "Contact" VALUES(14,'','Geoff','Minor','info@salesforce.com','(415) 555-1212','President','31'); -INSERT INTO "Contact" VALUES(15,'','Carole','White','info@salesforce.com','(415) 555-1212','VP Sales','31'); -INSERT INTO "Contact" VALUES(16,'','Jon','Amos','info@salesforce.com','(905) 555-1212','Sales Manager','31'); -INSERT INTO "Contact" VALUES(17,'','Edward','Stamos','info@salesforce.com','(212) 555-5555','President and CEO','32'); -INSERT INTO "Contact" VALUES(18,'','Howard','Jones','info@salesforce.com','(212) 555-5555','Buyer','32'); -INSERT INTO "Contact" VALUES(19,'','Leanne','Tomlin','info@salesforce.com','(212) 555-5555','VP Customer Support','32'); -INSERT INTO "Contact" VALUES(20,'','Sally','Jones','','','','4'); -INSERT INTO "Contact" VALUES(21,'','Bob','Test','','','','5'); -INSERT INTO "Contact" VALUES(22,'','Ken','Test','','','','6'); -INSERT INTO "Contact" VALUES(23,'','Lisa','Test','shari_reily@redpathcg.com','','','7'); -INSERT INTO "Contact" VALUES(24,'','Nancy','Carlson','','','','8'); -INSERT INTO "Contact" VALUES(25,'','Sally','Walker','','','','9'); -INSERT INTO "Contact" VALUES(26,'','Erin','Test','shari_reily@redpathcg.com','','','1'); -INSERT INTO "Contact" VALUES(27,'','Homer','Simpson','','','','17'); -INSERT INTO "Contact" VALUES(28,'Mr.','Big','Wig','','','CEO','11'); -INSERT INTO "Contact" VALUES(29,'Mr.','Bart','Simpson','','','Child','12'); -INSERT INTO "Contact" VALUES(30,'Ms.','Lisa','Simpson','','','','12'); -INSERT INTO "Contact" VALUES(31,'Mrs.','Marge','Simpson','','','','12'); -INSERT INTO "Contact" VALUES(32,'Mr.','Moe','Szyslak','','','Owner','13'); -INSERT INTO "Contact" VALUES(33,'Prof.','John','Frink','','','Professor','14'); -INSERT INTO "Contact" VALUES(34,'Mr.','Montgomery','Burns','','','','15'); -INSERT INTO "Contact" VALUES(35,'','Carol','Shelby','','','','16'); +INSERT INTO "Contact" VALUES(1,'Mr.','Dillon','Whitaker','Assistant City Manager','dillon.whitaker@gwcity.example.com','','','','719-555-2417','','','','','','445 North Peak Road','Grantwood','Colorado','80522','United States','','','','','','','2',''); +INSERT INTO "Contact" VALUES(2,'Ms.','Adriana','Atterberry','Grants Manager','adriana.atterberry@takagawa-institute.example.com','','','','602-555-3543','','','','','','9834 Plateau Street','Phoenix','Arizona','85310','United States','','','','','','','3','3'); +INSERT INTO "Contact" VALUES(3,'Dr.','Meiko','Takagawa','Executive Director','meiko.takagawa@takagawa-institute.example.com','','','','602-555-3542','','','','','','9833 Plateau Street','Phoenix','Arizona','85310','United States','','','','','','','3',''); +INSERT INTO "Contact" VALUES(4,'Mr.','Devon','Berger','Literacy Coach','devon.berger@hillside-elementary.example.com','','','','719-555-9914','','','','','','713 S. 8th Street','Englewood','Colorado','80110','United States','','','','','','','5',''); +INSERT INTO "Contact" VALUES(5,'Ms.','Ellen','Perez','Program Coordinator','ellen.perez@steps.example.com','','','','303-555-7541','','','','','','2920 Juniper Drive','Denver','Colorado','80230','United States','','','','','','','6','6'); +INSERT INTO "Contact" VALUES(6,'Ms.','Grace','Walker','Development Director','grace.walker@steps.example.com','','','','303-555-7540','','','','','','2920 Juniper Drive','Denver','Colorado','80230','United States','','','','','','','6',''); +INSERT INTO "Contact" VALUES(7,'Mr.','Jermaine','Harmon','Intern','jermaine.harmon@steps.example.com','','','','303-555-7540','','','','','','2920 Juniper Drive','Denver','Colorado','80230','United States','','','','','','','6',''); CREATE TABLE "Disbursement__c" ( - id INTEGER NOT NULL, - "Amount__c" VARCHAR(255), - "Disbursement_Date__c" VARCHAR(255), - "Disbursement_Method__c" VARCHAR(255), - "Scheduled_Date__c" VARCHAR(255), - "Status__c" VARCHAR(255), - "Type__c" VARCHAR(255), - "Funding_Request__c" VARCHAR(255), + id INTEGER NOT NULL, + "Amount__c" VARCHAR(255), + "Disbursement_Date__c" VARCHAR(255), + "Disbursement_Method__c" VARCHAR(255), + "Scheduled_Date__c" VARCHAR(255), + "Status__c" VARCHAR(255), + "Type__c" VARCHAR(255), + Funding_Request__c VARCHAR(255), PRIMARY KEY (id) ); -INSERT INTO "Disbursement__c" VALUES(1,'124.0','2018-04-12','Cash','2018-04-11','Paid','Initial','1'); -INSERT INTO "Disbursement__c" VALUES(2,'125345.0','','Cash','2018-05-11','Scheduled','Interim','1'); -INSERT INTO "Disbursement__c" VALUES(3,'65667.0','','Cash','2018-02-15','Scheduled','Amendment','1'); -INSERT INTO "Disbursement__c" VALUES(4,'5000.0','','EFT','2018-06-01','Scheduled','Initial','5'); -INSERT INTO "Disbursement__c" VALUES(5,'50000.0','','EFT','2018-12-01','Scheduled','Interim','5'); -INSERT INTO "Disbursement__c" VALUES(6,'50000.0','','EFT','2019-05-01','Scheduled','Final','5'); -INSERT INTO "Disbursement__c" VALUES(7,'25000.0','2018-07-13','Check','2018-07-15','Paid','Initial','17'); -INSERT INTO "Disbursement__c" VALUES(8,'25000.0','','Check','2018-12-15','Scheduled','Interim','17'); -INSERT INTO "Disbursement__c" VALUES(9,'4000.0','','','2018-11-01','Pending Approval','Final','8'); -INSERT INTO "Disbursement__c" VALUES(10,'4000.0','2018-05-31','EFT','2018-06-01','Approved','Initial','8'); -INSERT INTO "Disbursement__c" VALUES(11,'7000.0','2018-06-06','Cash','2018-06-06','Paid','Final','11'); -INSERT INTO "Disbursement__c" VALUES(12,'2500.0','','Check','2018-06-01','Scheduled','Initial','4'); -INSERT INTO "Disbursement__c" VALUES(13,'2500.0','','Check','2018-12-01','Scheduled','Final','4'); -INSERT INTO "Disbursement__c" VALUES(14,'20000.0','','EFT','2018-07-31','Pending Approval','Initial','6'); -INSERT INTO "Disbursement__c" VALUES(15,'20000.0','','EFT','2018-12-01','Scheduled','Final','6'); -INSERT INTO "Disbursement__c" VALUES(16,'50000.0','','EFT','2018-06-15','Approved','Initial','18'); -INSERT INTO "Disbursement__c" VALUES(17,'50000.0','','EFT','2018-09-01','Scheduled','Final','18'); -INSERT INTO "Disbursement__c" VALUES(18,'10000.0','','EFT','2018-09-01','Paid','Final','9'); -INSERT INTO "Disbursement__c" VALUES(19,'5000.0','2018-05-14','EFT','2018-05-11','Paid','Initial','9'); -INSERT INTO "Disbursement__c" VALUES(20,'15000.0','2017-08-01','Check','2017-08-01','Paid','Initial','13'); -INSERT INTO "Disbursement__c" VALUES(21,'5000.0','','EFT','2018-06-01','Scheduled','Initial','14'); -INSERT INTO "Disbursement__c" VALUES(22,'50000.0','','Check','2018-12-01','Scheduled','Interim','14'); -INSERT INTO "Disbursement__c" VALUES(23,'50000.0','','Check','2019-05-01','Scheduled','Final','14'); +INSERT INTO "Disbursement__c" VALUES(1,'40000.0','2019-05-14','EFT','2019-05-14','Paid','Final','5'); +INSERT INTO "Disbursement__c" VALUES(2,'10000.0','2020-03-28','EFT','2020-03-28','Paid','Initial','2'); +INSERT INTO "Disbursement__c" VALUES(3,'5000.0','2019-07-09','EFT','2019-07-09','Paid','Initial','3'); +INSERT INTO "Disbursement__c" VALUES(4,'5000.0','2020-07-09','','2020-07-09','Paid','Interim','3'); +INSERT INTO "Disbursement__c" VALUES(5,'5000.0','','EFT','2021-07-09','Scheduled','Final','3'); CREATE TABLE "Funding_Program__c" ( - id INTEGER NOT NULL, - "Name" VARCHAR(255), - "Description__c" VARCHAR(255), - "End_Date__c" VARCHAR(255), - "Start_Date__c" VARCHAR(255), - "Status__c" VARCHAR(255), - "Total_Program_Amount__c" VARCHAR(255), + id INTEGER NOT NULL, + "Name" VARCHAR(255), + "Description__c" VARCHAR(255), + "End_Date__c" VARCHAR(255), + "Start_Date__c" VARCHAR(255), + "Status__c" VARCHAR(255), + "Top_Level__c" VARCHAR(255), + "Total_Program_Amount__c" VARCHAR(255), + "Parent_Funding_Program__c" VARCHAR(255), + PRIMARY KEY (id) +); +INSERT INTO "Funding_Program__c" VALUES(1,'Kumar Endowment Scholarship','The Kumar family graciously sponsors the Kumar Endowment Scholarship Fund for high school students who have made a positive impact in their local community. This fund awards $2,000 scholarships every 4 years to ten students seeking higher education. Eligible expenses include tuition, room and board, fees, and books during the academic year.','2020-07-30','2020-01-14','In progress','False','200000.0','3'); +INSERT INTO "Funding_Program__c" VALUES(2,'Successful Scholars Grant','The Successful Scholars Grant provides funding to select non-profits and education institutes to enable students to excel in their academics. Past initiatives created by previous grantees include after-school tutoring, early literacy programs, and college preparation courses.','2020-08-13','2019-08-14','In progress','False','250000.0','3'); +INSERT INTO "Funding_Program__c" VALUES(3,'Education','','','','In progress','True','',''); +INSERT INTO "Funding_Program__c" VALUES(4,'Community Impact','','','','In progress','True','',''); +INSERT INTO "Funding_Program__c" VALUES(5,'Relief and Reinvestment Grant','The Relief and Reinvestment Grant provides financial assistance in the form of grants to small businesses experiencing temporary revenue loss due to unforeseen circumstances, such as a natural disaster or economic crisis. Grants of up to $10,000 are awarded to select small businesses to help offset lost revenue. This fund can be used for: + * Rent and utilities + * Payroll + * Outstanding debt + * Technology upgrades + * Immediate operation costs','2021-01-30','2020-01-31','In progress','False','300000.0','4'); +INSERT INTO "Funding_Program__c" VALUES(6,'Strategic Nonprofit Development','','','','Planned','True','',''); +CREATE TABLE "Funding_Request_Role__c" ( + id INTEGER NOT NULL, + "Role__c" VARCHAR(255), + "Status__c" VARCHAR(255), + "Contact__c" VARCHAR(255), + "Funding_Request__c" VARCHAR(255), PRIMARY KEY (id) ); -INSERT INTO "Funding_Program__c" VALUES(1,'Research Scholarship','','','','In progress',''); -INSERT INTO "Funding_Program__c" VALUES(2,'2017-2018 Research Scholarships','','2018-07-31','2017-08-01','In progress','500000.0'); -INSERT INTO "Funding_Program__c" VALUES(3,'2018-2019 Research Scholarship','','2019-07-31','2018-08-01','Planned','600000.0'); -INSERT INTO "Funding_Program__c" VALUES(4,'Community Support','Main Community Support program','','2018-01-01','In progress',''); -INSERT INTO "Funding_Program__c" VALUES(5,'2018 Community Support','2018 Community Support','2018-12-31','2018-01-01','Planned','100000.0'); -INSERT INTO "Funding_Program__c" VALUES(6,'Individual Fellowship','','','2018-01-01','In progress',''); -INSERT INTO "Funding_Program__c" VALUES(7,'2018 Individual Fellowship','','','2018-01-01','In progress','1000000.0'); -INSERT INTO "Funding_Program__c" VALUES(8,'2018-2019 STEAM Education','','2019-06-01','2018-08-01','In progress','50000.0'); -INSERT INTO "Funding_Program__c" VALUES(9,'College Scholarships','','','1994-01-01','In progress','1000000.0'); -INSERT INTO "Funding_Program__c" VALUES(10,'2018-2019 College Scholarships','','2018-08-31','2018-03-01','In progress','250000.0'); -INSERT INTO "Funding_Program__c" VALUES(11,'2018 Scholarships','','2018-08-01','2018-04-01','In progress','50000.0'); -INSERT INTO "Funding_Program__c" VALUES(12,'STEAM Education','','','2010-06-01','In progress',''); -INSERT INTO "Funding_Program__c" VALUES(13,'Environment','','','1987-04-19','In progress','100000000.0'); -INSERT INTO "Funding_Program__c" VALUES(14,'Lake Springfield Cleanup','','','2018-01-01','In progress','500000.0'); +INSERT INTO "Funding_Request_Role__c" VALUES(1,'Applicant','Current','3','2'); +INSERT INTO "Funding_Request_Role__c" VALUES(2,'Applicant','Former','7','5'); +INSERT INTO "Funding_Request_Role__c" VALUES(3,'Grant Manager','Current','2','2'); CREATE TABLE "Funding_Request__c" ( - id INTEGER NOT NULL, - "Name" VARCHAR(255), - "Application_Date__c" VARCHAR(255), - "Awarded_Amount__c" VARCHAR(255), - "Awarded_Date__c" VARCHAR(255), - "Close_Date__c" VARCHAR(255), - "Closed_reason__c" VARCHAR(255), - "Geographical_Area_Served__c" VARCHAR(255), - "Population_Served__c" VARCHAR(255), - "Recommended_Amount__c" VARCHAR(255), - "Requested_Amount__c" VARCHAR(255), - "Requested_For__c" VARCHAR(255), - "Status__c" VARCHAR(255), - "Term_End_Date__c" VARCHAR(255), - "Term_Start_Date__c" VARCHAR(255), - "Terms__c" VARCHAR(255), - "Applying_Contact__c" VARCHAR(255), - "Applying_Organization__c" VARCHAR(255), - "FundingProgram__c" VARCHAR(255), + id INTEGER NOT NULL, + "Name" VARCHAR(255), + "Application_Date__c" VARCHAR(255), + "Awarded_Amount__c" VARCHAR(255), + "Awarded_Date__c" VARCHAR(255), + "Close_Date__c" VARCHAR(255), + "Closed_reason__c" VARCHAR(255), + "Geographical_Area_Served__c" VARCHAR(255), + "Population_Served__c" VARCHAR(255), + "Recommended_Amount__c" VARCHAR(255), + "Requested_Amount__c" VARCHAR(255), + "Requested_For__c" VARCHAR(255), + "Status__c" VARCHAR(255), + "Term_End_Date__c" VARCHAR(255), + "Term_Start_Date__c" VARCHAR(255), + "Terms__c" VARCHAR(255), + "Applying_Contact__c" VARCHAR(255), + "Applying_Organization__c" VARCHAR(255), + "FundingProgram__c" VARCHAR(255), PRIMARY KEY (id) ); -INSERT INTO "Funding_Request__c" VALUES(1,'Test Funding Request','2018-04-02','12546.0','2018-04-10','2018-04-10','','State','Caregivers;Economically Disadvantaged People','15034.0','16408.0','','Awarded','2019-05-01','2018-05-01','','','','1'); -INSERT INTO "Funding_Request__c" VALUES(2,'Test Request','2018-09-19','','','','','','','','','','Submitted','','','','','','5'); -INSERT INTO "Funding_Request__c" VALUES(3,'Shelbyville Robotics','2018-03-01','','','','','City','Children and Youth','15000.0','20000.0','Shelbyville Robotics','Submitted','2019-05-31','2018-09-01','','','16','8'); -INSERT INTO "Funding_Request__c" VALUES(4,'2018 Nonprofit A 12345','2018-05-06','5000.0','2018-05-06','','','City','Children and Youth','9000.0','10000.0','Community Support for Youth','Awarded','2019-06-01','2018-06-01','Terms of the funded request','','3','5'); -INSERT INTO "Funding_Request__c" VALUES(5,'2018 Lisa Test 67897','2018-04-08','105000.0','2018-05-07','','','State','Adults','100000.0','100000.0','','Submitted','2019-05-31','2018-06-01','','23','','7'); -INSERT INTO "Funding_Request__c" VALUES(6,'Shari Reily 2018-2019 Scholarship','2018-03-01','40000.0','','','','','','4000.0','3000.0','SFDO Academy - SalesForce Admin','In Review','','','','1','','10'); -INSERT INTO "Funding_Request__c" VALUES(7,'DUFF Robots','2018-05-01','0.0','','2018-05-30','This is a for profit company, does not benefit children.','Country','Adults','0.0','30000.0','Building a robot army.','Rejected','','','','6','22','8'); -INSERT INTO "Funding_Request__c" VALUES(8,'Nick Lindberg - Scholarship 2018-19','2018-04-18','8000.0','2018-05-22','','','','','5000.0','3000.0','NYU - Dance & Computer Science','Submitted','2019-05-31','2018-08-15','Need a transcript and confirmation from NYU on acceptance','8','','10'); -INSERT INTO "Funding_Request__c" VALUES(9,'Springfield Robotics Team 2018','2018-01-01','15000.0','2018-05-30','','','City','Children and Youth','15000.0','10000.0','Robotics program','Awarded','2019-05-31','2018-09-01','For the 2018-19 School year to be used to support the robotics team.','12','29','8'); -INSERT INTO "Funding_Request__c" VALUES(10,'Bill Corkill Scholarship 2018-19','2018-04-02','','','','','','','5000.0','10000.0','WMU - Computers','Submitted','','','','9','','10'); -INSERT INTO "Funding_Request__c" VALUES(11,'Sarah Amin - Scholarship 2018-19','2018-04-03','','2018-06-06','','','','','5000.0','7000.0','UCLA - Arts & Crafts','Fully Disbursed','','','','10','','10'); -INSERT INTO "Funding_Request__c" VALUES(12,'Lisa Simpson Camp Scholarship','2018-04-17','','','','','','Children and Youth','','','','Submitted','','','','30','17','11'); -INSERT INTO "Funding_Request__c" VALUES(13,'Sally Jones','2017-04-28','50000.0','2017-07-26','','','','','55000.0','50000.0','','Awarded','2018-07-31','2017-08-01','','20','','2'); -INSERT INTO "Funding_Request__c" VALUES(14,'2018 Bob Test 98765','2018-04-22','105000.0','2018-05-07','','','State','Homeless','100000.0','100000.0','','Awarded','2019-05-31','2018-06-01','','21','','7'); -INSERT INTO "Funding_Request__c" VALUES(15,'2018 Nancy Carlson 23456','2018-03-06','','','','','City','Children and Youth','','100000.0','Serve children and youth','Submitted','','','','24','','7'); -INSERT INTO "Funding_Request__c" VALUES(16,'2018 Ken Test 34567','2018-04-29','','','','','Region','Economically Disadvantaged People','','100000.0','Information about request','Submitted','','','','22','','7'); -INSERT INTO "Funding_Request__c" VALUES(17,'2018 Operation Change the World 45678','2018-05-25','50000.0','2018-06-15','2018-06-15','','State','Families;Homeless;People with Disabilities','50000.0','75000.0','','Awarded','2018-06-30','2018-07-01','terms of the grant','25','9','5'); -INSERT INTO "Funding_Request__c" VALUES(18,'Remove 3 Eyed Fish','2018-06-07','100000.0','','','','City','Children and Youth','100000.0','100000.0','Remove contaminated fish from the lake','Awarded','','','','33','14','14'); +INSERT INTO "Funding_Request__c" VALUES(1,'Grantwood City Food Bank','','','','','','City','Below Poverty level;Economically Disadvantaged People;Homeless','','100000.0','Grantwood City Food Bank','In progress','','','','','2','4'); +INSERT INTO "Funding_Request__c" VALUES(2,'Takagawa Institute: Relief and Reinvestment Grant','2020-03-11','10000.0','2020-03-28','2020-03-28','Fully awarded.','Country','Immigrants and Refugees','10000.0','10000.0','','Fully Disbursed','2021-03-27','2020-03-28','One time payment with one year follow up','3','3','5'); +INSERT INTO "Funding_Request__c" VALUES(3,'Eager Beavers Read!','2019-04-25','15000.0','2019-07-09','','','City','Children and Youth','15000.0','15000.0','Eager Beavers Read! is an after school program that helps foster a love of reading in our 1st - 5th grade classes and also provides a safe place for students to go between 3:00 pm and 4:30 pm. Younger children will be paired up with an older student to help expand their early literacy skills, while older students work to develop mentoring skills and confidence.','Awarded','2022-08-13','2019-08-14','3 years','4','5','2'); +INSERT INTO "Funding_Request__c" VALUES(4,'STEPS to Leadership','2020-02-16','28000.0','','','','Region','Adults;Women','28000.0','28000.0','STEPS to Leadership is a proposed program that came from requests for additional leadership training for our graduates from Skills for Success, a successful program we currently offer to at-risk women in the community. After completing Skills for Success, graduates can learn leadership skills through various trainings, seminars, and one-on-one mentoring that will help prepare these future female leaders.','Submitted','','','','5','6','4'); +INSERT INTO "Funding_Request__c" VALUES(5,'Skills for Success','2019-03-21','40000.0','2019-05-14','','','Region','Adults;Women','40000.0','40000.0','Skills for Success addresses an existing gap for at-risk women seeking to learn technical and soft skills to help them find gainful employment in the community. Participants of the program receive: + +* Vouchers for free community college courses on select topics, such as bookkeeping, computer literacy, and communication skills. +* Help developing a resume and interview preparation. +* One-on-one mentoring with a female business owner in the community. +* Ongoing support from the STEPS staff.','Awarded','2020-05-30','2019-05-31','1 year','6','6','4'); +INSERT INTO "Funding_Request__c" VALUES(6,'Skills for Success','2020-05-31','','','','','Region','Adults;Women','','46000.0','Skills for Success addresses an existing gap for at-risk women seeking to learn technical and soft skills to help them find gainful employment in the community. Participants of the program receive: + +* Vouchers for free community college courses on select topics, such as bookkeeping, computer literacy, and communication skills. +* Help developing a resume and interview preparation. +* One-on-one mentoring with a female business owner in the community. +* Ongoing support from the STEPS staff.','In progress','','','1 year','6','6','4'); CREATE TABLE "Requirement__c" ( - id INTEGER NOT NULL, - "Name" VARCHAR(255), - "Completed_Date__c" VARCHAR(255), - "Due_Date__c" VARCHAR(255), - "Requirements__c" VARCHAR(255), - "Status__c" VARCHAR(255), - "Type__c" VARCHAR(255), - "Disbursement__c" VARCHAR(255), - "Funding_Request__c" VARCHAR(255), - "Primary_Contact__c" VARCHAR(255), + id INTEGER NOT NULL, + "Name" VARCHAR(255), + "Completed_Date__c" VARCHAR(255), + "Due_Date__c" VARCHAR(255), + "Requirements__c" VARCHAR(255), + "Status__c" VARCHAR(255), + "Type__c" VARCHAR(255), + "Disbursement__c" VARCHAR(255), + "Funding_Request__c" VARCHAR(255), + "Primary_Contact__c" VARCHAR(255), + PRIMARY KEY (id) +); +INSERT INTO "Requirement__c" VALUES(1,'Application','2019-03-21','2019-12-30','

Application

','Accepted','Final Application','','5','6'); +INSERT INTO "Requirement__c" VALUES(2,'Outcome Report','','2020-12-30','

Outcome Report

','Open','Outcome','','5','6'); +INSERT INTO "Requirement__c" VALUES(3,'Proposed Budget','2019-03-21','2019-12-30','

Proposed budget

','Accepted','Report','','5','6'); +INSERT INTO "Requirement__c" VALUES(4,'Budget Report','2020-02-11','2020-12-30','

Budget Report

','Complete','Report','','5','6'); +INSERT INTO "Requirement__c" VALUES(5,'Letter of Intent','2019-03-21','2019-12-30','

Cover letter

','Accepted','Letter of Intent','','5','6'); +INSERT INTO "Requirement__c" VALUES(6,'Budget Report','','2020-09-14','

Budget Report

','Open','Report','','2','3'); +INSERT INTO "Requirement__c" VALUES(7,'Outcome Report','','2021-03-31','

Outcome Report

','Open','Outcome','','2','3'); +INSERT INTO "Requirement__c" VALUES(8,'Application','2020-03-11','2020-12-30','

Application

','Accepted','Final Application','','2','3'); +INSERT INTO "Requirement__c" VALUES(9,'Letter of Intent','2019-04-25','2019-12-30','

Cover letter

','Accepted','Letter of Intent','','3','4'); +INSERT INTO "Requirement__c" VALUES(10,'Application','2019-04-25','2019-12-30','

Application

','Accepted','Final Application','','3','4'); +INSERT INTO "Requirement__c" VALUES(11,'Outcome Report','','2022-12-30','

Outcome Report

','Open','Outcome','','3','4'); +INSERT INTO "Requirement__c" VALUES(12,'Budget Report','','2021-12-30','

Budget Report

','Open','Report','','3','4'); +CREATE TABLE "Review__c" ( + id INTEGER NOT NULL, + "Name" VARCHAR(255), + "Comments__c" VARCHAR(255), + "DueDate__c" VARCHAR(255), + "Status__c" VARCHAR(255), + "SubmittedDate__c" VARCHAR(255), + "FundingRequest__c" VARCHAR(255), PRIMARY KEY (id) ); -INSERT INTO "Requirement__c" VALUES(1,'Review Completed','2018-05-01','2018-05-15','','Complete','Review','','17',''); -INSERT INTO "Requirement__c" VALUES(2,'Application Submitted','2018-04-12','2018-04-30','','Complete','Final Application','','17',''); -INSERT INTO "Requirement__c" VALUES(3,'Final Report','','2019-07-31','','Open','Report','','17','25'); -INSERT INTO "Requirement__c" VALUES(4,'Test Requirement','','','','','','','8','3'); -INSERT INTO "Requirement__c" VALUES(5,'Proposal Required','2018-05-28','2018-05-25','

Proposal must be submitted. Was not adequate and did not meet criteria for grant program.

','Rejected','Preliminary Application','','7','6'); -INSERT INTO "Requirement__c" VALUES(6,'LOI Required','2018-02-21','2018-02-13','','Accepted','Letter of Intent','','3','35'); -INSERT INTO "Requirement__c" VALUES(7,'Application','2018-05-16','2018-05-01','','In Progress','Preliminary Application','','3','35'); -INSERT INTO "Requirement__c" VALUES(8,'Budget Req.','','2018-07-02','','In Progress','Final Application','','3','35'); -INSERT INTO "Requirement__c" VALUES(9,'Final Report','','2019-05-01','','Open','Report','','3','35'); -INSERT INTO "Requirement__c" VALUES(10,'Budget Required','2018-06-07','2018-06-15','

Need budget from Ned before initial payment can be made.

','Complete','Preliminary Application','16','18','3'); -INSERT INTO "Requirement__c" VALUES(11,'Interim Report','','2018-11-30','','Open','Report','8','17','25'); -INSERT INTO "Requirement__c" VALUES(12,'Completion of Semester 1 and re-enrollment in semester 2','','2019-01-07','','Open','Final Application','9','8','8'); -INSERT INTO "Requirement__c" VALUES(13,'Acceptance Notice','2018-05-30','2018-08-01','','Complete','Final Application','10','8','8'); -INSERT INTO "Requirement__c" VALUES(14,'Transcript Required','','2018-06-30','','In Progress','Final Application','10','8','8'); -INSERT INTO "Requirement__c" VALUES(15,'Budget Required for 2nd (final) payment','','2018-08-01','','Open','Report','18','9','12'); -INSERT INTO "Requirement__c" VALUES(16,'Need Transcript','','2018-07-31','

Need Final Transcript before payment can be made

','Open','Final Application','14','6','1'); +INSERT INTO "Review__c" VALUES(1,'Scholarship 2021-22 - Sarah Amin','

Need more documentation!

','2021-07-17','In Progress','','1'); +INSERT INTO "Review__c" VALUES(2,'Review - External','','2021-04-29','Submitted','2021-04-28','2'); +INSERT INTO "Review__c" VALUES(3,'Review of Application - Shari Reily - Scholarship 2021','','2021-07-30','Not Started','','3'); +INSERT INTO "Review__c" VALUES(4,'Review - Program Officer','

Looks great!

','2021-04-27','Submitted','2021-04-28','2'); COMMIT; diff --git a/force-app/main/default/applications/Outbound_Funds.app-meta.xml b/force-app/main/default/applications/Outbound_Funds.app-meta.xml index 9150fa4e..385e31e9 100644 --- a/force-app/main/default/applications/Outbound_Funds.app-meta.xml +++ b/force-app/main/default/applications/Outbound_Funds.app-meta.xml @@ -62,6 +62,7 @@ Funding_Program__c Funding_Request__c Requirement__c + Review__c standard-report standard-Dashboard Lightning diff --git a/force-app/main/default/flexipages/Funding_Request_Record_Page.flexipage-meta.xml b/force-app/main/default/flexipages/Funding_Request_Record_Page.flexipage-meta.xml index 0daa52a4..9ee19f63 100644 --- a/force-app/main/default/flexipages/Funding_Request_Record_Page.flexipage-meta.xml +++ b/force-app/main/default/flexipages/Funding_Request_Record_Page.flexipage-meta.xml @@ -8,6 +8,10 @@ false + enableActionsConfiguration + false + + hideChatterActions false @@ -85,6 +89,35 @@ facet-cfea03f7-05b2-4289-b5dd-b370eddb1a3e Facet + + + + + parentFieldApiName + Funding_Request__c.Id + + + relatedListApiName + Reviews__r + + + relatedListComponentOverride + NONE + + + rowsToDisplay + 10 + + + showActionBar + true + + force:relatedListSingleContainer + + + Facet-3e434ff4-6a9b-4377-b354-0951fe451efb + Facet + @@ -133,6 +166,19 @@ flexipage:tab + + + + body + Facet-3e434ff4-6a9b-4377-b354-0951fe451efb + + + title + Reviews + + flexipage:tab + + facet-b1444878-6707-43f0-8ada-196082626d67 Facet diff --git a/force-app/main/default/flexipages/Review_Record_Page.flexipage-meta.xml b/force-app/main/default/flexipages/Review_Record_Page.flexipage-meta.xml new file mode 100644 index 00000000..0e6f1985 --- /dev/null +++ b/force-app/main/default/flexipages/Review_Record_Page.flexipage-meta.xml @@ -0,0 +1,167 @@ + + + + + + + collapsed + false + + + enableActionsConfiguration + false + + + enableActionsInNative + false + + + hideChatterActions + false + + + numVisibleActions + 3 + + force:highlightsPanel + + + Replace + header + Region + + + + + force:detailPanel + + + Replace + detailTabContent + Facet + + + + + + relatedListComponentOverride + NONE + + + rowsToDisplay + 10 + + + showActionBar + true + + force:relatedListContainer + + + Replace + relatedTabContent + Facet + + + + + + active + true + + + body + detailTabContent + + + title + Standard.Tab.detail + + flexipage:tab + + + + + + body + relatedTabContent + + + title + Standard.Tab.relatedLists + + flexipage:tab + + + Replace + maintabs + Facet + + + + + + tabs + maintabs + + flexipage:tabset + + + Replace + main + Region + + + + + runtime_sales_activities:activityPanel + + + Replace + activityTabContent + Facet + + + + + + active + true + + + body + activityTabContent + + + title + Standard.Tab.activity + + flexipage:tab + + + Replace + sidebartabs + Facet + + + + + + tabs + sidebartabs + + flexipage:tabset + + + Replace + sidebar + Region + + Review Record Page + flexipage__default_rec_L + Review__c + + RecordPage + diff --git a/force-app/main/default/layouts/Funding_Request__c-Funding Request Layout.layout-meta.xml b/force-app/main/default/layouts/Funding_Request__c-Funding Request Layout.layout-meta.xml index 61322c05..163e790c 100644 --- a/force-app/main/default/layouts/Funding_Request__c-Funding Request Layout.layout-meta.xml +++ b/force-app/main/default/layouts/Funding_Request__c-Funding Request Layout.layout-meta.xml @@ -199,11 +199,6 @@ Record - - FeedItem.TextPost - QuickAction - 0 - Funding_Request__c.Create_Bulk_Disbursements QuickAction @@ -244,6 +239,16 @@ StandardButton 8 + + Share + StandardButton + 9 + + + FeedItem.TextPost + QuickAction + 0 + NAME @@ -268,6 +273,13 @@ Scheduled_Date__c Asc + + NAME + AssignedTo__c + DueDate__c + Status__c + Review__c.FundingRequest__c + NAME Contact__c @@ -303,7 +315,7 @@ false false - 00hP0000000nX06 + 00h2D000002AEXN 4 0 Default diff --git a/force-app/main/default/layouts/Requirement__c-Requirement Layout.layout-meta.xml b/force-app/main/default/layouts/Requirement__c-Requirement Layout.layout-meta.xml index e63c8e63..3fd3fe72 100644 --- a/force-app/main/default/layouts/Requirement__c-Requirement Layout.layout-meta.xml +++ b/force-app/main/default/layouts/Requirement__c-Requirement Layout.layout-meta.xml @@ -139,14 +139,14 @@ 4 - FeedItem.TextPost + SendEmail QuickAction - 6 + 5 - SendEmail + FeedItem.TextPost QuickAction - 5 + 6 FeedItem.ContentPost @@ -158,6 +158,11 @@ QuickAction 8 + + Share + StandardButton + 9 + diff --git a/force-app/main/default/layouts/Review__c-Review Layout.layout-meta.xml b/force-app/main/default/layouts/Review__c-Review Layout.layout-meta.xml new file mode 100644 index 00000000..aefad4d4 --- /dev/null +++ b/force-app/main/default/layouts/Review__c-Review Layout.layout-meta.xml @@ -0,0 +1,168 @@ + + + ChangeRecordType + IsotopeSubscription + Submit + + false + false + true + + + + Required + Name + + + Edit + Status__c + + + Edit + FundingRequest__c + + + + + Edit + OwnerId + + + Edit + AssignedTo__c + + + Edit + DueDate__c + + + Edit + SubmittedDate__c + + + + + + true + true + true + + + + Edit + Comments__c + + + + + + false + false + true + + + + Readonly + CreatedById + + + + + Readonly + LastModifiedById + + + + + + true + false + true + + + + + + + + Record + + Review__c.SubmitReview + QuickAction + 0 + + + Edit + StandardButton + 1 + + + Clone + StandardButton + 2 + + + FeedItem.TextPost + QuickAction + 3 + + + Delete + StandardButton + 4 + + + FeedItem.ContentPost + QuickAction + 5 + + + ChangeOwnerOne + StandardButton + 6 + + + PrintableView + StandardButton + 7 + + + Share + StandardButton + 8 + + + + RelatedFileList + + + TASK.SUBJECT + TASK.WHO_NAME + ACTIVITY.TASK + TASK.DUE_DATE + TASK.STATUS + TASK.PRIORITY + CORE.USERS.FULL_NAME + RelatedActivityList + + + TASK.SUBJECT + TASK.WHO_NAME + ACTIVITY.TASK + TASK.DUE_DATE + CORE.USERS.FULL_NAME + TASK.LAST_UPDATE + RelatedHistoryList + + false + false + false + false + false + + 00h8A000002awrU + 4 + 0 + Default + + diff --git a/force-app/main/default/objects/Review__c/Review__c.object-meta.xml b/force-app/main/default/objects/Review__c/Review__c.object-meta.xml new file mode 100644 index 00000000..f86e2801 --- /dev/null +++ b/force-app/main/default/objects/Review__c/Review__c.object-meta.xml @@ -0,0 +1,188 @@ + + + + Accept + Default + + + Accept + Large + Default + + + Accept + Small + Default + + + CancelEdit + Default + + + CancelEdit + Large + Default + + + CancelEdit + Small + Default + + + Clone + Default + + + Clone + Large + Default + + + Clone + Small + Default + + + Delete + Default + + + Delete + Large + Default + + + Delete + Small + Default + + + Edit + Default + + + Edit + Large + Default + + + Edit + Small + Default + + + List + Default + + + List + Large + Default + + + List + Small + Default + + + New + Default + + + New + Large + Default + + + New + Small + Default + + + SaveEdit + Default + + + SaveEdit + Large + Default + + + SaveEdit + Small + Default + + + Tab + Default + + + Tab + Large + Default + + + Tab + Small + Default + + + View + Action override created by Lightning App Builder during activation. + Review_Record_Page + Large + false + Flexipage + + + View + Action override created by Lightning App Builder during activation. + Review_Record_Page + Small + false + Flexipage + + + View + Default + + true + SYSTEM + Deployed + Collects feedback from a reviewer. + true + true + false + true + false + true + true + true + true + Private + + + + false + Text + + Reviews + + Status__c + AssignedTo__c + DueDate__c + Status__c + AssignedTo__c + DueDate__c + NAME + Status__c + AssignedTo__c + DueDate__c + FundingRequest__c + Status__c + AssignedTo__c + DueDate__c + + ReadWrite + Public + diff --git a/force-app/main/default/objects/Review__c/fields/AssignedTo__c.field-meta.xml b/force-app/main/default/objects/Review__c/fields/AssignedTo__c.field-meta.xml new file mode 100644 index 00000000..e00069eb --- /dev/null +++ b/force-app/main/default/objects/Review__c/fields/AssignedTo__c.field-meta.xml @@ -0,0 +1,15 @@ + + + AssignedTo__c + Lookup to the User who is performing the Review. + Select who should review this Review record. + SetNull + false + + User + Reviews + false + false + false + Lookup + diff --git a/force-app/main/default/objects/Review__c/fields/Comments__c.field-meta.xml b/force-app/main/default/objects/Review__c/fields/Comments__c.field-meta.xml new file mode 100644 index 00000000..b43b3d88 --- /dev/null +++ b/force-app/main/default/objects/Review__c/fields/Comments__c.field-meta.xml @@ -0,0 +1,12 @@ + + + Comments__c + Add notes about the Review of the Funding Request. + false + + 32768 + false + false + Html + 25 + diff --git a/force-app/main/default/objects/Review__c/fields/DueDate__c.field-meta.xml b/force-app/main/default/objects/Review__c/fields/DueDate__c.field-meta.xml new file mode 100644 index 00000000..95dd1188 --- /dev/null +++ b/force-app/main/default/objects/Review__c/fields/DueDate__c.field-meta.xml @@ -0,0 +1,12 @@ + + + DueDate__c + The date the Review is due. + The date the Review is due. + false + + false + false + false + Date + diff --git a/force-app/main/default/objects/Review__c/fields/FundingRequest__c.field-meta.xml b/force-app/main/default/objects/Review__c/fields/FundingRequest__c.field-meta.xml new file mode 100644 index 00000000..0818b366 --- /dev/null +++ b/force-app/main/default/objects/Review__c/fields/FundingRequest__c.field-meta.xml @@ -0,0 +1,15 @@ + + + FundingRequest__c + The name of the Funding Request being reviewed. + SetNull + false + + Funding_Request__c + Reviews + Reviews + false + false + false + Lookup + diff --git a/force-app/main/default/objects/Review__c/fields/Status__c.field-meta.xml b/force-app/main/default/objects/Review__c/fields/Status__c.field-meta.xml new file mode 100644 index 00000000..c4e11d23 --- /dev/null +++ b/force-app/main/default/objects/Review__c/fields/Status__c.field-meta.xml @@ -0,0 +1,33 @@ + + + Status__c + The status of the Review. + false + The status of the Review. + + false + false + false + Picklist + + true + + false + + Not Started + false + + + + In Progress + false + + + + Submitted + false + + + + + diff --git a/force-app/main/default/objects/Review__c/fields/SubmittedDate__c.field-meta.xml b/force-app/main/default/objects/Review__c/fields/SubmittedDate__c.field-meta.xml new file mode 100644 index 00000000..deea2373 --- /dev/null +++ b/force-app/main/default/objects/Review__c/fields/SubmittedDate__c.field-meta.xml @@ -0,0 +1,12 @@ + + + SubmittedDate__c + The date the Review was submitted. + The date the Review was submitted. + false + + false + true + false + Date + diff --git a/force-app/main/default/objects/Review__c/listViews/All.listView-meta.xml b/force-app/main/default/objects/Review__c/listViews/All.listView-meta.xml new file mode 100644 index 00000000..39015a01 --- /dev/null +++ b/force-app/main/default/objects/Review__c/listViews/All.listView-meta.xml @@ -0,0 +1,10 @@ + + + All + NAME + Status__c + AssignedTo__c + DueDate__c + Everything + + diff --git a/force-app/main/default/objects/Review__c/listViews/OpenReviews.listView-meta.xml b/force-app/main/default/objects/Review__c/listViews/OpenReviews.listView-meta.xml new file mode 100644 index 00000000..60186c98 --- /dev/null +++ b/force-app/main/default/objects/Review__c/listViews/OpenReviews.listView-meta.xml @@ -0,0 +1,17 @@ + + + OpenReviews + FundingRequest__c + NAME + Status__c + DueDate__c + Comments__c + AssignedTo__c + Everything + + Status__c + notEqual + Submitted + + + diff --git a/force-app/main/default/quickActions/Review__c.SubmitReview.quickAction-meta.xml b/force-app/main/default/quickActions/Review__c.SubmitReview.quickAction-meta.xml new file mode 100644 index 00000000..857ffe3e --- /dev/null +++ b/force-app/main/default/quickActions/Review__c.SubmitReview.quickAction-meta.xml @@ -0,0 +1,38 @@ + + + Updates the Review Status to "Submitted" and Submitted Date to the current date. + + Status__c + Submitted + + + SubmittedDate__c + NOW() + + + false + + TwoColumnsLeftToRight + + + false + SubmittedDate__c + Readonly + + + false + Status__c + Readonly + + + + + false + AssignedTo__c + Readonly + + + + Review submitted. + Update + diff --git a/force-app/main/default/reports/NPSP_Outbound_Fund_Reports/Overdue_Disbursements.report-meta.xml b/force-app/main/default/reports/NPSP_Outbound_Fund_Reports/Overdue_Disbursements.report-meta.xml new file mode 100644 index 00000000..742f0f2e --- /dev/null +++ b/force-app/main/default/reports/NPSP_Outbound_Fund_Reports/Overdue_Disbursements.report-meta.xml @@ -0,0 +1,101 @@ + + + + #FFFFFF + #FFFFFF + Diagonal + + Sum + y + Funding_Program__c.FundingRequests__r.Disbursements__r$Amount__c + + VerticalColumnStacked + false + true + CDF1 + Right + CHART_BOTTOM + Funding_Program__c$Name + true + false + false + false + Medium + Auto + #000000 + 12 + Overdue Disbursements + #000000 + 18 + + + Funding_Program__c.FundingRequests__r.Disbursements__r$Funding_Request__c + + + Funding_Program__c.FundingRequests__r.Disbursements__r$Name + + + Funding_Program__c.FundingRequests__r.Disbursements__r$Scheduled_Date__c + + + Sum + Funding_Program__c.FundingRequests__r.Disbursements__r$Amount__c + + + Funding_Program__c.FundingRequests__r.Disbursements__r$Status__c + + List of Disbursements that are overdue by 1-30 days, 31-60 days, and 61+ days. + + IF(TODAY() - Disbursement__c.Scheduled_Date__c > 60 , '61+ Days', +IF( TODAY() - Disbursement__c.Scheduled_Date__c > 30 && TODAY() - Disbursement__c.Scheduled_Date__c < 61, '31 - 60 days', '1 - 30 days' +) +) + Text + Days Overdue + CDF1 + + 0 + + + + Funding_Program__c.FundingRequests__r.Disbursements__r$Status__c + false + true + notEqual + Paid,Cancelled + + + Funding_Program__c.FundingRequests__r.Disbursements__r$Scheduled_Date__c + false + true + lessThan + TODAY + + en_US + + Summary + + Day + CDF1 + Asc + + + Day + Funding_Program__c$Name + Asc + + Overdue Disbursements + + co + 1 + + Funding_Programs_with_Funding_Requests_with_Disbursements__c + organization + true + true + true + + Funding_Program__c$CreatedDate + INTERVAL_CUSTOM + + diff --git a/force-app/main/default/reports/NPSP_Outbound_Fund_Reports/Unscheduled_Disbursements.report-meta.xml b/force-app/main/default/reports/NPSP_Outbound_Fund_Reports/Unscheduled_Disbursements.report-meta.xml new file mode 100644 index 00000000..cc2c2ac7 --- /dev/null +++ b/force-app/main/default/reports/NPSP_Outbound_Fund_Reports/Unscheduled_Disbursements.report-meta.xml @@ -0,0 +1,57 @@ + + + + CUST_NAME + + + Funding_Request__c.Awarded_Date__c + + + Sum + Funding_Request__c.Awarded_Amount__c + + + Sum + Funding_Request__c.Total_Remaining__c + + + Sum + Funding_Request__c.Total_Disbursed__c + + + Sum + Funding_Request__c.Unpaid_Disbursements__c + + + Sum + Funding_Request__c.Total_Cancelled__c + + List of awarded Funding Requests that have available funds to be scheduled for disbursement. + + + Funding_Request__c.Total_Remaining__c + false + true + greaterThan + 0 + + en_US + + Tabular + Unscheduled Disbursements + + co + 1 + + CustomEntity$Funding_Request__c + organization + true + true + true + Funding_Request__c.Total_Remaining__c + Asc + + Funding_Request__c.Application_Date__c + INTERVAL_CUSTOM + + diff --git a/force-app/main/default/reports/NPSP_Outbound_Fund_Reports/UpcomingDisbursements_12mo.report-meta.xml b/force-app/main/default/reports/NPSP_Outbound_Fund_Reports/UpcomingDisbursements_12mo.report-meta.xml new file mode 100644 index 00000000..352a8ff7 --- /dev/null +++ b/force-app/main/default/reports/NPSP_Outbound_Fund_Reports/UpcomingDisbursements_12mo.report-meta.xml @@ -0,0 +1,101 @@ + + + + #FFFFFF + #FFFFFF + Diagonal + + Sum + y + Funding_Program__c.FundingRequests__r.Disbursements__r$Amount__c + + VerticalColumnStacked + false + true + Funding_Program__c.FundingRequests__r.Disbursements__r$Scheduled_Date__c + Right + CHART_BOTTOM + Funding_Program__c$Name + true + false + false + false + Medium + Auto + #000000 + 12 + Upcoming Disbursements + #000000 + 18 + + + Funding_Program__c.FundingRequests__r$Name + + + Funding_Program__c.FundingRequests__r$Awarded_Date__c + + + Funding_Program__c.FundingRequests__r$Awarded_Amount__c + + + Funding_Program__c.FundingRequests__r.Disbursements__r$Name + + + Funding_Program__c.FundingRequests__r.Disbursements__r$Status__c + + + Sum + Funding_Program__c.FundingRequests__r.Disbursements__r$Amount__c + + List of upcoming unpaid Disbursements over the next 12 months. + + 1 AND (2 OR 3) + + Funding_Program__c.FundingRequests__r.Disbursements__r$Status__c + false + true + notEqual + Paid,Cancelled + + + Funding_Program__c.FundingRequests__r.Disbursements__r$Scheduled_Date__c + false + true + equals + THIS_MONTH + + + Funding_Program__c.FundingRequests__r.Disbursements__r$Scheduled_Date__c + false + true + equals + NEXT_N_MONTHS:11 + + en_US + + Matrix + + Month + Funding_Program__c.FundingRequests__r.Disbursements__r$Scheduled_Date__c + Asc + + + Day + Funding_Program__c$Name + Asc + + Upcoming Disbursements + + co + 1 + + Funding_Programs_with_Funding_Requests_with_Disbursements__c + organization + false + true + true + + Funding_Program__c$CreatedDate + INTERVAL_CUSTOM + + diff --git a/force-app/main/default/tabs/Review__c.tab-meta.xml b/force-app/main/default/tabs/Review__c.tab-meta.xml new file mode 100644 index 00000000..606d6f66 --- /dev/null +++ b/force-app/main/default/tabs/Review__c.tab-meta.xml @@ -0,0 +1,5 @@ + + + true + Custom90: Scales + diff --git a/lib/admin.profile-meta.xml b/lib/admin.profile-meta.xml index c6fb40d7..21ae3cc2 100644 --- a/lib/admin.profile-meta.xml +++ b/lib/admin.profile-meta.xml @@ -12,11 +12,16 @@ Contact Lead Opportunity + %%%NAMESPACE%%%Funding_Request__c CustomObject Admin Profile + + * + CustomTab + 48.0 diff --git a/robot/OutboundFunds/doc/Keywords.html b/robot/OutboundFunds/doc/Keywords.html index 0b39f757..14498418 100644 --- a/robot/OutboundFunds/doc/Keywords.html +++ b/robot/OutboundFunds/doc/Keywords.html @@ -230,6 +230,37 @@

+ + Click Related List Link + + text + + +

Click on link with passed text

+ + + + + Click Related List Wrapper Button + + heading, + + button_title + + +

+ loads the related list and clicks on the button on + the list +

+ + + Click Save @@ -266,7 +297,12 @@

name - + +

+ This is a helper function to capture the namespace + prefix of the target org +

+ > Get Outfunds Namespace Prefix - + +

Get outfunds__ prefix for custom objects

+ @@ -308,6 +346,21 @@

+ + Select Value From Picklist + + dropdown, + + value + + +

Select given value in the dropdown field

+ + + + + + API Create Review on a Funding Request + + + funding_request_id, + + **fields + + +

Create a Review on a Funding Request via API

+ + + + + + API Get User Id of Permissions Test User + + + **fields + +

Returns the ID of a User

+ +

+ + + Change Field Permissions + + action, + + objectapiname, + + fieldapiname, + + permset + + +

+ Adds or removes the Create, Read, Edit and Delete + permissions for the specified object field on the + specified permission set. +

+ + + + + Change Object Permissions + + action, + + objectapiname, + + permset + + +

+ Adds or removes the Create, Read, Edit and Delete + permissions for the specified object on the + specified permission set.. +

+ + + + + Field Permissions Cleanup + + objectapiname, + + fieldapiname, + + permset + + +

+ Resets all field permissions in case a test fails + before they are restored. Skips the reset if the + permissions have already been added back. +

+ + + + + Object Permissions Cleanup + + objectapiname, + + permset + + +

+ Resets all object permissions in case a test fails + before they are restored. Skips the reset if the + permissions have already been added back. +

+ + @@ -746,9 +913,122 @@

+ +
+
+

+ ReviewPageObject.py +

+
+ robot/OutboundFunds/resources/ReviewPageObject.py +
+
+ +
+
+ + + + + + + + + + + +
DetailsReview__c
Page TypeObject Name
+
+ +
+

+ Documentation for library + ReviewPageObject.ReviewDetailPage. +

+
+ + + + + + + + + + + + + + + + + + + + +
KeywordArgumentsDocumentation
Log Current Page Object +

Logs the name of the current page object

+

+ The current page object is also returned as an + object +

+
Submit Review
+
+ +
+
+ + + + + + + + + + + +
ListingReview__c
Page TypeObject Name
+
+ +
+

+ Documentation for library + ReviewPageObject.ReviewListingPage. +

+
+ + + + + + + + + + + + + + +
KeywordArgumentsDocumentation
Log Current Page Object +

Logs the name of the current page object

+

+ The current page object is also returned as an + object +

+
+
+
diff --git a/robot/OutboundFunds/resources/ContactPageObject.py b/robot/OutboundFunds/resources/ContactPageObject.py new file mode 100644 index 00000000..000075c5 --- /dev/null +++ b/robot/OutboundFunds/resources/ContactPageObject.py @@ -0,0 +1,14 @@ +from cumulusci.robotframework.pageobjects import DetailPage +from cumulusci.robotframework.pageobjects import ListingPage +from cumulusci.robotframework.pageobjects import pageobject +from BaseObjects import BaseOutboundFundsPage + + +@pageobject("Listing", "Contact") +class ContactListingPage(BaseOutboundFundsPage, ListingPage): + object_name = "Contact" + + +@pageobject("Detail", "Contact") +class ContactDetailPage(BaseOutboundFundsPage, DetailPage): + object_name = "Contact" diff --git a/robot/OutboundFunds/resources/FundingRequestPageObject.py b/robot/OutboundFunds/resources/FundingRequestPageObject.py index 32a7057d..346ec2ad 100644 --- a/robot/OutboundFunds/resources/FundingRequestPageObject.py +++ b/robot/OutboundFunds/resources/FundingRequestPageObject.py @@ -32,3 +32,33 @@ def save_disbursement(self): locator = outboundfunds_lex_locators["details"]["button"].format("Save") self.selenium.set_focus_to_element(locator) self.selenium.get_webelement(locator).click() + + def save_funding_request_role(self): + """save funding request role""" + if self.OutboundFunds.latest_api_version == 52.0: + locator = outboundfunds_lex_locators["funding_req_role"]["save_button"] + self.selenium.set_focus_to_element(locator) + self.selenium.get_webelement(locator).click() + else: + locator = outboundfunds_lex_locators["funding_req_role"]["save_button_old"] + self.selenium.set_focus_to_element(locator) + self.selenium.get_webelement(locator).click() + + def click_funding_request_role_link(self): + """click on a link in right panel for funding request role""" + fr_link = outboundfunds_lex_locators["funding_req_role"]["fr_link"] + self.selenium.wait_until_page_contains_element( + fr_link, error="The FR- link is not available" + ) + self.selenium.get_webelement(fr_link).click() + + +@pageobject("Details", "Funding_Request_Role__c") +class FundingRequestRoleDetailPage(BaseOutboundFundsPage, DetailPage): + def _is_current_page(self): + """Verify we are on the Funding Request detail page + by verifying that the url contains '/view' + """ + self.selenium.wait_until_location_contains( + "/view", timeout=60, message="Detail page did not load in 1 min" + ) diff --git a/robot/OutboundFunds/resources/OutboundFunds.py b/robot/OutboundFunds/resources/OutboundFunds.py index 999fb104..f00d9bf9 100644 --- a/robot/OutboundFunds/resources/OutboundFunds.py +++ b/robot/OutboundFunds/resources/OutboundFunds.py @@ -2,15 +2,19 @@ import random import string import warnings +import time from BaseObjects import BaseOutboundFundsPage from selenium.common.exceptions import NoSuchWindowException from robot.libraries.BuiltIn import RobotNotRunningError +from locators_52 import outboundfunds_lex_locators as locators_52 from locators_51 import outboundfunds_lex_locators as locators_51 from cumulusci.robotframework.utils import selenium_retry, capture_screenshot_on_error +from selenium.webdriver.common.keys import Keys locators_by_api_version = { 51.0: locators_51, # Spring '21 + 52.0: locators_52, # Summer '21 } # will get populated in _init_locators outboundfunds_lex_locators = {} @@ -53,7 +57,7 @@ def _init_locators(self): outboundfunds_lex_locators.update(locators) def get_namespace_prefix(self, name): - """ This is a helper function to capture the namespace prefix of the target org """ + """This is a helper function to capture the namespace prefix of the target org""" parts = name.split("__") if parts[-1] == "c": parts = parts[:-1] @@ -85,7 +89,7 @@ def check_if_element_exists(self, xpath): return True if elements > 0 else False def new_random_string(self, len=5): - """Generate a random string of fixed length """ + """Generate a random string of fixed length""" return "".join(random.choice(string.ascii_lowercase) for _ in range(len)) def generate_new_string(self, prefix="Robot Test"): @@ -122,7 +126,7 @@ def click_save(self): locator = outboundfunds_lex_locators["new_record"]["footer_button"].format( "Save" ) - self.selenium.scroll_element_into_view(locator) + self.salesforce.scroll_element_into_view(locator) self.salesforce._jsclick(locator) def validate_field_value(self, field, status, value, section=None): @@ -131,7 +135,7 @@ def validate_field_value(self, field, status, value, section=None): """ if section is not None: section = "text:" + section - self.selenium.scroll_element_into_view(section) + self.salesforce.scroll_element_into_view(section) list_found = False locators = outboundfunds_lex_locators["confirm"].values() if status == "contains": @@ -178,22 +182,22 @@ def click_flexipage_dropdown(self, title, value): ) option = outboundfunds_lex_locators["span"].format(value) self.selenium.wait_until_page_contains_element(locator) - self.selenium.scroll_element_into_view(locator) + self.salesforce.scroll_element_into_view(locator) element = self.selenium.driver.find_element_by_xpath(locator) try: self.selenium.get_webelement(locator).click() self.wait_for_locator("flexipage-popup") - self.selenium.scroll_element_into_view(option) + self.salesforce.scroll_element_into_view(option) self.selenium.click_element(option) except Exception: self.builtin.sleep(1, "waiting for a second and retrying click again") self.selenium.driver.execute_script("arguments[0].click()", element) self.wait_for_locator("flexipage-popup") - self.selenium.scroll_element_into_view(option) + self.salesforce.scroll_element_into_view(option) self.selenium.click_element(option) def click_related_list_wrapper_button(self, heading, button_title): - """ loads the related list and clicks on the button on the list """ + """loads the related list and clicks on the button on the list""" locator = outboundfunds_lex_locators["related"]["flexi_button"].format( heading, button_title ) @@ -207,3 +211,150 @@ def click_related_list_link(self, text): self.selenium.wait_until_page_contains_element(locator) element = self.selenium.driver.find_element_by_xpath(locator) self.selenium.driver.execute_script("arguments[0].click()", element) + + @capture_screenshot_on_error + def select_value_from_picklist(self, dropdown, value): + """Select given value in the dropdown field""" + locator = outboundfunds_lex_locators["new_record"]["dropdown_field"].format( + dropdown + ) + self.selenium.get_webelement(locator).click() + popup_loc = outboundfunds_lex_locators["new_record"]["dropdown_popup"] + self.selenium.wait_until_page_contains_element( + popup_loc, error="Picklist dropdown did not open" + ) + value_loc = outboundfunds_lex_locators["new_record"]["dropdown_value"].format( + value + ) + self.salesforce._jsclick(value_loc) + + def populate_new_record_form(self, **kwargs): + """Populate New Record Form with Key Value Pair""" + for key, value in kwargs.items(): + if key in ( + "Applying Contact", + "Applying Employee", + "Applying Organization", + "Funding Program", + "Assigned", + "Primary Contact", + "Assigned", + "Funding Request", + "Disbursement", + ): + locator = outboundfunds_lex_locators["new_record"][ + "lightning_lookup" + ].format(key) + self.check_if_element_exists(locator) + self.salesforce.scroll_element_into_view(locator) + self.selenium.set_focus_to_element(locator) + self.salesforce.populate_lookup_field(key, value) + elif key in ( + "Requested Amount", + "Awarded Amount", + "Recommended Amount", + "Funding Request Name", + "Funding Program Name", + "Total Program Amount", + "Description", + "Requirement Name", + ): + locator = outboundfunds_lex_locators["new_record"][ + "amount_field" + ].format(key) + self.check_if_element_exists(locator) + self.salesforce.scroll_element_into_view(locator) + self.selenium.get_webelement(locator).send_keys(value) + elif key in ( + "Awarded Date", + "Close Date", + "Awarded Date", + "Application Date", + "Start Date", + "End Date", + "Due Date", + "Completed Date", + ): + locator = outboundfunds_lex_locators["new_record"]["date_field"].format( + key + ) + self.selenium.set_focus_to_element(locator) + self.selenium.clear_element_text(locator) + self.selenium.get_webelement(locator).send_keys(value) + elif key in ("Status", "Geographical Area Served", "Type"): + locator = outboundfunds_lex_locators["new_record"][ + "dropdown_field" + ].format(key) + self.selenium.get_webelement(locator).click() + popup_loc = outboundfunds_lex_locators["new_record"]["dropdown_popup"] + self.selenium.wait_until_page_contains_element( + popup_loc, error="Picklist dropdown did not open" + ) + value_loc = outboundfunds_lex_locators["new_record"][ + "dropdown_value" + ].format(value) + self.salesforce._jsclick(value_loc) + else: + raise Exception(f"Field provided by name '{key}' does not exist") + + @capture_screenshot_on_error + def verify_toast_message(self, value): + """Verifies the toast message""" + locator = outboundfunds_lex_locators["toast_message"].format(value) + self.selenium.wait_until_element_is_visible(locator) + try: + close_locator = outboundfunds_lex_locators["toast_close"].format(value) + self.selenium.wait_until_page_contains_element(close_locator) + self.selenium.click_element(close_locator) + except Exception: + self.builtin.log("The toast could not be closed.", "WARN") + + def select_value_from_dropdown(self, dropdown, value): + """Select given value in the dropdown field""" + if dropdown in ("Role", "Status"): + locator = outboundfunds_lex_locators["funding_req_role"][ + "select_dropdown" + ].format(dropdown) + selection_value = outboundfunds_lex_locators["funding_req_role"][ + "select_value" + ].format(value) + self.salesforce._jsclick(locator) + self.selenium.click_element(selection_value) + + @capture_screenshot_on_error + def share_a_record(self): + """Click on Sharing link on Funding Request and Requirement Record""" + locator_sharing = outboundfunds_lex_locators["sharing"]["sharing_button"] + self.selenium.click_element(locator_sharing) + locator_sharing_link = outboundfunds_lex_locators["sharing"]["sharing_link"] + self.selenium.wait_until_page_contains_element( + locator_sharing_link, + error="'Sharing' option is not available in the list of actions", + ) + self.selenium.click_element(locator_sharing_link) + if self.latest_api_version == 52.0: + self.selenium.location_should_contain( + "recordShare?", + message="Current page is not Share", + ) + else: + pass + locator = outboundfunds_lex_locators["header_title"].format("Share") + self.selenium.wait_until_page_contains_element( + locator, error="The header for this page is not 'Share' as expected" + ) + user_locator = outboundfunds_lex_locators["sharing"]["search_user"] + set_user = self.selenium.driver.find_element_by_xpath(user_locator) + set_user.click() + time.sleep(1) + set_user.send_keys("PermsTestingUser RobotUser") + time.sleep(2) + set_user.send_keys(Keys.ENTER) + if self.latest_api_version == 52.0: + save_locator = outboundfunds_lex_locators["sharing"]["save_share"] + else: + save_locator = outboundfunds_lex_locators["funding_req_role"][ + "save_button_old" + ] + self.selenium.set_focus_to_element(save_locator) + self.selenium.click_element(save_locator) diff --git a/robot/OutboundFunds/resources/OutboundFunds.robot b/robot/OutboundFunds/resources/OutboundFunds.robot index f05e197b..beb4ceb0 100644 --- a/robot/OutboundFunds/resources/OutboundFunds.robot +++ b/robot/OutboundFunds/resources/OutboundFunds.robot @@ -64,6 +64,24 @@ API Create Funding Program &{fundingprogram} = Salesforce Get ${ns}Funding_Program__c ${funding_program_id} [Return] &{fundingprogram} +API Create Review on a Funding Request + [Documentation] Create a Review on a Funding Request via API + [Arguments] ${funding_request_id} &{fields} + ${ns} = Get Outfunds Namespace Prefix + ${review_name} = Generate New String + ${user_id} = API Get User Id of Permissions Test User + ${due_date} = Get Current Date result_format=%Y-%m-%d increment=30 days + ${review_id} = Salesforce Insert ${ns}Review__c + ... Name=${review_name} + ... ${ns}DueDate__c=${due_date} + ... ${ns}Status__c=In Progress + ... ${ns}FundingRequest__c=${funding_request_id} + ... ${ns}AssignedTo__c=${user_id} + ... &{fields} + &{review} = Salesforce Get ${ns}Review__c ${review_id} + Store Session Record ${ns}Review__c ${review_id} + [Return] &{review} + API Create Funding Request [Documentation] Create a Funding Request via API [Arguments] ${funding_program_id} ${contact_id} &{fields} @@ -84,18 +102,18 @@ API Create Funding Request API Create Requirement on a Funding Request [Documentation] Create a Requirement on a Funding Request via API - [Arguments] ${funding_request_id} ${contact_id} ${user_id} &{fields} - ${ns} = Get Outfunds Namespace Prefix + [Arguments] ${funding_request_id} &{fields} ${requirement_name} = Generate New String + ${ns} = Get Outfunds Namespace Prefix ${due_date} = Get Current Date result_format=%Y-%m-%d increment=30 days - ${requirement_id} = Salesforce Insert outfunds__Requirement__c + ${contact_id} = API Get Contact Id for Robot User Walker + ${requirement_id} = Salesforce Insert ${ns}Requirement__c ... Name=${requirement_name} ... ${ns}Primary_Contact__c=${contact_id} ... ${ns}Due_Date__c=${due_date} - ... ${ns}Assigned__c=${user_id} ... ${ns}Status__c=Open ... ${ns}Funding_Request__c=${funding_request_id} - ... ${ns}Type__c=Review + ... ${ns}Type__c=Letter of Intent ... &{fields} &{requirement} = Salesforce Get ${ns}Requirement__c ${requirement_id} Store Session Record ${ns}Requirement__c ${requirement_id} @@ -120,110 +138,26 @@ API Create Disbursement on a Funding Request Store Session Record ${ns}disbursement__c ${disbursement_id} [Return] &{disbursement} -Change Object Permissions - [Documentation] Adds or removes the Create, Read, Edit and Delete permissions - ... for the specified object on the specified permission set.. - [Arguments] ${action} ${objectapiname} ${permset} - - - ${removeobjperms} = Catenate SEPARATOR=\n - ... ObjectPermissions objperm; - ... objperm = [SELECT Id, PermissionsRead, PermissionsEdit, PermissionsCreate, - ... PermissionsDelete FROM ObjectPermissions - ... WHERE parentId IN ( SELECT id FROM permissionset WHERE PermissionSet.Name = '${permset}') - ... AND SobjectType='${objectapiname}']; - ... objperm.PermissionsRead = false; - ... objperm.PermissionsEdit = false; - ... objperm.PermissionsCreate = false; - ... objperm.PermissionsDelete = false; - ... update objperm; - - ${addobjperms} = Catenate SEPARATOR=\n - ... String permid = [SELECT id FROM permissionset WHERE PermissionSet.Name = '${permset}'].id; - ... ObjectPermissions objperm = New ObjectPermissions(PermissionsRead = true, - ... PermissionsEdit = true, PermissionsCreate = true, - ... PermissionsDelete = true, ParentId = permid, SobjectType='${objectapiname}'); - ... insert objperm; - - Run Keyword if "${action}" == "remove" - ... Run Task execute_anon - ... apex= ${removeobjperms} - - Run Keyword if "${action}" == "add" - ... Run Task execute_anon - ... apex= ${addobjperms} - -Change Field Permissions - [Documentation] Adds or removes the Create, Read, Edit and Delete permissions - ... for the specified object field on the specified permission set. - [Arguments] ${action} ${objectapiname} ${fieldapiname} ${permset} - - ${removefieldperms} = Catenate SEPARATOR=\n - ... FieldPermissions fldperm; - ... fldperm = [SELECT Id, Field, PermissionsRead, PermissionsEdit FROM FieldPermissions - ... WHERE parentId IN ( SELECT id FROM permissionset WHERE PermissionSet.Name = '${permset}') - ... AND SobjectType='${objectapiname}' - ... AND Field='${objectapiname}.${fieldapiname}']; - ... fldperm.PermissionsRead = false; - ... fldperm.PermissionsEdit = false; - ... update fldperm; - - ${addfieldperms} = Catenate SEPARATOR=\n - ... String permid = [SELECT id FROM permissionset WHERE PermissionSet.Name = '${permset}'].id; - ... FieldPermissions fldperm = New FieldPermissions(PermissionsRead = true, - ... PermissionsEdit = true, - ... ParentId = permid, Field = '${objectapiname}.${fieldapiname}', - ... SobjectType='${objectapiname}'); - ... insert fldperm; - - Run Keyword if "${action}" == "remove" - ... Run Task execute_anon - ... apex= ${removefieldperms} - - Run Keyword if "${action}" == "add" - ... Run Task execute_anon - ... apex= ${addfieldperms} - -Object Permissions Cleanup - [Documentation] Resets all object permissions in case a test fails - ... before they are restored. Skips the reset if the permissions - ... have already been added back. - [Arguments] ${objectapiname} ${permset} - - ${addobjback} = Catenate SEPARATOR=\n - ... List checkperms = [SELECT PermissionsRead FROM ObjectPermissions - ... WHERE parentId IN ( SELECT id FROM permissionset WHERE PermissionSet.Name = '${permset}') - ... AND - ... SobjectType = '${objectapiname}']; - ... if (checkperms.isEmpty()) { - ... String permid = [SELECT id FROM permissionset WHERE PermissionSet.Name = '${permset}'].id; - ... ObjectPermissions objperm = New ObjectPermissions(PermissionsRead = true, - ... PermissionsEdit = true, PermissionsCreate = true, - ... PermissionsDelete = true, ParentId = permid, SobjectType = '${objectapiname}'); - ... insert objperm; } - ... else { System.debug('Permissions Exist, skipping.'); } - - Run Task execute_anon apex=${addobjback} - -Field Permissions Cleanup - [Documentation] Resets all field permissions in case a test fails before they are restored. - ... Skips the reset if the permissions have already been added back. - [Arguments] ${objectapiname} ${fieldapiname} ${permset} - - ${ns} = Get Outfunds Namespace Prefix - - ${addfieldback} = Catenate SEPARATOR=\n - ... List checkperms = [SELECT PermissionsRead FROM FieldPermissions - ... WHERE parentId IN ( SELECT id FROM permissionset WHERE PermissionSet.Name = '${permset}') - ... AND - ... SobjectType = '${objectapiname}' AND Field = '${objectapiname}.${fieldapiname}']; - ... if (checkperms.isEmpty()) { - ... String permid = [SELECT id FROM permissionset WHERE PermissionSet.Name = '${permset}'].id; - ... FieldPermissions fldperm = New FieldPermissions(PermissionsRead = true, - ... PermissionsEdit = true, - ... ParentId = permid, Field = '${objectapiname}.${fieldapiname}', - ... SobjectType = '${objectapiname}'); - ... insert fldperm; } - ... else { System.debug('Permissions Exist, skipping.'); } - - Run Task execute_anon apex=${addfieldback} \ No newline at end of file +API Get User Id of Permissions Test User + [Documentation] Returns the ID of a User + [Arguments] &{fields} + ${result} = SOQL Query + ... SELECT Id FROM User where Email LIKE '%testingperms%' and IsActive=True + &{Id} = Get From List ${result['records']} 0 + [return] ${Id}[Id] + +API Get Contact Id for Robot User + [Documentation] Returns the ID of a Robot Test User + [Arguments] ${last_name} &{fields} + ${result} = API Get Id Contact LastName=${last_name} + [return] ${result} + +API Get Id + [Documentation] Returns the ID of a record identified by the given field_name + ... and field_value input for a specific object + [Arguments] ${obj_name} &{fields} + @{records} = Salesforce Query ${obj_name} + ... select=Id + ... &{fields} + &{Id} = Get From List ${records} 0 + [return] ${Id}[Id] \ No newline at end of file diff --git a/robot/OutboundFunds/resources/RequirementPageObject.py b/robot/OutboundFunds/resources/RequirementPageObject.py new file mode 100644 index 00000000..8298d1bc --- /dev/null +++ b/robot/OutboundFunds/resources/RequirementPageObject.py @@ -0,0 +1,30 @@ +from cumulusci.robotframework.pageobjects import ListingPage +from cumulusci.robotframework.pageobjects import DetailPage +from cumulusci.robotframework.pageobjects import pageobject +from BaseObjects import BaseOutboundFundsPage +from cumulusci.robotframework.utils import capture_screenshot_on_error + + +@pageobject("Listing", "Requirement__c") +class RequirementListingPage(BaseOutboundFundsPage, ListingPage): + @capture_screenshot_on_error + def _is_current_page(self): + """Verify we are on the Requirement Listing page + by verifying that the url contains '/view' + """ + self.selenium.location_should_contain( + "Requirement__c/list?", + message="Current page is not a Funding Program List view", + ) + + +@pageobject("Details", "Requirement__c") +class RequirementDetailPage(BaseOutboundFundsPage, DetailPage): + @capture_screenshot_on_error + def _is_current_page(self): + """Verify we are on the Requirement detail page + by verifying that the url contains '/view' + """ + self.selenium.wait_until_location_contains( + "/view", timeout=60, message="Detail page did not load in 1 min" + ) diff --git a/robot/OutboundFunds/resources/ReviewPageObject.py b/robot/OutboundFunds/resources/ReviewPageObject.py new file mode 100644 index 00000000..1ac96d3b --- /dev/null +++ b/robot/OutboundFunds/resources/ReviewPageObject.py @@ -0,0 +1,63 @@ +from cumulusci.robotframework.pageobjects import ListingPage +from cumulusci.robotframework.pageobjects import DetailPage +from cumulusci.robotframework.pageobjects import pageobject +from cumulusci.robotframework.pageobjects import BasePage +from BaseObjects import BaseOutboundFundsPage +from OutboundFunds import outboundfunds_lex_locators +from cumulusci.robotframework.utils import capture_screenshot_on_error + + +@pageobject("Listing", "Review__c") +class ReviewListingPage(BaseOutboundFundsPage, ListingPage): + def _is_current_page(self): + """Verify we are on the Review Listing page + by verifying that the url contains '/view' + """ + self.selenium.location_should_contain( + "/list?", + message="Current page is not a Review List view", + ) + + +@pageobject("Details", "Review__c") +class ReviewDetailPage(BaseOutboundFundsPage, DetailPage): + def _is_current_page(self): + """Verify we are on the Review detail page + by verifying that the url contains '/view' + """ + self.selenium.wait_until_location_contains( + "/view", timeout=60, message="Detail page did not load in 1 min" + ) + + +@pageobject("SubmitReview", "Review__c") +class SubmitReviewPage(BaseOutboundFundsPage, BasePage): + def _is_current_page(self): + """Verify we are on the Submit Review + by verifying that the url contains 'SubmitReview?' + """ + self.selenium.location_should_contain( + "SubmitReview?", + message="Current page is not Submit Review", + ) + locator = outboundfunds_lex_locators["new_record"]["edit_title"].format( + "Submit Review" + ) + self.selenium.wait_until_page_contains_element( + locator, error="The header for this page is not 'Submit Review' as expected" + ) + + @capture_screenshot_on_error + def submit_review(self): + if self.OutboundFunds.latest_api_version == 52.0: + footer_locator = outboundfunds_lex_locators["new_record"]["modal_footer"] + self.selenium.set_focus_to_element(footer_locator) + locator = outboundfunds_lex_locators["new_record"][ + "modal_footer_button" + ].format("Save") + self.selenium.set_focus_to_element(locator) + self.salesforce._jsclick(locator) + else: + locator = outboundfunds_lex_locators["funding_req_role"]["save_button_old"] + self.selenium.set_focus_to_element(locator) + self.selenium.get_webelement(locator).click() diff --git a/robot/OutboundFunds/resources/locators_50.py b/robot/OutboundFunds/resources/locators_50.py deleted file mode 100644 index 2af51ae8..00000000 --- a/robot/OutboundFunds/resources/locators_50.py +++ /dev/null @@ -1,6 +0,0 @@ -""" Locators for Winter '21 """ - -from locators_51 import outboundfunds_lex_locators -import copy - -outboundfunds_lex_locators = copy.deepcopy(outboundfunds_lex_locators) diff --git a/robot/OutboundFunds/resources/locators_51.py b/robot/OutboundFunds/resources/locators_51.py index e5fc8a89..fc917f07 100644 --- a/robot/OutboundFunds/resources/locators_51.py +++ b/robot/OutboundFunds/resources/locators_51.py @@ -1,54 +1,6 @@ -# Spring '21 locators -outboundfunds_lex_locators = { - "app_launcher": { - "view_all_button": "//button[text()='View All']", - "app_link": "//p[contains(@title,'{}')]", - "app_link_search_result": "//mark[contains(text(),'{}')]", - "search_input": "//input[contains(@placeholder,'Search apps or items...')]", - }, - "new_record": { - "label": "//label[text()='{}']", - "title": "//h2[contains(@class, 'inlineTitle') and text()='{}']", - "field_label": "//div[./*/*[text()='{}']]", - "edit_title": "//h2[contains(@class, 'title') and text()='{}']", - "list": "//div[contains(@class,'forcePageBlockSectionRow')]/div[contains(@class,'forcePageBlockItem')]/div[contains(@class,'slds-hint-parent')]/div[@class='slds-form-element__control']/div[.//span[text()='{}']][//div[contains(@class,'uiMenu')]//a[@class='select']]", - "text_field": "//div[contains(@class, 'uiInput')][.//label[contains(@class, 'uiLabel')][.//span[text()='{}']]]//*[self::input or self::textarea]", - "flexipage-list": '//lightning-combobox[./label[text()="{}"]]//input[contains(@class,"combobox__input")]', - "dd_selection": "//lightning-base-combobox-item[@data-value='{}']", - "button": "//button[contains(@class, 'slds-button') and text()='{}']", - "lookup_field": "//div[contains(@class, 'autocompleteWrapper')]//input[@title='{}']", - "lightning_lookup": "//label[text()='{}']/following-sibling::div//input", - "lookup_value": "//div[contains(@class, 'listContent')]//div[contains(@class, 'slds-truncate') and @title='{}']", - "checkbox": "//div[contains(@class,'uiInputCheckbox')]/label/span[text()='{}']/../following-sibling::input[@type='checkbox']", - "field_input": '//label[text()="{}"]/following-sibling::div//*[self::input or self::textarea]', - "open_date_picker": "//div[@class='slds-form-element__control']/div[.//span[text()='{}']]//div//a[contains(@class,'datePicker-openIcon display')]", - "datepicker_popup": "//table[@class='calGrid' and @role='grid']", - "select_date": "//div[contains(@class,'uiDatePickerGrid')]/table[@class='calGrid']//*[text()='{}']", - "text-field": "//label/span[text()='{}']/../following-sibling::input", - "footer_button": "//lightning-button//button[text()='{}']", - }, - "confirm": { - "check_value": "//div[contains(@class, 'forcePageBlockItem') or contains(@class, 'slds-form-element_stacked')][.//span[text()='{}']]//following-sibling::div[.//span[contains(@class, 'test-id__field-value')]]//*[text()='{}']", - "check_status": "//div[contains(@class, 'field-label-container')][.//span[text()='{}']]//following-sibling::div[.//span[contains(@class, 'test-id__field-value')]]/span//lightning-formatted-text[text()='{}']", - "check_numbers": "//div[contains(@class, 'field-label-container')][.//span[text()='{}']]//following-sibling::div[.//span[contains(@class, 'test-id__field-value')]]/span//lightning-formatted-number[text()='{}']", - }, - "tab": { - "tab_header": "//a[@class='slds-tabs_default__link' and text()='{}']", - "record_detail_tab": "//a[contains(@data-label,'{}')]", - "verify_header": "//div[contains(@class, 'entityNameTitle')]", - "verify_details": "//div[contains(@class, 'slds-form-element')][.//span[text()='{}']]//following-sibling::div[.//span[contains(@class, 'test-id__field-value')]]/span", - }, - "related": { - "title": '//div[contains(@class, "slds-card")]/header[.//span[@title="{}"]]', - "button": "//div[contains(@class, 'forceRelatedListSingleContainer')][.//img][.//span[@title='{}']]//a[@title='{}']", - "count": "//tbody/tr/td[1]", - "flexi_button": "//div[@lst-listviewmanagerheader_listviewmanagerheader][.//span[@title='{}']]//lightning-button//button[text()='{}']", - "flexi_link": "//a//span[text()='{}']", - }, - "details": { - "button": "//button[contains(@class, 'slds-button') and text() = '{}']", - "header": "//h1//div[contains(@class, 'entityNameTitle') and contains(text(),'{}')]", - }, - "link": "//a[contains(text(),'{}')]", - "flexipage-popup": "//div[contains(@class, 'slds-is-open')][contains(@class, 'slds-combobox')]", -} +""" Locators for Spring '21 """ + +from locators_52 import outboundfunds_lex_locators +import copy + +outboundfunds_lex_locators = copy.deepcopy(outboundfunds_lex_locators) diff --git a/robot/OutboundFunds/resources/locators_52.py b/robot/OutboundFunds/resources/locators_52.py new file mode 100644 index 00000000..b9e11a66 --- /dev/null +++ b/robot/OutboundFunds/resources/locators_52.py @@ -0,0 +1,78 @@ +# Summer '21 locators +outboundfunds_lex_locators = { + "app_launcher": { + "view_all_button": "//button[text()='View All']", + "app_link": "//p[contains(@title,'{}')]", + "app_link_search_result": "//mark[contains(text(),'{}')]", + "search_input": "//input[contains(@placeholder,'Search apps or items...')]", + }, + "new_record": { + "label": "//label[text()='{}']", + "title": "//h2[contains(@class, 'inlineTitle') and text()='{}']", + "field_label": "//div[./*/*[text()='{}']]", + "edit_title": "//h2[contains(@class, 'title') and text()='{}']", + "list": "//div[contains(@class,'forcePageBlockSectionRow')]/div[contains(@class,'forcePageBlockItem')]/div[contains(@class,'slds-hint-parent')]/div[@class='slds-form-element__control']/div[.//span[text()='{}']][//div[contains(@class,'uiMenu')]//a[@class='select']]", + "text_field": "//div[contains(@class, 'uiInput')][.//label[contains(@class, 'uiLabel')][.//span[text()='{}']]]//*[self::input or self::textarea]", + "flexipage-list": '//lightning-combobox[./label[text()="{}"]]//input[contains(@class,"combobox__input")]', + "dd_selection": "//lightning-base-combobox-item[@data-value='{}']", + "button": "//button[contains(@class, 'slds-button') and text()='{}']", + "lookup_field": "//div[contains(@class, 'autocompleteWrapper')]//input[@title='{}']", + "lightning_lookup": "//label[text()='{}']/following-sibling::div//input", + "lookup_value": "//div[contains(@class, 'listContent')]//div[contains(@class, 'slds-truncate') and @title='{}']", + "checkbox": "//div[contains(@class,'uiInputCheckbox')]/label/span[text()='{}']/../following-sibling::input[@type='checkbox']", + "field_input": '//label[text()="{}"]/following-sibling::div//*[self::input or self::textarea]', + "open_date_picker": "//div[@class='slds-form-element__control']/div[.//span[text()='{}']]//div//a[contains(@class,'datePicker-openIcon display')]", + "datepicker_popup": "//table[@class='calGrid' and @role='grid']", + "select_date": "//div[contains(@class,'uiDatePickerGrid')]/table[@class='calGrid']//*[text()='{}']", + "text-field": "//label/span[text()='{}']/../following-sibling::input", + "footer_button": "//lightning-button//button[text()='{}']", + "dropdown_field": "//lightning-combobox[./label[text()='{}']]/div//input[contains(@class,'combobox__input')]", + "dropdown_popup": "//div[contains(@class, 'slds-dropdown-trigger')]/div[contains(@class, 'slds-listbox')]", + "dropdown_value": "//div[contains(@class,'slds-listbox')]//lightning-base-combobox-item//span[text()='{}']", + "modal_footer_button": "//*[@id='wrapper-body']/footer/button/span[text()='{}']", + "modal_footer": "//footer[@class='slds-modal__footer']", + "amount_field": "//label[text()='{}']/..//*[self::input or self::textarea]", + "date_field": "//div[contains(@class,'slds-dropdown-trigger')][./label[text()='{}']]/div/input", + }, + "confirm": { + "check_value": "//div[contains(@class, 'forcePageBlockItem') or contains(@class, 'slds-form-element_stacked')][.//span[text()='{}']]//following-sibling::div[.//span[contains(@class, 'test-id__field-value')]]//*[text()='{}']", + "check_status": "//div[contains(@class, 'field-label-container')][.//span[text()='{}']]//following-sibling::div[.//span[contains(@class, 'test-id__field-value')]]/span//lightning-formatted-text[text()='{}']", + "check_numbers": "//div[contains(@class, 'field-label-container')][.//span[text()='{}']]//following-sibling::div[.//span[contains(@class, 'test-id__field-value')]]/span//lightning-formatted-number[text()='{}']", + }, + "tab": { + "tab_header": "//a[@class='slds-tabs_default__link' and text()='{}']", + "record_detail_tab": "//a[contains(@data-label,'{}')]", + "verify_header": "//div[contains(@class, 'entityNameTitle')]", + "verify_details": "//div[contains(@class, 'slds-form-element')][.//span[text()='{}']]//following-sibling::div[.//span[contains(@class, 'test-id__field-value')]]/span", + }, + "related": { + "title": '//div[contains(@class, "slds-card")]/header[.//span[@title="{}"]]', + "button": "//div[contains(@class, 'forceRelatedListSingleContainer')][.//img][.//span[@title='{}']]//a[@title='{}']", + "count": "//tbody/tr/td[1]", + "flexi_button": "//div[@lst-listviewmanagerheader_listviewmanagerheader][.//span[@title='{}']]//lightning-button//button[text()='{}']", + "flexi_link": "//a//span[text()='{}']", + }, + "details": { + "button": "//button[contains(@class, 'slds-button') and text() = '{}']", + "header": "//h1//div[contains(@class, 'entityNameTitle') and contains(text(),'{}')]", + }, + "funding_req_role": { + "select_value": "//li/a[text()='{}']", + "select_dropdown": "//div[contains(@class, 'uiInput')][.//span[contains(@class, 'inputLabel')]]//span[text()='{}']/../following-sibling::div//a[@class='select']", + "save_button": "//footer/button/span[text()='Save']", + "fr_link": "//div//a//span[contains(text(),'FR-')]", + "save_button_old": "//div[contains(@class, 'modal-footer')]//button/span[text()='Save']", + }, + "sharing": { + "sharing_link": "//a//span[contains(text(), 'Sharing')]", + "sharing_button": "//div[contains(@class, 'highlights slds-clearfix slds-page-header slds-page-header_record-home fixed-position')]//lightning-button-menu[contains(@class,'slds-dropdown-trigger')]/button[contains(@class, 'slds-button_icon-border-filled')]", + "search_user": "//label//span[text()='Search']/../../div//input", + "save_share": "//div[contains(@class, 'modal-footer')]//button[text()='Save']", + }, + "link": "//a[contains(text(),'{}')]", + "flexipage-popup": "//div[contains(@class, 'slds-is-open')][contains(@class, 'slds-combobox')]", + "header_title": "//h2[(contains(@class, 'inlineTitle') or contains(@class, 'slds-text-heading') or contains(@class, 'listTitle') or contains(@class, 'slds-hyphenate')) and contains(text(),'{}')]", + "object_button": "//div[contains(@class, 'slds-page-header')]//*[self::a[@title='Edit'] or self::button[@name='Edit']]", + "toast_message": "//div[contains(@class,'toastContent')]/child::div/span[contains(text(),\"{}\")]", + "toast_close": "//span[contains(@class, 'toastMessage') and text()=\"{}\"]/ancestor::div//button[@title='Close']", +} diff --git a/robot/OutboundFunds/resources/qa_org/users/perms_test_user.json b/robot/OutboundFunds/resources/qa_org/users/perms_test_user.json index d9c4a1a9..81133f13 100644 --- a/robot/OutboundFunds/resources/qa_org/users/perms_test_user.json +++ b/robot/OutboundFunds/resources/qa_org/users/perms_test_user.json @@ -1,6 +1,6 @@ { "FirstName": "PermsTestingUser", - "LastName": "ForDisbursement", + "LastName": "RobotUser", "Email": "testingperms@sfdx.org", "Alias": "permtest", "TimeZoneSidKey": "America/Los_Angeles", @@ -9,5 +9,5 @@ "LanguageLocaleKey": "en_US", "profileName": "Standard User", "generatePassword": true, - "permsets": ["Disbursements"] + "permsets": ["Disbursements", "SubmitReview"] } diff --git a/robot/OutboundFunds/resources/unpackaged/qa/package.xml b/robot/OutboundFunds/resources/unpackaged/qa/package.xml index 398a15a6..526e2a63 100644 --- a/robot/OutboundFunds/resources/unpackaged/qa/package.xml +++ b/robot/OutboundFunds/resources/unpackaged/qa/package.xml @@ -4,5 +4,9 @@ Disbursements PermissionSet + + SubmitReview + PermissionSet + 50.0 \ No newline at end of file diff --git a/robot/OutboundFunds/resources/unpackaged/qa/permissionsets/SubmitReview.permissionset-meta.xml b/robot/OutboundFunds/resources/unpackaged/qa/permissionsets/SubmitReview.permissionset-meta.xml new file mode 100644 index 00000000..4b09413f --- /dev/null +++ b/robot/OutboundFunds/resources/unpackaged/qa/permissionsets/SubmitReview.permissionset-meta.xml @@ -0,0 +1,241 @@ + + + + %%%NAMESPACE%%%Outbound_Funds + true + + + false + %%%NAMESPACE%%%Funding_Program__c.%%%NAMESPACE%%%Description__c + true + + + false + %%%NAMESPACE%%%Funding_Program__c.%%%NAMESPACE%%%End_Date__c + true + + + false + %%%NAMESPACE%%%Funding_Program__c.%%%NAMESPACE%%%Funding_Program_Manager__c + true + + + false + %%%NAMESPACE%%%Funding_Program__c.%%%NAMESPACE%%%Parent_Funding_Program__c + true + + + false + %%%NAMESPACE%%%Funding_Program__c.%%%NAMESPACE%%%Start_Date__c + true + + + false + %%%NAMESPACE%%%Funding_Program__c.%%%NAMESPACE%%%Status__c + true + + + false + %%%NAMESPACE%%%Funding_Program__c.%%%NAMESPACE%%%Top_Level__c + true + + + false + %%%NAMESPACE%%%Funding_Program__c.%%%NAMESPACE%%%Total_Program_Amount__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Application_Date__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Applying_Contact__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Applying_Employee__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Applying_Organization__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Awarded_Amount__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Awarded_Date__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Close_Date__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Closed_reason__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%FundingProgram__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Geographical_Area_Served__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Population_Served__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Recommended_Amount__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Requested_Amount__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Requested_For__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Status__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Term_End_Date__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Term_Start_Date__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Terms__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Total_Cancelled__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Total_Disbursed__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Total_Remaining__c + true + + + false + %%%NAMESPACE%%%Funding_Request__c.%%%NAMESPACE%%%Unpaid_Disbursements__c + true + + + false + %%%NAMESPACE%%%Review__c.%%%NAMESPACE%%%AssignedTo__c + true + + + true + %%%NAMESPACE%%%Review__c.%%%NAMESPACE%%%Comments__c + true + + + false + %%%NAMESPACE%%%Review__c.%%%NAMESPACE%%%DueDate__c + true + + + true + %%%NAMESPACE%%%Review__c.%%%NAMESPACE%%%FundingRequest__c + true + + + true + %%%NAMESPACE%%%Review__c.%%%NAMESPACE%%%Status__c + true + + + true + %%%NAMESPACE%%%Review__c.%%%NAMESPACE%%%SubmittedDate__c + true + + false + + + false + false + false + true + false + %%%NAMESPACE%%%Funding_Program__c + false + + + false + false + false + true + false + %%%NAMESPACE%%%Funding_Request__c + false + + + false + false + false + true + false + %%%NAMESPACE%%%Requirement__c + false + + + false + false + true + true + false + %%%NAMESPACE%%%Review__c + false + + + %%%NAMESPACE%%%Funding_Program__c + Visible + + + %%%NAMESPACE%%%Funding_Request__c + Visible + + + %%%NAMESPACE%%%Requirement__c + Visible + + + %%%NAMESPACE%%%Review__c + Visible + + diff --git a/robot/OutboundFunds/tests/browser/Disbursements/Disbursements.robot b/robot/OutboundFunds/tests/browser/Disbursements/Disbursements.robot index ce885db1..0674da91 100644 --- a/robot/OutboundFunds/tests/browser/Disbursements/Disbursements.robot +++ b/robot/OutboundFunds/tests/browser/Disbursements/Disbursements.robot @@ -45,6 +45,7 @@ Create Disbursement on a Funding Request click button Calculate Wait Until Element Is Visible text:Scheduled Date Save Disbursement + Verify Toast Message Disbursements Current Page Should Be Details Funding_Request__c Validate Field Value Unpaid Disbursements contains $80,000.00 Validate Field Value Available for Disbursement contains $20,000.00 \ No newline at end of file diff --git a/robot/OutboundFunds/tests/browser/FundingProgram/FundingProgram.robot b/robot/OutboundFunds/tests/browser/FundingProgram/FundingProgram.robot index aeff40ab..f2acb5de 100644 --- a/robot/OutboundFunds/tests/browser/FundingProgram/FundingProgram.robot +++ b/robot/OutboundFunds/tests/browser/FundingProgram/FundingProgram.robot @@ -1,5 +1,5 @@ *** Settings *** -Documentation Create a nw Funding Program +Documentation Create a new Funding Program Resource robot/OutboundFunds/resources/OutboundFunds.robot Library cumulusci.robotframework.PageObjects ... robot/OutboundFunds/resources/FundingProgramPageObject.py @@ -19,6 +19,10 @@ Setup Test Data ${fp_name} = Generate New String Set suite variable &{fundingprogram} Set suite variable ${fp_name} + ${date_1} = Get current date result_format=%m/%d/%Y increment=1 day + Set suite variable ${date_1} + ${date_2} = Get current date result_format=%m/%d/%Y increment=240 days + Set suite variable ${date_2} *** Test Case *** Create Funding Program Via API @@ -31,6 +35,7 @@ Create Funding Program Via API Click Link With Text ${fundingprogram}[Name] Wait Until Loading Is Complete Current Page Should Be Details Funding_Program__c + Validate Field Value Funding Program Name contains ${fundingprogram}[Name] Create Funding Program via UI in OutboundFunds [Documentation] Creates a Funding Program via UI. @@ -40,8 +45,14 @@ Create Funding Program via UI in OutboundFunds Capture Page Screenshot Click Object Button New Wait Until Modal Is Open - Populate Field Funding Program Name ${fp_name} - Populate Field Description Automated Robot Funding Program + Populate New Record Form Funding Program Name=${fp_name} + ... Status=In progress + ... Start Date=${date_1} + ... End Date=${date_2} + ... Description=Automated Robot Funding Program + ... Total Program Amount=500000 Click Save - Wait Until Modal Is Closed - Current Page Should Be Details Funding_Program__c \ No newline at end of file + Verify Toast Message Funding Program + Current Page Should Be Details Funding_Program__c + Validate Field Value Funding Program Name contains ${fp_name} + Validate Field Value Total Program Amount contains $500,000.00 diff --git a/robot/OutboundFunds/tests/browser/FundingRequest/FundingRequest.robot b/robot/OutboundFunds/tests/browser/FundingRequest/FundingRequest.robot index 22fd01ed..32ee10af 100644 --- a/robot/OutboundFunds/tests/browser/FundingRequest/FundingRequest.robot +++ b/robot/OutboundFunds/tests/browser/FundingRequest/FundingRequest.robot @@ -34,6 +34,14 @@ Setup Test Data Set suite variable ${fr_name} ${req_name} = Generate New String Set suite variable ${req_name} + ${date_1} = Get current date result_format=%m/%d/%Y increment=1 day + Set suite variable ${date_1} + ${contact_role} = API Create Contact + Store Session Record Contact ${contact_role}[Id] + Set suite variable ${contact_role} + +*** Variables *** +${test_user} permtest *** Test Case *** Create Funding Request Via API @@ -56,10 +64,48 @@ Create Funding Request via UI in Outbound Funds Go To Page Listing ${ns}Funding_Request__c Click Object Button New wait until modal is open - Populate Field Funding Request Name ${fr_name} - Populate Lookup Field Funding Program ${fundingprogram}[Name] - Populate Lookup Field Applying Contact ${contact}[Name] + Populate New Record Form Funding Request Name=${fr_name} + ... Funding Program=${fundingprogram}[Name] + ... Application Date=${date_1} + ... Status=Submitted + ... Geographical Area Served=State + ... Applying Contact=${contact}[Name] + ... Requested Amount=25000 Click Save - wait until modal is closed + Verify Toast Message Funding Request Current Page Should Be Details Funding_Request__c Validate Field Value Funding Request Name contains ${fr_name} + +Add New Funding Request Role + [Documentation] Add New Funding Request Role on a Funding Request + [tags] feature:FundingRequest feature:FundingRequestRole + Go To Page Listing ${ns}Funding_Request__c + Click Link With Text ${funding_request}[Name] + Wait Until Loading Is Complete + Current Page Should Be Details Funding_Request__c + Click Button Create Funding Request Role + Wait Until Modal Is Open + Populate Lookup Field Contact ${contact_role}[Name] + Select Value From Dropdown Status Current + Select Value From Dropdown Role Applicant + Save Funding Request Role + Verify Toast Message A new Funding Request Role has been created + Current Page Should Be Details Funding_Request__c + Click Funding Request Role link + Current Page Should Be Details Funding_Request_Role__c + Validate Field Value Status contains Current + +Share a Funding Request + [Documentation] Creates a Funding Request via API and Share + ... Verifies that Funding Request is created and + ... Share Funding Request + [tags] feature:FundingRequest + Go To Page Details Funding_Request__c object_id=${funding_request}[Id] + Share A Record + Close Browser + Open test browser useralias=${test_user} + Go To Page Details Funding_Request__c object_id=${funding_request}[Id] + Validate Field Value Status contains In progress + Validate Field Value Funding Request Name contains + ... ${funding_request}[Name] + Page Should Not Contain Element OutboundFunds:object_button diff --git a/robot/OutboundFunds/tests/browser/Requirements/Requirements.robot b/robot/OutboundFunds/tests/browser/Requirements/Requirements.robot index 3a4200a4..7357c074 100644 --- a/robot/OutboundFunds/tests/browser/Requirements/Requirements.robot +++ b/robot/OutboundFunds/tests/browser/Requirements/Requirements.robot @@ -3,6 +3,7 @@ Documentation Create a Requirement on a Funding Request. Resource robot/OutboundFunds/resources/OutboundFunds.robot Library cumulusci.robotframework.PageObjects ... robot/OutboundFunds/resources/FundingRequestPageObject.py +... robot/OutboundFunds/resources/RequirementPageObject.py ... robot/OutboundFunds/resources/OutboundFunds.py Suite Setup Run keywords @@ -12,7 +13,7 @@ Suite Teardown Capture Screenshot And Delete Records And Close Browser *** Keywords *** Setup Test Data - [Documentation] Create data to run tests + [Documentation] Create data to run tests ${ns} = Get Outfunds Namespace Prefix Set Suite Variable ${ns} ${fundingprogram} = API Create Funding Program @@ -28,12 +29,21 @@ Setup Test Data Set suite variable ${funding_request} ${req_name} = Generate New String Set suite variable ${req_name} + ${req}= API Create Requirement on a Funding Request ${funding_request}[Id] + Set suite variable ${req} + ${date} = Get current date result_format=%m/%d/%Y increment=60 days + Set suite variable ${date} + +*** Variables *** +${test_user} permtest + + *** Test Case *** Add a Requirement on a Funding Request - [Documentation] Creates a Funding Request via API. + [Documentation] Creates a Funding Request via API, add a requirement. ... Go to Requirements and add a new Requirement - [tags] feature:FundingRequest Requirements + [tags] feature:FundingRequest feature:Requirements Go To Page Listing ${ns}Funding_Request__c Click Link With Text ${funding_request}[Name] Wait Until Loading Is Complete @@ -41,10 +51,24 @@ Add a Requirement on a Funding Request Click Tab Requirements click related list wrapper button Requirements New Wait For Modal New Requirement - Populate Field Requirement Name ${req_name} - Populate Lookup Field Primary Contact ${contact}[Name] + Populate New Record Form Requirement Name=${req_name} + ... Primary Contact=${contact}[Name] + ... Type=Letter of Intent + ... Due Date=${date} + ... Status=Open + ... Assigned=PermsTestingUser RobotUser Click Save - wait until modal is closed + Verify Toast Message Requirement Click Related List Link ${req_name} Validate Field Value Requirement Name contains ${req_name} Validate Field Value Primary Contact contains ${contact}[Name] + +Share a Requirement + [Documentation] Share a Requirement. + [tags] feature:Requirements feature:sharing + Go To Page Details Requirement__c object_id=${req}[Id] + Share A Record + Close Browser + Open test browser useralias=${test_user} + Go To Page Details Requirement__c object_id=${req}[Id] + Page Should Not Contain Element OutboundFunds:object_button diff --git a/robot/OutboundFunds/tests/browser/Review/Review.robot b/robot/OutboundFunds/tests/browser/Review/Review.robot new file mode 100644 index 00000000..b159ce9b --- /dev/null +++ b/robot/OutboundFunds/tests/browser/Review/Review.robot @@ -0,0 +1,84 @@ +*** Settings *** +Documentation Create a Review on a Funding Request. +Resource robot/OutboundFunds/resources/OutboundFunds.robot +Library cumulusci.robotframework.PageObjects +... robot/OutboundFunds/resources/FundingRequestPageObject.py +... robot/OutboundFunds/resources/ReviewPageObject.py +... robot/OutboundFunds/resources/OutboundFunds.py + +Suite Setup Run keywords +... Open Test Browser +... Setup Test Data +Suite Teardown Capture Screenshot And Delete Records And Close Browser + +*** Keywords *** +Setup Test Data + [Documentation] Create data to run tests + ${ns} = Get Outfunds Namespace Prefix + Set Suite Variable ${ns} + ${fundingprogram} = API Create Funding Program + Set suite variable ${fundingprogram} + ${contact} = API Create Contact + Store Session Record Contact ${contact}[Id] + Set suite variable ${contact} + ${funding_request} = API Create Funding Request ${fundingprogram}[Id] + ... ${contact}[Id] + ... ${ns}Status__c=In Progress + ... ${ns}Awarded_Amount__c=100000 + Store Session Record ${ns}Funding_Request__c ${funding_request}[Id] + Set suite variable ${funding_request} + &{review} = API Create Review on a Funding Request + ... ${funding_request}[Id] + Set Suite Variable &{review} + ${review_name1} = Generate New String + Set suite variable ${review_name1} + ${review_name2} = Generate New String + Set suite variable ${review_name2} + +*** Test Case *** +Create Review Via API + [Documentation] Creates a Review via API. + ... Verifies that Review is created + [tags] feature:Review + Go To Page Listing ${ns}Review__c + Capture Page Screenshot + Click Link With Text ${review}[Name] + Wait Until Loading Is Complete + Current Page Should Be Details Review__c + +Add a Review on a Funding Request + [Documentation] Creates a Funding Request via API. + ... Go to Reviews and add a new Review + [tags] feature:Review + Go To Page Listing ${ns}Funding_Request__c + Click Link With Text ${funding_request}[Name] + Wait Until Loading Is Complete + Current Page Should Be Details Funding_Request__c + Click Tab Reviews + Click Related List Wrapper Button Reviews New + Wait For Modal New Review + Populate Field Review Name ${review_name1} + Click Save + Wait Until Modal is Closed + Current Page Should Be Details Funding_Request__c + Click Tab Reviews + # validtes column names + Page Should Contain Element //span[@title='Review Name'] + Page Should Contain Element //span[@title='Status'] + Page Should Contain Element //span[@title='Assigned To'] + Page Should Contain Element //span[@title='Due Date'] + Click Related List Link ${review_name1} + Validate Field Value Review Name contains ${review_name1} + +Create a Review via Review Object Tab + [Documentation] Creates a Review via the Review object tab + [tags] feature:Review + Go To Page Listing ${ns}Review__c + Click Object Button New + Wait For Modal New Review + Populate Field Review Name ${review_name2} + Populate Lookup Field Funding Request ${funding_request}[Name] + Click Save + Wait Until Modal Is Closed + Current Page Should Be Details Review__c + Validate Field Value Review Name contains ${review_name2} diff --git a/robot/OutboundFunds/tests/browser/Review/SubmitReview.robot b/robot/OutboundFunds/tests/browser/Review/SubmitReview.robot new file mode 100644 index 00000000..92d4fdb8 --- /dev/null +++ b/robot/OutboundFunds/tests/browser/Review/SubmitReview.robot @@ -0,0 +1,62 @@ +*** Settings *** +Documentation Create a Review on a Funding Request. +Resource robot/OutboundFunds/resources/OutboundFunds.robot +Library cumulusci.robotframework.PageObjects +... robot/OutboundFunds/resources/FundingRequestPageObject.py +... robot/OutboundFunds/resources/ReviewPageObject.py +... robot/OutboundFunds/resources/OutboundFunds.py + +Suite Setup Run keywords +... Open test browser +... Setup Test Data +Suite Teardown Capture Screenshot And Delete Records And Close Browser + +*** Variables *** +${test_user} permtest + +*** Keywords *** +Setup Test Data + [Documentation] Create data to run tests + ${ns} = Get Outfunds Namespace Prefix + Set Suite Variable ${ns} + ${fundingprogram} = API Create Funding Program + Set suite variable ${fundingprogram} + ${contact} = API Create Contact + Store Session Record Contact ${contact}[Id] + Set suite variable ${contact} + ${funding_request} = API Create Funding Request ${fundingprogram}[Id] + ... ${contact}[Id] + ... ${ns}Status__c=Not Started + ... ${ns}Awarded_Amount__c=100000 + Store Session Record ${ns}Funding_Request__c ${funding_request}[Id] + Set suite variable ${funding_request} + &{review} = API Create Review on a Funding Request + ... ${funding_request}[Id] + Set Suite Variable &{review} + ${submitted_date} = Get current date result_format=%m/%d/%Y + Set suite variable ${submitted_date} + Close Browser + +*** Test Case *** +Submit a Review + [Documentation] Submit a Review + [tags] feature:Review + Open Test Browser useralias=${test_user} + ${today} = Get current date result_format=%-m/%d/%Y + Go To Page Details Review__c + ... object_id=${review}[Id] + Current Page Should Be Details Review__c + Click Button Edit + Wait until modal is open + Select Value from Picklist Status In Progress + Click Save + Verify Toast Message Review + Current Page Should Be Details Review__c + Validate Field Value Status contains In Progress + Click Button Submit Review + Wait until modal is open + Current page should be SubmitReview Review__c + Submit Review + Verify Toast Message Review submitted. + Current Page Should Be Details Review__c + Validate Field Value Status contains Submitted diff --git a/robot/OutboundFunds/tests/standard_objects/create_contact.robot b/robot/OutboundFunds/tests/standard_objects/create_contact.robot index ab6d5855..2d041413 100644 --- a/robot/OutboundFunds/tests/standard_objects/create_contact.robot +++ b/robot/OutboundFunds/tests/standard_objects/create_contact.robot @@ -1,45 +1,59 @@ *** Settings *** Documentation Create a new Contact via API and UI. -Resource cumulusci/robotframework/Salesforce.robot +Resource robot/OutboundFunds/resources/OutboundFunds.robot +Library cumulusci.robotframework.PageObjects +... robot/OutboundFunds/resources/ContactPageObject.py Suite Setup Open Test Browser Suite Teardown Delete Records and Close Browser *** Test Cases *** Via API - [Documentation] Create a Contact via API ${first_name} = Generate Random String ${last_name} = Generate Random String ${contact_id} = Salesforce Insert Contact ... FirstName=${first_name} ... LastName=${last_name} + &{contact} = Salesforce Get Contact ${contact_id} Validate Contact ${contact_id} ${first_name} ${last_name} Via UI - [Documentation] Create a Contact via UI ${first_name} = Generate Random String ${last_name} = Generate Random String - Go To Object Home Contact + + Go To Page Home Contact Click Object Button New + Wait For Modal New Contact + Populate Form ... First Name=${first_name} ... Last Name=${last_name} Click Modal Button Save + Wait Until Modal Is Closed + ${contact_id} = Get Current Record Id Store Session Record Contact ${contact_id} Validate Contact ${contact_id} ${first_name} ${last_name} + *** Keywords *** Validate Contact [Arguments] ${contact_id} ${first_name} ${last_name} - [Documentation] Validate via UI and API + [Documentation] + ... Given a contact id, validate that the contact has the + ... expected first and last name both through the detail page in + ... the UI and via the API. + # Validate via UI - Go To Record Home ${contact_id} - Page Should Contain ${first_name} ${last_name} + Go To Page Detail Contact ${contact_id} + Page Should Contain ${first_name} ${last_name} + # Validate via API &{contact} = Salesforce Get Contact ${contact_id} - Should Be Equal ${first_name} &{contact}[FirstName] - Should Be Equal ${last_name} &{contact}[LastName] + Should Be Equal ${first_name} ${contact}[FirstName] + Should Be Equal ${last_name} ${contact}[LastName] + Should Be Equal ${first_name} ${contact}[FirstName] + Should Be Equal ${last_name} ${contact}[LastName]