First Access date or Enrolled date for a specific course - moodle

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.

Related

Getting percentage of breaching SLA tickets

I have table where I have data of zendesk tickets with all the SLA details.
For instance, with this table I can write a query like below to see where a particular service ticket has breached the SLA or not.
case when m.reply_time_in_minutes.[calendar] > 120 then 'Yes' else 'No' end as 'fr_sla_breach'
If I want to get a percentage of breach for each person, how can I approach this.
I am not developer, but If you guys show some way to think I can develop it.
The O/P of the data will look like below:
person
ticket id
fr_sla_breach
Person A
1234
yes
Person B
3453
no
This is the result I am able to get. But If I want to get the below O/P , how can i go about it.
person
fr_sla_breach_percentage
Person A
50%
I can able to see for a particualr person how many were breaching SLA and how many are not. But If I want to figure out the percentage, not sure how to approach it.
Complete Query:
SELECT assignee_name,
'https://hevodata.zendesk.com/agent/tickets/'|| t.id AS URL,
t.created_at,
m.solved_at,
m.initially_assigned_at,
CASE
WHEN m.reply_time_in_minutes.[calendar] > 120 THEN 'Yes'
ELSE 'No'
END AS "fr_sla_breach"
FROM tickets t
JOIN ticket_metrics m ON t.id = m.ticket_id
WHERE date(t.created_at) BETWEEN 'MM/DD/YYYY' AND 'MM/DD/YYYY'
AND t.assignee_name LIKE ('XXX%')

Compare 2 Tables When 1 Is Null in PostgreSQL

List item
I am kinda new in PostgreSQL and I have difficulty to get the result that I want.
In order to get the appropriate result, I need to make multiple joins and I have difficulty when counting grouping them in one query as well.
The table names as following: pers_person, pers_position, and acc_transaction.
What I want to accomplish is;
To see who was absent on which date comparing pers_person with acc_transaction for any record, if there any record its fine... but if record is null the person was definitely absent.
I want to count the absence by pers_person, how many times in month this person is absent.
Also the person hired_date should be considered, the person might be hired in November in October report this person should be filtered out.
pers_postition table is for giving position information of that person.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SELECT tr.create_time::date AS Date, pers.pin, tr.dept_name, tr.name, tr.last_name, pos.name, Count(*)
FROM acc_transaction AS tr
RIGHT JOIN pers_person as pers
ON tr.pin = pers.pin
LEFT JOIN pers_position as pos
ON pers.position_id=pos.id
WHERE tr.event_no = 0 AND DATE_PART('month', DATE)=10 AND DATE_PART('month', pr.hire_date::date)<=10 AND pr.pin IS DISTINCT FROM tr.pin
GROUP BY DATE
ORDER BY DATE
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
*This is report for octeber,
*Pin is ID number
I'd start by
changing the RIGHT JOIN for a LEFT JOIN as they works the same in reverse but it's confusing to figure them both in mind :
removing for now the pers_position table as it is used for added information purpose rather than changing any returned result
there is an unknown alias pr and I'd assume it is meant for pers (?), changing it accordingly
that leads to strange WHERE conditions, removing them
"pers.pin IS DISTINCT FROM pers.pin" (a field is never distinct from itself)
"AND DATE_PART('month', DATE)=10 " (always true when run in october, always false otherwise)
Giving the resulting query :
SELECT tr.create_time::date AS Date, pers.pin, tr.dept_name, tr.name, tr.last_name, Count(*)
FROM pers_person as pers
LEFT JOIN acc_transaction AS tr ON tr.pin = pers.pin
WHERE tr.event_no = 0
AND DATE_PART('month', pers.hire_date::date)<=10
GROUP BY DATE
ORDER BY DATE
At the end, I don't know if that answers the question, since the title says "Compare 2 Tables When 1 Is Null in PostgreSQL" and the content of the question says nothing about it.

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.

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

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);

MicroStrategy - Dynamic Attribute with join

