How to notify users their connected time to a course since begining - moodle

I want to know if there is a plugin or somehow to notify via email to moodle users if they have not connected since xxxx date to complete a course.
Is there a way to make this automatically via cron or so?
Thanks.

You're question is a 2 in 1. You're asking how to identify users who haven't signed on in a while, and how to email them. I'm going to answer in parts accordingly. All of this can be accomplished via cron, but I don't use Moodle so I don't know what plugins are available to you.
He's an example of a query that would identify users who haven't logged on in 180 days (but it will ignore those who have never logged in).
SELECT * FROM mdl_user
WHERE lastlogin < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 180 DAY))
AND lastlogin != 0
AND lastaccess < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 180 DAY))
AND deleted = 0
Now for the email bit. Per Google, Moodle uses the PHPMailer for it's email_to_user() function. An example of using this in PHP:
email_to_user($toUser, $fromUser, $subject, $messageText, $messageHtml, '', '', true);
$toUser and $fromUser should be Moodle user objects, not email addresses. Traversing your query results to build these objects would be all that's left to do.
Last tip: To get a user object based on each result of your query, you can use the get_record function like so:
$userObj = get_record("user", "id", $userID);

Related

How to send email with the list of all people - Power Automate

There are some tutorials that explain how to email someone on their birthday. What I am looking for is to send a single email with the list of all the people who celebrate their birthday that day.
I would like to know how I can send in the body of the email the name of the people who celebrate their birthday on that day.
I have been working on a flow with each of the following steps:
Recurrence:
With this step I send my daily mail every certain hour.
Get items:
I created a sharepoint list where I have the name of the birthday boy, date of birthday (DOB), gender and department.
Initialize variable:
Apply to each
Append to string variable
I add to the Birthdays variable the value that would be the name of the employee whose birthday is that day that is in the sharepoint list
Send an email
In the step of sending an email, I add the previously initialized variable "Birthdays" to the body of the email, which should contain the list of employees whose birthday is that day
I have supported myself with this question made in the Microsoft Power Automate forum but it does not work as it should since I am new to power automate
Error:
At the moment of executing my manual flow I get in the condition as a result false in addition to two errors when I add the variable and send the mail
Can someone give me an orientation in knowing what I am doing wrong in the flow since my mail does not arrive either.
UPDATE:
The value of the Birthdays variable at runtime is as follows:
UPDATE 2:
I have added in Filter Query the following expression formatDateTime(utcNow(),'dd-MM-yyyy') eq 'listColumn' but when executing the manual flow I get that The expression "28-01-2022 eq 'listColumn'" does not It is valid.
Annex error that shows me in the execution of the manual test
UPDATE 3:
The column in the sharepoint list where I am storing the birthday date is called DOB:
Get Items action you should use Filter Query row to search something like: formatDateTime(utcNow(),'dd-MM-yyyy') eq 'listColumn'.(You should have a column in sharepoint containing all user birthdays).
[1]: https://i.stack.imgur.com/Y3s4S.png
Append to String all the emails that you get from GetItems: Email;
Try this one; it should work:
Birthdays eq '#{formatDateTime(utcNow(), 'yyyy-MM-dd')}'

First Access date or Enrolled date for a specific course

I would really appreciate any help with this dilemma !
I need a report that just lists out the exact date when a user has enrolled into a specific course (or First access). i.e. if the user is enrolled in two courses on the site on two different dates, I need the exact date when the user commenced each course. (either enrolled or access)
I believe the role assignment date for the specific course should do the trick, but how do I get the 'role assigned' date for all users of a course ?
I tried setting up a SQL query as below. It gives me the list of users, the courses they are enrolled into etc.
However, it is giving me the same creation / access date for all the course - which is the site level date. How do I get the course level start or role assignment date ?
I would really appreciate any help. I am really at my wits end !
user2.firstname AS Firstname,
user2.lastname AS Lastname,
user2.email AS Email,
user2.city AS City,
DATE_FORMAT(FROM_UNIXTIME(user2.firstaccess), '%Y-%m-%d %H:%i') AS 'Firstaccess',
DATE_FORMAT(FROM_UNIXTIME(user2.timecreated), '%Y-%m-%d %H:%i') AS 'Timecreated',
course.fullname AS Course
,(SELECT shortname FROM prefix_role WHERE id=en.roleid) AS ROLE
,(SELECT name FROM prefix_role WHERE id=en.roleid) AS RoleName
FROM prefix_course AS course
JOIN prefix_enrol AS en ON en.courseid = course.id
JOIN prefix_user_enrolments AS ue ON ue.enrolid = en.id
JOIN prefix_user AS user2 ON ue.userid = user2.id
Moodle version 3.5 -
You cannot get first course access in moodle 3+. This action is not logged anymore, you can only get last access.
As for enrolment time (TimeCreated), try this:
SELECT u.username, u.lastname, u.firstname, c.fullname, DATE_FORMAT(FROM_UNIXTIME(ue.timecreated), '%Y-%m-%d %H:%i') AS 'Timecreated' FROM prefix_user_enrolments ue LEFT JOIN prefix_enrol e ON (ue.enrolid = e.id) LEFT JOIN prefix_course c ON (e.courseid = c.id) LEFT JOIN prefix_user u ON (ue.userid = u.id)
First access actually makes no sense, since enrolment time will always be the earliest date between two. Even if user uses self-enrolment. Guest course access is probably the only exception, but it doesn't require user id, so it will make your report inconsistent anyway. So 99% of the time you would want to check upon user enrolments exactly, and the earliest date is always enrolment time.
If your moodle version is less than 3, you may get first access via prefix_log
You can retrieve the first access to the course by querying the mdl_logstore_standard_log for the event "\core\event\course viewed" eventname.
SELECT * FROM mdl_logstore_standard_log
WHERE eventname LIKE "%course_viewed%"
AND userid=##
timecreated is the specific field you're looking for
If a user is not enrolled in the course and they view the enrollment page (for that course), the course viewed event is not fired. So you shouldn't get any false positives.

