How can I submit unsubmitted Moodle attempt via SQL - moodle

Hello I ma trying to submit unsubmitted quiz attempts so I can grade them. So far I have set the timefinish column in mdl_quiz_attempts which changes the attempt status to "Not yet graded", then setting fraction to 0 from NULL and state to "gradewrong" from "complete" in mdl_question_attempt_steps to simulate submission but this seems to break the site. What am I missing?

You're going to have to trace through the code for the process_finish() function in mod/quiz/attemptlib.php ( https://github.com/moodle/moodle/blob/master/mod/quiz/attemptlib.php#L2171 ) and figure out how that all works.
This is a complex process and will require a lot of DB queries / updates in order to achieve it manually.
I would strongly recommend that you write a PHP script to do this, instead of trying to handle it manually (that way you can create an instance of 'quiz_attempt' for each user's attempt, then call $attempt->process_finish() on each, in order to close the attempt properly).

Thanks. The trick is to set the timefinish column in mdl_quiz_attempts which changes the attempt status to "Not yet graded", then setting the state to "gradewrong" from "complete" in mdl_question_attempt_steps for unsubmitted responses to simulate submission. Then set a fake 0 grade to sumgrades where grades are NULL in mdl_quiz_attempts and then running a regrade in the admin panel.

Related

Using QCMDEXC to call QEZSNDMG via DB2 stored procedure

Working on a side project where I use a set of views to identify contention of records within an iSeries set of physical files.
What I would like to do once identified is pull the user profile locking the record, and then send a break message to their terminal as an informational break message.
What I have found is the QEZSNDMG API. Simple enough to use interactively, but I'm trying to put together a command that would be used in conjunction with QCMDEXC API to issue the call to QEZSNDMG and alert the user that they are locking a record.
Reviewing the IBM documentation of the QEZSNDMG API, I see that there are two sets of option parameters, but nothing as required (which seems odd to me, but another topic for another day). But I continue to receive the error "Parameters passed on CALL do not match those required."
Here are some examples that I have tried from the command line so far:
CALL PGM(QEZSNDMG) PARM('*INFO' '*BREAK' 'TEST' '4' 'DOUGLAS' '1' '1' '-4')
CALL PGM(QEZSNDMG) PARM('*INFO' '*BREAK' 'TEST' '4' 'DOUGLAS')
CALL PGM(QEZSNDMG) PARM('*INFO' '*BREAK' 'TEST' '4' 'DOUGLAS' '1')
Note: I would like to avoid using a CL or RPG program if possible but understand it may come to that using one of many examples I found before posting. Just want to exhaust this option before going down that road.
Update
While logged in, I used WRKMSGQ to see the message queues assigned to my station. There were two: QSYS/DOUGLAS and QUSRSYS/DOUGLAS. I then issued SNDBRKMSG with no affect on my workstation (IE, the message didn't break my session):
SNDBRKMSG MSG(TESTING) TOMSGQ(QSYS/DOUGLAS)
SNDBRKMSG MSG(TESTING) TOMSGQ(QUSRSYS/DOUGLAS)
I realized if I provide the workstation session name in the TOMSG parameter it worked:
SNDBRKMSG MSG(TESTING) TOMSGQ(*LIBL/QPADEV0003)
Using SNDBRKMSG was what I was looking for.
Some nudging in the right direction lead me to realize that the workstation session ID is located within QSYS2.RCD_LOCK in field JOB_NAME (job number/username/workstation).
Extracting the workstation ID allowed me to create a correctly formatted SNDBRKMSG command to QCMDEXC and alert the user that they are locking a record needed by another process.

How to prevent the NULLS being removed?

I am currently using SQL Server 2008R2.
I am using this script:
SELECT a.productname, a.orderdate, a.workarea
FROM database1table1 AS a
WHERE a.orderdate >='2016/08/01'
Which gives the output:
PRODUCT NAME ORDER DATE WORKAREA
x 2016/08/07 NULL
y 2016/08/09 HOLDING
z 2016/08/10 ACTION
a 2016/08/12 ACTION
My problem arises when I amend the above script to read,
...
WHERE a.orderdate >='2016/08/01'
**AND a.workarea NOT IN ('HOLDING')**
When I do this, not only does it remove 'HOLDING', but it also removes the NULL rows as well, which I definitely do not want.
Please can you suggest an amendment to the script to prevent the NULLS being removed - I only want to see the value 'HOLDING' taken out.
With many thanks!
You can try a workaround
AND ISNULL(a.workarea,'') NOT IN ('HOLDING')
It will transform all null a.workarea in the "where" the "not in" works correctly

MS Access - me.recordset not passing to sub

I have a form that loads a single record. The user does what they need to do on the form...in this case, they enter a date, and a button becomes available to click to advance the record to the next step in the process.
I have a public function that is logging the activity to tblActivity, and sets the record's new Status and Location. This Function takes 3 variables, and was working fine until today.
'I'm calling the function with this line from the button's Click event
LogActivity 15, Screen.ActiveForm, Me.Recordset
Public Function LogActivity(ByVal lSID As Long, Optional fForm As Form, Optional ByRef fRS As Recordset)
With fRS
Do Until .EOF
Debug.Print .Fields(5)
.MoveNext
Loop
End With
...
End Function
This should be printing the form's Status value, but fRS is passed in with no values. The form's recordset has values prior to being passed as the form has data. Some how it is getting lost in the pass. This was working fine, I have multiple buttons across 5 different forms that all call this same Function. Suddenly today, none of them can pass the recordset. I can think of nothing that was changed that would effect this. Most of the changes recently involved locking down fields and the appearance of buttons at the right time...nothing related to the recordset.
Naturally, this DB is supposed to go live on Monday.
Found the problem.
I had a backup from yesterday that was working fine.
One by one, I went through the changes I logged from yesterday and found that by changing some fields to .enabled = False and .locked = True is what was doing it. Apparently that was enough to clear all the values when passing.
Left the fields enabled, just locked them and it passes all values correctly.
Even though this was a failure on my part, I'll leave this up in case some one else makes the same mistake I made.
**** Update ****
I also found out that if I did a
fRS.movelast
fRS.movefirst
before anything else, it found the data. Not sure why it started happening, but these two things seem to have fixed it completely.

Cannot update one field at a time with VSTO for Word

When fields are nested, there is a problem.
foreach (Word.Field field in this.Application.ActiveDocument.Fields)
{
field.Update();
text = field.Result.Text;
}
The above code does not work.
The process starts, but winds up in an endless loop or some other process that hangs the system.
Thinking about it, I can surmise that when you update a field, it might have an effect on the fields collection - thus, the loop fails.
Does anyone have any ideas on implementing this?
P.S. I know there is a Document.UpdateFields() method to update ALL fields. However, there are reasons why I cannot use this and need to only update specific field types.
My apologies! I was going to give an example of a nested field but was trying to test some more before sending anyone (Jack) on a goose-chase.
I waited and waited and waited, and after a good 2 or 3 minutes, it finished. After the last field, it crashed with this message:
Object has been deleted.
The error was generated from the following line inside the loop:
string text = field.Code.Text;
The template is being tested on mergefields that are not being found because I am testing without database connectivity. It would be odd, but explainable, that it goes through all the fields and then, at the end of the day, the very OUTER IF field's result is "Error! Reference source not found." But I still don't get why this could happen.
Nor do I understand why looping takes 3 minutes while a call to document.Fields.Update() will do the same thing in about 1 second and NOT result in the error described above.
Again, my apologies. I never considered updating inside a loop would be vastly slower that a call to doc.fields.update().

Manipulating form input values after submission causes multiple instances

I'm building a form with Yii that updates two models at once.
The form takes the inputs for each model as $modelA and $modelB and then handles them separately as described here http://www.yiiframework.com/wiki/19/how-to-use-a-single-form-to-collect-data-for-two-or-more-models/
This is all good. The difference I have to the example is that $modelA (documents) has to be saved and its ID retrieved and then $modelB has to be saved including the ID from $model A as they are related.
There's an additional twist that $modelB has a file which needs to be saved.
My action code is as follows:
if(isset($_POST['Documents'], $_POST['DocumentVersions']))
{
$modelA->attributes=$_POST['Documents'];
$modelB->attributes=$_POST['DocumentVersions'];
$valid=$modelA->validate();
$valid=$modelB->validate() && $valid;
if($valid)
{
$modelA->save(false); // don't validate as we validated above.
$newdoc = $modelA->primaryKey; // get the ID of the document just created
$modelB->document_id = $newdoc; // set the Document_id of the DocumentVersions to be $newdoc
// todo: set the filename to some long hash
$modelB->file=CUploadedFile::getInstance($modelB,'file');
// finish set filename
$modelB->save(false);
if($modelB->save()) {
$modelB->file->saveAs(Yii::getPathOfAlias('webroot').'/uploads/'.$modelB->file);
}
$this->redirect(array('projects/myprojects','id'=>$_POST['project_id']));
}
}
ELSE {
$this->render('create',array(
'modelA'=>$modelA,
'modelB'=>$modelB,
'parent'=>$id,
'userid'=>$userid,
'categories'=>$categoriesList
));
}
You can see that I push the new values for 'file' and 'document_id' into $modelB. What this all works no problem, but... each time I push one of these values into $modelB I seem to get an new instance of $modelA. So the net result, I get 3 new documents, and 1 new version. The new version is all linked up correctly, but the other two documents are just straight duplicates.
I've tested removing the $modelB update steps, and sure enough, for each one removed a copy of $modelA is removed (or at least the resulting database entry).
I've no idea how to prevent this.
UPDATE....
As I put in a comment below, further testing shows the number of instances of $modelA depends on how many times the form has been submitted. Even if other pages/views are accessed in the meantime, if the form is resubmitted within a short period of time, each time I get an extra entry in the database. If this was due to some form of persistence, then I'd expect to get an extra copy of the PREVIOUS model, not multiples of the current one. So I suspect something in the way its saving, like there is some counter that's incrementing, but I've no idea where to look for this, or how to zero it each time.
Some help would be much appreciated.
thanks
JMB
OK, I had Ajax validation set to true. This was calling the create action and inserting entries. I don't fully get this, or how I could use ajax validation if I really wanted to without this effect, but... at least the two model insert with relationship works.
Thanks for the comments.
cheers
JMB