In our MicroStrategy 9.3 environment, we have a star schema that has multiple date dimensions. For this example, assume we have a order_fact table has two dates, order_date and ship_date and an invoice_fact table with two dates invoice_date and actual_ship_date. We have a date dimension that has "calendar" related data. We have setup each date with an alias, per the MicroStrategy Advanced Data Warehousing guide, which is MicroStrategy's recommended approach to handling role-playing dimensions.
Now for the problem. The aliased dates allow for users to create reports specific to the date that has been aliased. However, since the dates have been aliased, MicroStrategy won't combine "dates" as they appear to it to be different. Case in point, I can't easily put on a report that shows order quantities and invoice quantities by order_date and invoice_date as it results in a cross join.
The solution we have been talking about internally, is creating a new attribute called order_fact_date and an invoice_fact_date. These dates would be determined at runtime via the psuedo code below:
case when <user picked date> = 'order date'
then order_date
else ship_date end as order_fact_date
case when <user picked date> = 'invoice date'
then invoice_date
else actual_ship_date as invoice_fact_date
Our thinking was then, we could have a "general" date dimension mapped to both dates which would enable MicroStrategy to leverage the same table in the joins and thereby eliminating the cross join issue.
Clear as mud?
Edit 1: Changed "three dates" to "two dates".
if I have understood correctly your problem, you have created multiple dates attributes (with different logical meaning) and they are mapped on different aliases of the calendar table.
Until users use different a single fact table in their reports there is no problem, but when they use metrics/facts from sales and invoices you have multiplied results because "Order Date" and "Invoice Date" are different attributes.
Your SQL looks something like:
...
FROM order_fact a11
INNER JOIN invoice_fact a12
INNER JOIN lu_calendar a13
ON a11.order_date = a13.date_id
INNER JOIN lu_calendar a14
ON a12.invoice_date = a14.date_id
...
As usual there are possible solution, not all of them very straight forward.
Option 1 - Single date attribute
You mention this possibility in your question, instead of using "Order Date" and "Invoice Date", just use a single "Date" attribute and teach users to use it. You can call it "Reporting Date" or "Operation Date" if this makes the life easier for them.
The SQL you should get is something like:
...
FROM order_fact a11
INNER JOIN invoice_fact a12
ON a11.order_date = a12.invoice_date
INNER JOIN lu_calendar a13 -- Only one join
ON a11.order_date = a13.date_id -- because the date is the same
...
Option 2 - We need to keep the two date attributes!
Map "Order Date" and "Invoice Date" on the same alias of your calendar table. This is usually can cause problems in MicroStrategy, because two attributes will be joined together on the same look-up table [see later on this], but in your case this is exactly what you are looking for.
With this solution you should get an SQL like this:
...
FROM order_fact a11
INNER JOIN invoice_fact a12 -- Hey! this is again a cross join!
INNER JOIN lu_calendar a13
ON a11.order_date = a13.date_id -- Relax man, we got you covered.
AND a12.invoice_date = a13.date_id -- Yes, we do it!
...
This is nice, but it works only if you have description forms coming from the calendar table (this is not always the case with dates because the ID is usually also the actual value that you show on your reports). In case you don't have a join with the calendar lookup, you SQL will end up again with duplicated result:
...
FROM order_fact a11 -- Notice no join column between the two facts
INNER JOIN invoice_fact a12 -- and no other conditions will help to join them
...
For this reason if you want to keep the two attributes separate, beside mapping them on the same lookup, you should also:
Create an hidden attribute (let's call it "Date_on_fact") map it on the fact table and the calendar table and make it child of both "Order Date" and "Invoice Date".
Un-map the "Order Date" and "Invoice Date" from the fact tables.
The idea here is to force MicroStrategy to use always the SQL code always the calendar lookup table:
...
FROM order_fact a11
INNER JOIN invoice_fact a12 -- This is like the previous one
INNER JOIN lu_calendar a13 -- But I'm back to help you
ON a11.order_date = a13.date_id
AND a12.invoice_date = a13.date_id
...
The attribute "Date_on_fact" can actually be hidden and users don't need to put it in their reports, but MicroStrategy will use it to go from the parent attributes to the fact table.
Hope this can help you to get out from the mud.
We had a same problem.
We had to create a generic time hierarchy for this and connected 2 different invoice and order time hierarchies to the generic one.
It works like charm!