Jump to content

Help with complex composition


mclarke

Recommended Posts

Hello!

 

I am *very* new to FusionPro and somewhat of a beginner in Javascript, but I have to come up with a demo for a customer creating one of their more complex products (at least to me) in FusionPro to show them it's merits in their daily production.

 

The product is raffle ticket books. Each book has a personalized front cover, dual numbered tickets with the amount of tickets in each book set at time of order (variable) and a back cover. The cover of each book also has to have "Book x of y" numbering on it.

 

So, I have a calculation for the total number of books, some "setbodypageusage" loops and then have to produce them as both one file for each book and one file for each order (not at the same time - two different production runs).

 

The customer wants a totally hands-off production run (we're going to be looking at FusionPro Producer if I can get this to work manually) with each order a separate line in the data file.

 

I've watched all the training videos, read the entire Rules guide and the User Guide section on rules, and I still can't figure out how to setup the loops.

 

This is what I've managed to come up with so far:

 

OnJobStart

FusionPro.Composition.chunksBreakStacks = true;


OnRecordStart

FusionPro.Composition.SetBodyPageUsage(Front, true)

var jobNumber = Field("CompanyName") + "_" + Field("TotalTickets");
var totalBooks = 0;
var ticketsPerBook = Field("TicketsPerBook");
var jobExtension = "." + (FusionPro.Composition.outputFormatExtension || "pdf");

if (FieldChanged("Companyname") || FusionPro.Composition.repeatRecordNumber % couponPerBook == 1)
{
   var jobNumber = Field("CompanyName") + "_" + Field("TotalTickets") + "_Book" + Int((FusionPro.Composition.repeatRecordNumber-1) / couponPerBook);
   var jobExtension = "." + (FusionPro.Composition.outputFormatExtension || "pdf");
   FusionPro.Composition.OpenNewOutputFile(jobNumber + jobExtension);
}


Ticket Number Rule

FusionPro.Composition.composeAllRecords = false; 
FusionPro.Composition.startRecordNumber = Field("StartNumber"); 
FusionPro.Composition.endRecordNumber = Field("TotalTickets"); 
FusionPro.Composition.repeatRecordCount = Field("TotalTickets");

return FormatNumber ("####", FusionPro.Composition.repeatRecordNumber);


Book Number Rule

var bookTotal = Field("TotalTickets") / Field("TicketsPerBook");

FusionPro.Composition.composeAllRecords = false; 
FusionPro.Composition.startRecordNumber = Field("StartNumber"); 
FusionPro.Composition.endRecordNumber = bookTotal; 
FusionPro.Composition.repeatRecordCount = bookTotal;

return FormatNumber ("####", FusionPro.Composition.repeatRecordNumber);


Book Total Rule

var bookTotal = Field("TotalTickets") / Field("TicketsPerBook");

return bookTotal

 

 

 

The sample data is as follows:

 

CompanyName,TotalTickets,TicketsPerBook,Date,Location,FirstPrize,SecondPrize,ThirdPrize,Price,MultPrice,StartNumber

ABC Company,1500,10,"July 3, 2020","123 Main Street, Anytown","40"" Smart TV",A Case of Mixed Wine,$25 Gas Card,5,20,1

Acme Widgets,2500,25,"August 14, 2020","895 Smith Place, Toytown",Weekend for Two in Las Vegas,"32"" Smart TV",$100 Gift Card,5,20,1

Spacely Sprockets,500,5,"September 7, 2020","999 Jon Street, Cape End",Entertainment Gift Basket,$25 Gas Card,$10 Starbucks Card,1,3,1

 

 

Any help will be greatly appreciated!!

 

Mike

Link to comment
Share on other sites

Welcome to the community!

 

Can you please post the FusionPro template you have so far? That would be a lot easier to examine and troubleshoot. It's hard to know what the template or the output should look like from just the rules and data. Thanks!

Link to comment
Share on other sites

Sure, no problem. It's very rough, no graphics, just the text. Before I went to the trouble of "fancying it up", I wanted to make sure I could get the variable pages to work. I don;t even have an imposition yet. The three pages are named and marked as unused (as per one of the training videos), so you will have to turn them on.

 

I did find some errors in the code I posted last night. I had an unknown variable because I had missed changing "couponsPerBook" to "ticketsPerBook" and the OnRecordStart gave an error to the lone "FusionPro.Composition.SetBodyPageUsage(Front, true)" I had at the beginning. It said "Front" (name of the cover page) was unknown.

 

I hope to get better at all this stuff, but it's hard learning scripting as I try to do this project and also teaching myself MySQL at the same time (needed for another part of the project). So, thank you for looking into this issue for me. I really appreciate it.

Sample-Ticket-Book.pdf

Link to comment
Share on other sites

Okay, thanks for posting the template. I still had to guess a bit as to what you want the output to be (a picture can be worth a thousand words), but the attached template should do what I think you want.

 

There's a lot going on here, but a few basic notes:

 

First, some of the code was in the wrong place. Some properties of the FusionPro.Composition object can be set only in certain Callback/Event rules; for instance, the composeAllRecords property can be set only in OnJobStart, and repeatRecordCount can be set only in OnRecordStart.

 

Conversely, some functions can't be called in certain rules. In particular, the Field function can't be called in either the JavaScript Globals nor in the OnJobStart function, as you're not actually in the context of a particular record (which has a particular value for the data field).

 

Also, you usually either want to set startRecordNumber and endRecordNumber OR set repeatRecordCount, but not both. Usually, it's easier to set set FusionPro.Composition.repeatRecordCount (in OnRecordStart) and access FusionPro.Composition.repeatRecordNumber to do something different for each repeat; that's what I've done here.

 

I've also made use of the FusionPro.Composition.AddVariable function to "inject" certain text variables, rather than writing a bunch of separate yet related rules for each one. This allows all the code to be centralized into a single rule, which is OnRecordStart. This one rule can "drive" what happens in each output record and file. I think that keeping all the logic in one place like this makes it easier to understand and maintain, but your mileage may vary.

 

You'll see some math in the rule, including use of the % (modulus) operator, to calculate things like which ticket number we're on within the current book, as well as some plain old division (with the / operator), and some functions such as Int and Math.ceil to round the results of such divisions to the next-lowest or next-highest integer value.

 

Note also that there aren't really any "loops" in the rule per se (though I did leave some commented-out code to debug the setting of all those other variables for the various numbers like which ticket and book we're on at each point in the repeat). The main repetition is triggered by setting FusionPro.Composition.repeatRecordCount, and by accessing FusionPro.Composition.repeatRecordNumber to vary the output per repeat. Also, I think the code as written will handle the case where StartNumber is something other than 1, but of course you will want to craft some data to test that particular case.

 

