WF4 - Display workflow image in asp.net and highlight an activity - asp.net

I need to display current status of a document approval workflow task in asp.net web page with a specific activity highlighted.
I have seen the Visual workflow tracker example (in wf & wcf samples) but I have two issues,
I have to render workflow in asp.net not in a WPF app.
I don't need to display current status with workflow running, all activities that need to be highlighted are the ones that require user input. e.g. "waiting for approval from department head" etc.
If I could just convert the workflow XAML to JPG after highlighting a specific activity by activity id "that created a bookmark and waiting for resumption the bookmark" it would do the work.
check the attached file for required workflow image to be rendered on asp.net page:
Workflow with current activity highlighted (that is waiting to be resumed)

First load the workflow into the designer.
You should already know the 'activity' you want highlighted. There is selection service in the workflow you can use to select the appropriate model items. This example shows single selection, but there is multiple.
ModelService modelService = wd.Context.Services.GetService<ModelService>();
IEnumerable<ModelItem> activityCollection = modelService.Find(modelService.Root, typeof(Activity));
Selection.Select(wd.Context, activityCollection.ElementAt(5));
On the workflow designer there is a button to copy workflow as image or something along those lines. This link will show you how to get the jpg from the WorkflowDesigner.View.
http://social.msdn.microsoft.com/Forums/en-US/wfprerelease/thread/b781c8df-608a-485a-80e3-a795d800f08d
const double DPI = 96.0;
Rect size = VisualTreeHelper.GetDescendantBounds(view);
int imageWidth = (int)size.Width;
int imageHeight = (int)size.Height;
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(imageWidth, imageHeight, DPI, DPI, PixelFormats.Pbgra32);
renderBitmap.Render(view);
BitmapFrame bf = BitmapFrame.Create(renderBitmap);
using (FileStream fs = new FileStream(#"c:\test.jpg", FileMode.Create))
{
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bf));
encoder.Save(fs);
fs.Close();
}
As an added note you should check out Kushals example:
http://blogs.msdn.com/b/kushals/archive/2009/12/22/visualworkflowtracking-aka-workflowsimulator.aspx

Related

Google App maker multiple files drive upload

We are going to use drive picker as attachement field, so whenever an user uploads a file or multiples files to drive we have to get the links of the files and show it to the user in the form.
Here is a code sample with following assumptions:
you have Master and Attachment models with One-to-Many relation
datasource of the current page is set to record from the Master model
datasource is in Auto Save mode
// onDocumentSelect Drive Picker's event handler
var create = widget.root.datasource.relations.Attachments.modes.create;
result.docs.forEach(function(doc) {
create.item.Url = doc.url;
create.createItem();
});
This code will make N requests to the server, where N is number of attachments. You can use google.script.run to make a single call and handle creating new attachment records and relations on server, but then you'll need manually reload relation to show changes to user.

How to generate totals of fields from related model records

I'm trying to work out how to generate totals of fields from related model records.
Example: I have 2 Google Drive Table models (Projects & Stages) with a relation where 1 Project can have many Stages. The Stages model has a number of fields, one of which is Budget.
I'm trying work out how to display a Total Project Budget, which is the sum of the Budget fields of the Stages related to each Project.
I'm really stuck on getting this to work and wondering if I need to create a client script, server script, or calculated model, or if there's an easy way to do this directly within a binding.
Here is a link to a bunch of screen-grabs of what I'm trying to build, the UI and setup in App Maker:
https://www.dropbox.com/sh/wt00virvn88puyi/AACy7-fPLYFF1H9uFkvEuvgTa?dl=0
Datasource has client event onLoad, so you can calculate value in this event, find widget, which shows total, and set text of this widget.
I got it working by creating the following client script, after studying Andrey's suggestion & link (thanks!). I call the script whenever the totals need recalculating (i.e. onValueChange of existing Stages, and onAttach/Detach for new or deleted Stages. Works nicely.
function updateProjectTotals() {
var currentProject = app.datasources.Projects.item;
var totals = {ProjectName:currentProject.ProjectName, Stages:0, Progress:0, Budget:0};
var stages = currentProject.Stages;
stages.forEach(function(item){
totals.Progress += item.StageProgress;
totals.Budget += item.StageBudget;
});
totals.Stages = stages.length;
totals.Progress = (totals.Progress/totals.Stages);
var record = app.datasources.Projects.item;
record.ProjectProgress = totals.Progress;
record.ProjectBudget = totals.Budget;
}

Open print dialog for report from code

I am attempting to force open the print dialog so that all the user has to do is set the email address and press ok. I've found multiple tutorials on how to print a report to file or a printer without the print dialog, but that's not what I'm looking for.
Typically to email a report, the user displays the report, clicks the print icon in the tool bar, and then chooses email and sends it. I want to cut out the first two steps automatically.
This is one of my many attempts at doing this so far, but to no avail.
void emailInvoice()
{
Args args;
ReportRun rr;
Report rb;
PrintJobSettings pjs;
CustInvoiceJour record;
;
select record where record.RecId == 5637175089;
args = new Args("SalesInvoice");
args.record(record);
args.parmEnum(PrintCopyOriginal::OriginalPrint);
// Set report run properties
rr = new ReportRun(args,'');
rr.suppressReportIsEmptyMessage(true);
rr.query().interactive(false);
// set report properties
rb = rr.report();
rb.interactive(true);
// set print job settings
pjs = rr.printJobSettings();
pjs.fileName(strfmt("C:\\Users\\gbonzo\\Desktop\\%1.pdf", record.SalesId));
pjs.fitToPage(true);
// break the report info pages using the height of the current printer's paper
pjs.virtualPageHeight(-1);
// force PDF printing
pjs.format(PrintFormat::PDF);
pjs.setTarget(PrintMedium::Mail);
pjs.viewerType(ReportOutputUserType::PDF);
// lock the print job settings so can't be changed
// X++ code int the report may try to change the destination
// to the screen for example but this does not make
// sense when running a report here
pjs.lockDestinationProperties(true);
// Initialize the report
rr.init();
rr.run();
}
Thanks in advance for your help!
Have you tried to develop a RunBase standard dialog class (RunBaseBatchPrintable if you need to select the printer) that get all the dialog fields you need and from there, programatically run the report passing all the desired parameters? I'm prety sure it will work, and probably will left a cleaner code separating the report of the logic needed to the user interaction.
Read an example here:
http://waikeatng.blogspot.com.es/2010/10/using-runbasebatchprintable-class.html
You have to call the prompt() method of the ReportRun class before calling the run() method.
if (rr.prompt())
{
rr.run();
}
The prompt() method will show the print dialog. If you want it easier for your users you could use the SysMailer class, take a look to the quickSend() method.

