ImageViewport.refresh() seems to do nothing / how to re-render in BGE before taking a screenshot
BGE API:


  bge.render.makeScreenshot(filename)
  
  
    Writes an image file with the
    current displayed frame
  


Your changes to the scene will be rendered after all logic of the current frame completed. Regardless what you do and in what order the rotation will not be part of the already rendered output of the last frame. 

Your idea to perform logic (rotation) in one frame and call makeScreenshot within the next one is correct. 

I strongly suggest to separate these two operations. Rotating an object and making a screenshot are two separate operations. As they need to run at different time points running it from the same controller makes the design unnecessary complex.

As you want to create the filename dependent on a previously chosen number I suggest to transfer this number somehow to the other processing. In this case I suggest to send it via message. This serves two puposes: 


tells when to make a screen shot
provides information necessary to create the file name


I would not send the file name as it is the responsibility of the saving operation to care this detail, while the rotation processing cares just the random selection (it selects an option not a file name).

Randomly Turn



turnRandomly

import bge
from mathutils import Euler
import random
import math


controller = bge.logic.getCurrentController()

if all(sensor.positive for sensor in controller.sensors):
    owner = controller.owner
    new_q = random.randint(0,3)
    if new_q == 0:
        q = Euler((0.0, 0.0, 0.0)).to_quaternion()    
    elif new_q == 1:
        q = Euler((0.0, 0.0, math.radians(90.0))).to_quaternion()    
    elif new_q == 2:
        q = Euler((0.0, 0.0, math.radians(180.0))).to_quaternion()    
    elif new_q == 3:
        q = Euler((0.0, 0.0, math.radians(270.0))).to_quaternion()    
    owner.worldOrientation = q

    for actuator in controller.actuators:
        try:
            actuator.body = str(new_q)
        except AttributeError:
            pass
        controller.activate(actuator)


Assumptions:


all sensors needs to be positive (AND behavior)
should have a message actuator (otherwise there will be no error but make screenshot will not be triggered)
all actuators will be activated

Make Screenshot




makeScreenshot

import bge
from datetime import datetime

controller = bge.logic.getCurrentController()
if all(sensor.positive for sensor in controller.sensors):
    for sensor in controller.sensors:
        try:
           bodies = sensor.bodies
        except AttributeError:
            continue

        for body in bodies:
            option = body
            filename = 'e:/temp/q_{}-{:%Y%m%d-%H%M%S}.png'.format(
                option, datetime.now())
            print ('saving {}'.format(filename))
            bge.render.makeScreenshot(filename)


assumptions:


all sensors needs to be positive (AND behavior)
non-message sensors will only be checked without any further processing
all bodies will be processed (e.g. several messages arrive at the same frame)
the screenshot will use a timestamp in name (rather than a non-unique random number)


As the message will trigger one frame later, the screenshot will be made a the right frame.

Be aware these operations do not need to be performed by the same object.