Staff availability form in FileMaker

I'm have trouble coming up with a solution to a staff availability form, for a live event facility.
The goal is to have someone in the office select start and end dates, which generates a list of upcoming events. This list will be seen by employees on WebDirect, and they will be able to mark whether they are available or not via checkbox. The people in the office will then be able to see who is available for the all upcoming events while scheduling.
The idea behind choosing the start and end date is so the office can selectively "publish" which dates the employees see, as well as having a log of all responses tied to that form.
I also want to limit the employee to only be able to see their responses to the form.
So far I have tables as follows:
Employee Event Availability Form Response
-------- ----- ------------ ---- --------
ID ID ID ID ID
Name Date StartDate fk_AvailabilityID fk_EmployeeID
Title EndDate fk_ResponseID Checkbox
All of the relationships are primary key = foreign key except Event Date has a relationship to Availability:
Date ≥ StartDate AND
Date ≤ EndDate
Not really sure where to go past this or if this even is correct to begin with. I've experimented with a FormResponse table but not really sure what connections to make.
I'm fairly new to FileMaker and Databases in general, so laymens terms would be appreciated.
For starters, instead of convoluted relationships, you could use a field in the event table as a publish flag and then perform a search for that in web direct upon login.
When the staff sets a start/end date, they run a script that sets the publish flag for these records only.
To match the logged in user to an employee, you would need to store the account name in the employee table and match these upon login. Then set the privileges such that records can only be viewed when there is a match.
Hope this helps.

Grouping By with missing data

Image of Data and desired result:
I'm trying to aggregate volunteer hours from a Google spreadsheet a non-profit I volunteer for. We collect volunteer e-mail information and the time that each volunteer has contributed. Each volunteer only puts in their e-mail the first time. I've found examples online on how to send e-mails, but I'm having trouble aggregating the data. I think the trouble might be that not every row has an e-mail address associated with it.
I've been able to get the sum of hours worked by volunteer using QUERY(data, "select A, sum(C) Group By A", ) but can't figure out how to get the e-mail associated with each individual.
Thanks for the advice! The VLOOKUP and ArrayFormula functions were new to me. Here's how I solved it:
QUERY(data, "select A, B where B <>'' ", -1)
This allowed me to get the Key-Value pair (Name, Email) for each volunteer (solving the problem of people who volunteered multiple times, but only left their e-mail once). From there, I was able to generate the 'Name:Hours Worked' table off to the right with:
QUERY(data, "select A, sum(C) Group By A", ).
Then, I used VLOOKUP to query my Name-Email table to get the desired result of:
Name-Email-aggregatedHours
Thanks!
You can't achieve this with query. But you could apply vlookup to sorted table:
=ArrayFormula(VLOOKUP(UNIQUE(FILTER(A2:A,A2:A<>"")),SORT(A2:B,2,0),2,0))
and get email list for unique names.
First, clean up your data. You shoud be certain that at least one column has no typos an that this column appropiate identify which data corresponds to each volunteer. This is called key value. This also could be done by, but not limited to, filling up the missing values for each row. If this will be hard, then
Create a volunteer list without missing data.
Calculate the time contributed by each volunteer. If you was able to fill up the missing values, then you could use QUERY, I this case the QUERY formula should have to group by name and email, if not, then use SUMIF

Automatic email dependant on date in Microsoft Access

I'm currently creating a database for my work that consists of basic information on the company car fleet. I've created the database and front sheet which consists of variables such as car,c ar color, MOT Date, Tax Date, etc.
I need to somehow have Access detect when a company car's MOT date is due and email someone to notify them that the date is upcoming by comparing today's date with the date entered into the MOT date field.
Something like, if today's date is a week prior to the MOT date, send an email to whoever to notify them that this is due.
I need this to happen automatically, I plan to open and refresh the sheet daily so it doesn't need to be particularly fancy and do it without Access being open, I just need it to perform this task without trawling through pages and pages of data.
You can do this on launch. Just write a query that picks the records you want. Then loop through the query and fire off an email to each person, then make sure you have a field called "EmailSent" that you'll update to True so you don't send them an email the following day (assuming you just want to email them once).
You'll probably just want some VBA along these lines:
Dim db as Database
Dim rec as Recordset
Set db = CurrentDB
Set rec = db.OpenRecordset("SELECT * FROM MyQueryName")
Do while rec.EOF = False
'Loop through each record, send them an email
'Add code to send email here
rec.MoveNext
'Now update the table so these guys don't get emailed again
dim MySQL as String
MySQL = "UPDATE MyQueryName SET EmailSent = 'True'"
DoCmd.RunSQL MySQL
The above is all "aircode" and is untested, but should set you in the right direction.
Just make sure EmailSent = False is a condition in your query.