More thoughts:

produce them as both one file for each book and one file for each order (not at the same time - two different production runs).

Yes, so this requires something FusionPro can trigger off of to determine which of those two modes you want the composition to run in. I've made that something to be a hard-coded value in the rule, which you can change to switch from the "one file per book" mode to the "one file per order (record in the main data file)" mode.

 

However, it would be better, especially in an automated, or "totally hands-off" workflow, to have this specified in the data. I would add another data field (column) to the data file, called something like "OutputBooks", and set it to a value of Yes or No; the rule has some commented-out code showing how that can be accessed.

The customer wants a totally hands-off production run (we're going to be looking at FusionPro Producer if I can get this to work manually) with each order a separate line in the data file.

So in addition to having something in the data to denote which kind of production run you're doing, I would say that a "totally hands-off" workflow would actually require FusionPro Server. FusionPro VDP Producer frees you up from having to initiate each composition/production run in Acrobat, but a human still needs to push the Recompose button in the Producer Monitor app. Only FP Server allows a fully automated workflow, where another process can trigger a composition, via an API call, or by placing a data file in a hot folder, or some other automated mechanism.

Sure, no problem. It's very rough, no graphics, just the text. Before I went to the trouble of "fancying it up", I wanted to make sure I could get the variable pages to work. I don;t even have an imposition yet.

Yes, that's a good way to start.

The three pages are named and marked as unused (as per one of the training videos), so you will have to turn them on.

Yes, so here is another place where I had to guess a bit as to what you want the output to be. My version of the job outputs that "Cover" page at the start of each new book, and then a pair of pages ("Ticket" and "Back") for each ticket.

 

You presumably want a "Back" page for each Cover page as well, especially if you're imposing, as imposition requires each output record to have the same number of pages. What I would do is add a second Unused page named "Cover Back", and add a second call to FusionPro.Composition.SetBodyPageUsage to activate it along with the main "Cover" page. (This second call is there in the rule, commented out.)

 

Other than that, you shouldn't need any code to activate the main ticket pages, and those pages should NOT be marked as Unused in the Page Usage.

I hope to get better at all this stuff, but it's hard learning scripting as I try to do this project and also teaching myself MySQL at the same time (needed for another part of the project). So, thank you for looking into this issue for me. I really appreciate it.

No problem! That does seem like a lot to bite off at one time. I'm interested in how you're using SQL as part of this project.

Sample-Ticket-Book-Dan-1.pdf

Link to comment
Share on other sites

Thanks for helping me with this project. The SQL database is for the data management. It's how the CSV files will be generated to put into FusionPro Server (yeah, I typed the wrong product, didn't catch it in my proofreading). As I am under a NDA, that is all I can go into right now. Also, the product isn't tickets, but it's close.

 

