[APER-1968]
We don't have a good way to understand if grade data in Credentials is out of sync with the LMS. Grades are sent to Credentials via a REST API call originating from an asynchronous Celery task on the LMS side. This PR updates our Celery task `send_grade_to_credentials` to include sending the `modified` DateTime value of a grade record to the Credentials IDA. Updates will be made on the Credentials side to accept and store this data as part of the UserGrade instance.
* Updates the `send_grade_to_credentials` task to include passing the grade's `modified` DateTime info as part of the request data to Credentials
* Updates the `CourseGradeBase` class to include an optional `last_updated` field. This will store the `modified` date of a PersistentCourseGrade instance when a grade is read through the CourseGradeFactory.
* Update existing log statement to use format strings where possible.
Fix for an error related to endless recursion
Dev Notes:
The student gets the passing grade
-> CourseGradeFactory sends the `COURSE_GRADE_NOW_PASSED` signal after the grade calculation
-> `listen_for_passing_grade` receives the signal and calls `generate_certificate_task`
-> `generate_certificate_task` calls `_generate_regular_certificate_task`
-> `_generate_regular_certificate_task` trying to get grade by calling the `_get_course_grade`
-> `_get_course_grade` calls `CourseGradeFactory().read()` but I have persistent grades off, so actually that ends with `CourseGradeFactory().update()`
-> `CourseGradeFactory().update()` sends the `COURSE_GRADE_NOW_PASSED`
And so on
Previously, the course grade returned would be the stored grade,
which is calculated for all content, not just the visible grades.
(Some grades are not yet released to the learner.)
This fix recalculates the overall grade before sending to the MFE,
so that it doesn't have to recompute it itself (without all the
particular logic that the platform uses when grading).
AA-1217
After executing python-modernize and isort, few changes
occurred in import sequence as well as unicode func is
replaced by six.text_type func.
INCR-439