VB.NET WebBrowser Object Captures Remote Web Page At Low Resolution

Background
I have an ASP.NET web application with a VB.NET back end. In this application users can create payment requests which must be approved by a manager before they are sent to accounts payable for further processing. Within my request page (the page where the user enters the request information) I have a button that links to a separate .aspx page which provides a print preview of the request. When the request is approved by all of the required approvers, I have a VB.NET function that contains a WebBrowser object that navigates to the print preview page behind the scenes and takes a snap shot of it, then saves it as a .tiff file to an internal file share which is then picked up by a internal process and imported into another internal application called OnBase to go through processing for accounts payable.
The Problem
My problem is that when the my function takes the snap shot of the print preview page, the saved tiff has a lower resolution than desired. In other words, it looks kind of crappy when it is viewed through OnBase and when it is printed out.
The Question
How do I increase the resolution of the generated .tiff file at the time that the snapshot of the webpage is generated?
The Code
Private Sub CaptureWebPage()
Try
Dim tiffFileName As String
tiffFileName = OnBasePath & "CheckRequest_" & CurrentRequestId & ".tiff"
Dim impersonateCode As New AliasAccount("TheUsername", "ThePassword")
impersonateCode.BeginImpersonation()
Dim browser As Windows.Forms.WebBrowser = New Windows.Forms.WebBrowser
browser.ScrollBarsEnabled = False
browser.ScriptErrorsSuppressed = True
browser.Navigate(OnBasePath & htmlFileName)
While browser.ReadyState <> Windows.Forms.WebBrowserReadyState.Complete
System.Windows.Forms.Application.DoEvents()
End While
System.Threading.Thread.Sleep(1500)
browser.ClientSize = New Size(950, 768)
Dim Height As Integer = browser.Document.Body.ScrollRectangle.Bottom
browser.ClientSize = New Size(950, Height)
Dim bmp As Bitmap = New Bitmap(browser.Bounds.Width, Height)
browser.DrawToBitmap(bmp, browser.Bounds)
If File.Exists(tiffFileName) Then
File.Delete(tiffFileName)
End If
If File.Exists(OnBasePath & htmlFileName) Then
File.Delete(OnBasePath & htmlFileName)
End If
bmp.Save(tiffFileName.ToString(), ImageFormat.Tiff)
bmp.Dispose()
impersonateCode.EndImpersonation()
Catch ex As Exception
Throw
End Try
End Sub
Additional Information
I have tried to use the .SetResolution method of my bitmap object, but it doesn't actually change the resolution of the generated .tiff file. I have tried to Google this numerous times find a solution, but haven't found anything useful.
Thanks In Advance
Screen "resolution" is much lower than print "resolution". Typically desktop monitors are around 100ppi, where a normal printer on a desk might be 600dpi.
The only suggestion I have for getting a higher resolution rendering of the web page would be configure what is grabbing the screenshot to use a resolution 3x what you are using now, and then set its zoom to 300%. Text elements and vector graphics will be rendered smoothly. Images will still be their web resolutions, and you may even lose image quality through interpolation when sizing up.
You could try and print the page to a virtual print driver in PDF format. I have found OnBase sometimes does strange things with image files, it doesn't like colour or grey scale TIFFs. Instead use JPEG for colour / grey scale.

Printing silently from Spring MVC/Jasper Application

This is very abstract question.
I'm working on a Spring MVC Web Application which has to deal with lot of invoice printing continuously. Currently When the invoice is saved, the spring controller delegates the invoice id to the jasper pdf generation service which prepares the pdf. After the pdf gets downloaded, the user manually prints it.
I need a way to print the invoice silently when the user saves the invoice.
Any ideas?
Since you are exporting to PDF it is possible. You need to add a JRPdfExporterParameter.PDF_JAVASCRIPT parameter to your JRPdfExporter instance with the value "this.print({bUI: true,bSilent: false,bShrinkToFit: true});". For Example:
protected static byte[] exportReportToPdf(JasperPrint jasperPrint) throws JRException{
JRPdfExporter exporter = new JRPdfExporter();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);
exporter.setParameter(JRPdfExporterParameter.PDF_JAVASCRIPT, "this.print({bUI: true,bSilent: false,bShrinkToFit: true});");
exporter.exportReport();
return baos.toByteArray();
}
This actually adds the JavaScript to the PDF. When the PDF is opened it is ran, and will send it the print queue. It should be noted that this should be used sparingly as it is not generally considered to be nice to do this automatically for your users. When I have used it in an app, we had to buttons for each report. An Export button, that does not contain the JavaScript, and a Print button that did. That way users that wanted it to just print it would do so, and those that wanted a digital copy had that also.

Resources