I've added a back cover, but it is coming out after the first front/back ticket, instead of at the end of each book (right before the next cover page). Is there an easy way to move it? Also, I found out that I have to add a line on the cover to list the range of tickets in the book, too. Can the variables already created do it?

 

I've attached the updated ticket template with the back cover and a small sample file.

Spacely Sprockets_50.pdf

Sample-Ticket-Book-Dan-1.pdf

Link to comment
Share on other sites

Thanks for helping me with this project. The SQL database is for the data management. It's how the CSV files will be generated to put into FusionPro Server (yeah, I typed the wrong product, didn't catch it in my proofreading). As I am under a NDA, that is all I can go into right now. Also, the product isn't tickets, but it's close.

Sounds interesting!

I've added a back cover, but it is coming out after the first front/back ticket, instead of at the end of each book (right before the next cover page). Is there an easy way to move it?

Sure, you can move pages around in any PDF in Acrobat, with the Page Thumbnails panel, or with the Organize Pages tool:

https://helpx.adobe.com/acrobat/using/manipulating-deleting-renumbering-pdf-pages.html#move_or_copy_a_page

 

The pages in each record in the FusionPro output are in the same order as in the template PDF. So all you need to do is move that "CoverBack" page to be the second page in the template, between the Cover and Ticket pages.

Also, I found out that I have to add a line on the cover to list the range of tickets in the book, too. Can the variables already created do it?

No, that requires a bit more math.

I've attached the updated ticket template with the back cover and a small sample file.

Thanks! That's helpful.

 

I've rearranged the pages as mentioned, and added code to output the ticket ranges for each book.

Sample-Ticket-Book-Dan-2.pdf

Link to comment
Share on other sites

Dan:

 

I have it working perfectly now. Had to make a couple small changes to get the back cover of the book to be in the correct position, though. I even managed to figure it out on my own.

 

Thank you again.

 

Mike

 

P.S. How hard would it be to make all the side 2 pages variable? I figure to control it by added a column for number of sides. Then, I would just need to set up some conditions to check for the value and turn on/off the required pages, right?

Link to comment
Share on other sites

I have it working perfectly now. Had to make a couple small changes to get the back cover of the book to be in the correct position, though. I even managed to figure it out on my own.

 

Thank you again.

Great! Glad to help.

P.S. How hard would it be to make all the side 2 pages variable? I figure to control it by added a column for number of sides. Then, I would just need to set up some conditions to check for the value and turn on/off the required pages, right?

Sure. Though if you're imposing, you need to have the same number of pages output for each record. But you can certainly put variable content on those back pages. You could also have multiple versions of those that you swap in and out with SetBodyPageUsage, but I would think you could accomplish what you need without that, maybe by conditionally suppressing frames. I'd need to know more about what kind of variability you're trying to accomplish to make a more specific suggestion.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...