Example #1
0
            return new Promise(function (resolve, reject) {
                if (meta.project_type_class === "standard") {
                    // normalize input
                    var chapters = _.mapValues(_.groupBy(translation, function (obj) {
                        //console.debug('map chapter values', obj);
                        return obj.chunkmeta.chapterid;
                    }), function (chapter, key) {
                        var frames = _.mapKeys(chapter, function (obj) {
                            //console.debug('map chapter keys', obj);
                            return obj.chunkmeta.frameid;
                        });

                        var chapterObj = {
                            id: key,
                            title: frames.title || key,
                            reference: frames.reference === undefined ? null : frames.reference,
                            format: meta.format
                        };
                        delete frames.reference;
                        delete frames.title;
                        chapterObj.frames = _.sortBy(_.filter(frames, function (o) {
                            return o.transcontent !== '';
                        }), function (f) {
                            //console.debug('sort frames',f);
                            return f.chunkmeta.frame;
                        });
                        return chapterObj;
                    });
                    var project = {
                        format: meta.format,
                        title: chapters['00'].title
                    };
                    delete chapters['00'];
                    project.chapters = _.sortBy(_.filter(chapters, function (o) {
                        return o.frames.length > 0;
                    }), 'id');
                    chapters = null;

                    if (project.format === 'markdown') {

                        var doc = new PDFDocument({
                            bufferPages: true,
                            margins:{
                                top: 72,
                                bottom: 50,
                                left: 72,
                                right: 72
                            }
                        });
                        doc.pipe(fs.createWriteStream(filePath));
                        // default meta
                        if (project.title.transcontent !== "") {
                            doc.info.Title = project.title.transcontent;
                        } else {
                            doc.info.Title = project.title.projectmeta.project.name;
                        }

                        //doc.info.Author = 'Joel Lonbeck'; // todo: translators
                        //doc.info.Subject = 'an unrestricted, visual mini-Bible in any language'; // todo: project sub-title
                        doc.info.Keywords = meta.target_language.name;

                        // book title
                        doc.fontSize(25)
                            .font(targetfont)
                            .text(doc.info.Title, 72, doc.page.height / 2, {align: 'center'});

                        mythis.renderLicense(doc, "OBS_LICENSE.md");

                        // TOC placeholders
                        doc.addPage();
                        var lastTOCPage = doc.bufferedPageRange().count;
                        var tocPages = {
                            start: lastTOCPage - 1
                        };
                        doc.fontSize(25)
                            .text(' ', 72, 72)
                            .moveDown();
                        _.forEach(project.chapters, function (chapter) {
                            doc.fontSize(10)
                                .text(' ')
                                .moveDown();
                            var currPage = doc.bufferedPageRange().count;
                            if (lastTOCPage !== currPage) {
                                // record toc page split
                                tocPages[chapter.id] = currPage - 1;
                                lastTOCPage = currPage;

                                // give room for header on new page
                                doc.fontSize(25)
                                    .text(' ', 72, 72)
                                    .moveDown();
                            }
                        });

                        // book body
                        _.forEach(project.chapters, function (chapter) {
                            // chapter title
                            doc.addPage();
                            doc.fontSize(20)
                                .text(chapter.title.transcontent || chapter.title.chunkmeta.title, 72, doc.page.height / 2, {align: 'center'});
                            chapter.page = doc.bufferedPageRange().count;

                            // frames
                            if (options.doubleSpace === true) {
                                doc.lineGap(20);
                            }
                            doc.addPage();
                            _.forEach(chapter.frames, function (frame) {
                                if (options.includeIncompleteFrames === true || frame.completed === true) {
                                    doc.moveDown();
                                    if (options.includeImages === true) {
                                        //console.debug(meta);
                                        //console.debug(frame);
                                        // TRICKY: right now all images are en
                                        var imgPath = path.join(imagePath, meta.resource.id + "-en-" + frame.chunkmeta.chapterid + "-" + frame.chunkmeta.frameid + ".jpg");
                                        //check the position of the text on the page.
                                        // 792 (total ht of page) - 50 ( lower margin) - 263.25 (height of pic) = 478.75 (max amount of space used before image)
                                        if (doc.y > 478.75) {
                                            doc.addPage();
                                        }
                                       doc.image(imgPath, {width:doc.page.width - 72*2});
                                    }
                                    doc.fontSize(10)
                                        .text(frame.transcontent);
                                    if (options.includeImages === true) {
                                        doc.moveDown();//add extra line break after image and text as per github issue527
                                    }
                                }
                            });

                            // chapter reference
                            if (chapter.reference !== null) {
                                doc.moveDown()
                                    .fontSize(10)
                                    .text(chapter.reference.transcontent);
                            }
                        });

                        // number pages
                        var range = doc.bufferedPageRange();
                        for (var i = range.start; i < range.start + range.count; i ++) {
                            doc.switchToPage(i);
                            doc.fontSize(10)
                                .font(defaultfont)
                                .text(i + 1, 72, doc.page.height - 50 - 12, {align: 'center'});
                        }

                        // write TOC
                        var currTocPage = tocPages.start;
                        doc.switchToPage(currTocPage);
                        // TODO: display correct title of TOC based on the project
                        doc.fontSize(25)
                            .lineGap(0)
                            .text('Table of Contents', 72, 72)
                            .font(targetfont)
                            .moveDown();
                        _.forEach(project.chapters, function (chapter) {
                            if (tocPages[chapter.id] !== undefined && tocPages[chapter.id] !== currTocPage) {
                                currTocPage = tocPages[chapter.id];
                                doc.switchToPage(currTocPage);
                                doc.fontSize(10)
                                    .text(' ')
                                    .moveUp();
                            }
                            doc.switchToPage(currTocPage);
                            doc.fontSize(10)
                                .text(chapter.title.transcontent || chapter.title.chunkmeta.title)
                                .moveUp()
                                .text(chapter.page + '', {align: 'right'})
                                .moveDown();
                        });

                        doc.end();
                        resolve(true);
                    } else if (project.format === 'usfm') {

                         var doc = new PDFDocument({
                            bufferPages: true,
                            margins:{
                                top: 72,
                                bottom: 50,
                                left: 72,
                                right: 72
                            }
                        });
                        doc.pipe(fs.createWriteStream(filePath));

                        //set the title
                        doc.info.Title = translation[0].transcontent || meta.project.name;
                        doc.fontSize(25)
                            .font(targetfont)
                            .text(doc.info.Title, 72, doc.page.height / 2, {align: 'center'});

                        mythis.renderLicense(doc, "LICENSE.md");

                             // book body
                        _.forEach(project.chapters, function (chapter) {

                            doc.addPage();//start each chapter on new page

                            //list chapters (remove leading zeros in the numbers)
                            var chapterNum = chapter.id.replace(/\b0+/, '');
                            doc.fontSize(20)
                                .lineGap(10)
                                .text(chapterNum + ' ', {continued: true});
                            chapter.page = doc.bufferedPageRange().count;

                            // frames
                            if (options.doubleSpace === true) {
                                doc.lineGap(20);
                            }

                            _.forEach(chapter.frames, function (frame) {
                                if (options.includeIncompleteFrames === true || frame.completed === true) {
                                    var content = frame.transcontent.split(/[\\]*[\\||\/][v][ ]([0-9]+)/g);

                                    _.forEach(content, function (info) {
                                        let output = info;
                                       //superscript for verses not supported by pdfkit: https://github.com/devongovett/pdfkit/issues/15
                                       output = output.replace(/[\\][\\c][ ][0-9]+ /g, '');
                                        doc.fontSize(10)
                                            .text(output + ' ',  { continued: true});
                                    });
                                }
                                doc.moveDown()
                                    .text("");
                            });
                        });

                        // number pages
                        var range = doc.bufferedPageRange();
                        for (var i = range.start; i < range.start + range.count; i ++) {
                            doc.switchToPage(i);
                            doc.fontSize(10)
                                .font(defaultfont)
                                .text(i + 1, 72, doc.page.height - 50 - 12, {align: 'center'});
                        }

                        doc.end();
                        resolve(true);
                    } else {
                        reject('We only support printing OBS and Bible projects for now');
                    }
                } else {
                    // TODO: support exporting other target translation types if needed e.g. notes, words, questions
                    reject('We do not support printing that project type yet');
                }
            });
Example #2
0
			var findTests = function(error, tests){
				//Handle Error.
				if(error){
					return next(error);
				}
				
				//Create a pdf document
				var doc = new PDFKit({bufferPages: true});
				var stream = doc.pipe(res);
				
				//First page (Build infos)
				doc.fillColor('black').fontSize(30).text('Build Report');
				doc.moveDown();
				doc.fontSize(15).text('Build Name', {underline:true, continued: true}).text(': '+build.name, {underline:false});
				doc.moveDown();
				doc.fontSize(15).text('Date', {underline:true, continued: true}).text(': '+build.date, {underline:false});
				doc.moveDown();
				if(!_.isNull(build.duration.value)){
					doc.fontSize(15).text('Duration', {underline:true, continued: true}).text(': '+batam_util.durationToStr(build.duration.value), {underline:false});
				}else{
					doc.fontSize(15).text('Duration', {underline:true, continued: true}).text(': Not Available', {underline:false});
				}	
				doc.moveDown();
				doc.fontSize(15).text('Total Tests', {underline:true, continued: true}).text(': '+build.tests.value, {underline:false});
				doc.moveDown();
				doc.fontSize(15).text('Passes', {underline:true, continued: true}).text(': '+build.passes.value, {underline:false});
				doc.moveDown();
				if(!_.isUndefined(build.regressions) && !_.isUndefined(build.regressions.value)){
					doc.fontSize(15).text('Regressions', {underline:true, continued: true}).text(': '+build.regressions.value, {underline:false});
				}else{
					doc.fontSize(15).text('Regressions', {underline:true, continued: true}).text(': Not Available', {underline:false});
				}	
				doc.moveDown();
				if(!_.isUndefined(build.failures) && !_.isUndefined(build.failures.value)){
					doc.fontSize(15).text('Failures', {underline:true, continued: true}).text(': '+build.failures.value, {underline:false});
				}else{
					doc.fontSize(15).text('Failures', {underline:true, continued: true}).text(': Not Available', {underline:false});
				}
				doc.moveDown();
				if(!_.isUndefined(build.errors) && !_.isUndefined(build.errors.value)){
					doc.fontSize(15).text('Errors', {underline:true, continued: true}).text(': '+build.errors.value, {underline:false});
				}else{
					doc.fontSize(15).text('Errors', {underline:true, continued: true}).text(': Not Available', {underline:false});
				}
				//Table of Content
				doc.addPage();
				doc.fillColor('black').fontSize(20).text('Table of Content');
				doc.moveDown();
				
				//Summary
				doc.addPage();
				var summaryPage = doc.bufferedPageRange().count -1;
				var initialYAxis = 150;
				doc.fontSize(30).fillColor('black').text('Summary');
				doc.rect(75, initialYAxis, 200, 25).fillAndStroke("#F0F0F0", "black");
				doc.rect(275, initialYAxis, 50, 25).fillAndStroke("#F0F0F0", "black");
				doc.rect(325, initialYAxis, 50, 25).fillAndStroke("#F0F0F0", "black");
				doc.rect(375, initialYAxis, 50, 25).fillAndStroke("#F0F0F0", "black");
				doc.rect(425, initialYAxis, 50, 25).fillAndStroke("#F0F0F0", "black");
				doc.rect(475, initialYAxis, 50, 25).fillAndStroke("#F0F0F0", "black");
				doc.fontSize(8).fillColor('black').text('Functional Areas', 80, initialYAxis + 5);
				doc.fontSize(8).fillColor('black').text('Tests', 280, initialYAxis + 5);
				doc.fontSize(8).fillColor('black').text('Passes', 330, initialYAxis + 5);
				doc.fontSize(8).fillColor('black').text('Regressions', 380, initialYAxis + 5);
				doc.fontSize(8).fillColor('black').text('Failures', 430, initialYAxis + 5);
				doc.fontSize(8).fillColor('black').text('Errors', 480, initialYAxis + 5);
				var totalTests = 0;
				var totalPasses = 0;
				var totalRegressions = 0;
				var totalFailures = 0;
				var totalErrors = 0;

				var rowPerPage = 20;
				var pageIndex = 1;
				for(var i = 1; i <= reports.length; i++){
					if(pageIndex % rowPerPage == 0){
						doc.addPage();
						pageIndex = 1;
						rowPerPage = 25;
						initialYAxis = 50; 
					}
					doc.rect(75, initialYAxis+(pageIndex*25), 200, 25).fillAndStroke("white", "black");
					doc.rect(275, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("white", "black");
					doc.rect(325, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("white", "black");
					if(reports[i-1].tests.regressions.value != 0){
						doc.rect(375, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#990000", "black");
					}else{
						doc.rect(375, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#669966", "black");
					}
					if(reports[i-1].tests.failures.value != 0){
						doc.rect(425, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#990000", "black");
					}else{
						doc.rect(425, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#669966", "black");
					}
					if(reports[i-1].tests.errors.value != 0){
						doc.rect(475, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#990000", "black");
					}else{
						doc.rect(475, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#669966", "black");
					}
					
					doc.fontSize(9).fillColor('black').text(reports[i-1].name, 80, initialYAxis+(pageIndex*25)+5);
					doc.fontSize(9).fillColor('black').text(reports[i-1].tests.all.value, 280, initialYAxis+(pageIndex*25)+5);
					doc.fontSize(9).fillColor('black').text(reports[i-1].tests.passes.value, 330, initialYAxis+(pageIndex*25)+5);
					doc.fontSize(9).fillColor('black').text(reports[i-1].tests.regressions.value, 380, initialYAxis+(pageIndex*25)+5);
					doc.fontSize(9).fillColor('black').text(reports[i-1].tests.failures.value, 430, initialYAxis+(pageIndex*25)+5);
					doc.fontSize(9).fillColor('black').text(reports[i-1].tests.errors.value, 480, initialYAxis+(pageIndex*25)+5);
					
					totalTests += reports[i-1].tests.all.value;
					totalPasses += reports[i-1].tests.passes.value;
					totalRegressions += reports[i-1].tests.regressions.value;
					totalFailures += reports[i-1].tests.failures.value;
					totalErrors += reports[i-1].tests.errors.value;
					
					pageIndex++;
				}
				doc.rect(75, initialYAxis+(pageIndex*25), 200, 25).fillAndStroke("#F0F0F0", "black");
				doc.rect(275, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("white", "black");
				doc.rect(325, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("white", "black");
				if(totalRegressions != 0){
					doc.rect(375, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#990000", "black");
				}else{
					doc.rect(375, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#669966", "black");
				}
				if(totalFailures != 0){
					doc.rect(425, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#990000", "black");
				}else{
					doc.rect(425, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#669966", "black");
				}
				if(totalErrors != 0){
					doc.rect(475, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#990000", "black");
				}else{
					doc.rect(475, initialYAxis+(pageIndex*25), 50, 25).fillAndStroke("#669966", "black");
				}
				doc.fontSize(9).fillColor('black').text("Total", 80, initialYAxis+(pageIndex*25)+5);
				doc.fontSize(9).fillColor('black').text(totalTests, 280, initialYAxis+(pageIndex*25)+5);
				doc.fontSize(9).fillColor('black').text(totalPasses, 330, initialYAxis+(pageIndex*25)+5);
				doc.fontSize(9).fillColor('black').text(totalRegressions, 380, initialYAxis+(pageIndex*25)+5);
				doc.fontSize(9).fillColor('black').text(totalFailures, 430, initialYAxis+(pageIndex*25)+5);
				doc.fontSize(9).fillColor('black').text(totalErrors, 480, initialYAxis+(pageIndex*25)+5);
				
				//Tests results per reports
				doc.addPage();
				var reportPage = doc.bufferedPageRange().count -1;
				doc.fontSize(30).fillColor('black').text('Results by Functional Area');
				for(var i = 0; i < reports.length; i++){
					doc.addPage();	
					doc.fontSize(20).fillColor('black').text(reports[i].name, {underline:false});
					doc.moveDown();
					doc.fontSize(10).fillColor('black').text('Tests', {underline:true, continued: true}).text(': '+reports[i].tests.all.value+", ", {underline:false, continued: true})
					.text('Pass', {underline:true, continued: true}).text(': '+(reports[i].tests.all.value - reports[i].tests.regressions.value)+", ", {underline:false, continued: true})
					.text('Failures', {underline:true, continued: true}).text(': '+reports[i].tests.regressions.value+", ", {underline:false, continued: true})
					.text('Run Time', {underline:true, continued: true}).text(': '+batam_util.durationToStr(reports[i].duration.value), {underline:false});
					doc.moveDown();
					doc.fontSize(10).text(reports[i].description, {underline:false});
					
					doc.rect(60, 200, 380, 25).fillAndStroke("#F0F0F0", "black");
					doc.rect(435, 200, 60, 25).fillAndStroke("#F0F0F0", "black");
					doc.rect(495, 200, 60, 25).fillAndStroke("#F0F0F0", "black");
					doc.fontSize(8).fillColor('black').text('Test Name / Description', 65, 205);
					doc.fontSize(8).fillColor('black').text('Status', 440, 205);
					doc.fontSize(8).fillColor('black').text('Run Time', 500, 205);
					var rowPerPage = 9;
					initialYAxis = 175;
					var pageIndex = 1;
					for(var j = 0; j < tests.length; j++){
						//fetch test that belongs to the current report
						if(tests[j].report_id == reports[i].id){
							if(pageIndex % rowPerPage == 0){
								doc.addPage();
								pageIndex = 1;
								rowPerPage = 12;
								initialYAxis = 50;
							}
						
							if(tests[j].status != 'pass'){
								doc.rect(60, initialYAxis+(pageIndex * 50), 5, 50).fillAndStroke("#990000", "black");
							}else{
								doc.rect(60, initialYAxis+(pageIndex * 50), 5, 50).fillAndStroke("#669966", "black");
							}
							if(pageIndex % 2 == 0){
								doc.rect(65, initialYAxis+(pageIndex * 50), 490, 50).fillAndStroke("white", "black");
							}else{
								doc.rect(65, initialYAxis+(pageIndex * 50), 490, 50).fillAndStroke("#F0F0F0", "black");
							}
								
							if(tests[j].status != 'pass'){
								doc.rect(435, initialYAxis+(pageIndex * 50), 60, 25).fillAndStroke("#990000", "black");
							}else{
								doc.rect(435, initialYAxis+(pageIndex * 50), 60, 25).fillAndStroke("#669966", "black");
							}
							doc.rect(495, initialYAxis+(pageIndex * 50), 60, 25).fillAndStroke("white", "black");
							
							doc.fontSize(6).fillColor('black').text(tests[j].name, 70, initialYAxis + (pageIndex * 50) + 5);
							doc.fontSize(6).fillColor('black').text(tests[j].status, 440, initialYAxis + (pageIndex * 50) + 5);
							doc.fontSize(6).fillColor('black').text(batam_util.durationToStr(tests[j].duration.value), 500, initialYAxis + (pageIndex * 50) + 5);
							
							doc.fontSize(6).fillColor('black').text(tests[j].description == null ? "Description Not Available" : tests[j].description, 70, initialYAxis + (pageIndex * 50) + 30);

							var dynamicFields = 'Criterias: ';
					      	for(var field in tests[j]){
					      		if(field != '_id' &&
					      				field != 'description' &&
					      				field != 'report_id' &&
					      				field != 'name' &&
					      				field != 'start_date' &&
					      				field != 'end_date' &&
					      				field != 'status' &&
					      				field != 'time' &&
					      				field != 'regression' &&
					      				field != 'log' &&
					      				field != 'duration' &&
					      				field != 'steps' &&
					      				field != 'report_name' &&
					      				field != 'build_name' &&
					      				field != 'build_id' &&
					      				field != 'test_suite' &&
					      				field != 'author' &&
					      				field != 'previous_id' &&
					      				field != 'next_id'){
					      			dynamicFields += field+" ";
					      		}
					      	}
					      	doc.fontSize(6).fillColor('black').text(dynamicFields, 70, initialYAxis + (pageIndex * 50) + 40);
							
							pageIndex++;
						}
					}
					//Sub Total
					doc.rect(60, initialYAxis+(pageIndex * 50), 60, 25).fillAndStroke("#F0F0F0", "black");
					doc.rect(120, initialYAxis+(pageIndex * 50), 60, 25).fillAndStroke("#F0F0F0", "black");
					doc.rect(180, initialYAxis+(pageIndex * 50), 60, 25).fillAndStroke("#F0F0F0", "black");
					doc.rect(240, initialYAxis+(pageIndex * 50), 60, 25).fillAndStroke("#F0F0F0", "black");
					doc.rect(300, initialYAxis+(pageIndex * 50), 60, 25).fillAndStroke("#F0F0F0", "black");
					doc.fontSize(9).fillColor('black').text('Total', 65, initialYAxis+(pageIndex  * 50) + 5);
					doc.fontSize(9).fillColor('black').text('Pass', 125, initialYAxis+(pageIndex  * 50) + 5);
					doc.fontSize(9).fillColor('black').text('Regressions', 185, initialYAxis+(pageIndex  * 50) + 5);
					doc.fontSize(9).fillColor('black').text('Failues', 245, initialYAxis+(pageIndex  * 50) + 5);
					doc.fontSize(9).fillColor('black').text('Errors', 305, initialYAxis+(pageIndex  * 50) + 5);
					doc.rect(60, initialYAxis+((pageIndex + 1) * 50) - 25, 60, 25).fillAndStroke("white", "black");
					doc.rect(120, initialYAxis+((pageIndex + 1) * 50) - 25, 60, 25).fillAndStroke("white", "black");
					if(reports[i].tests.regressions.value != 0){
						doc.rect(180, initialYAxis+((pageIndex + 1) * 50) - 25, 60, 25).fillAndStroke("#990000", "black");
					}else{
						doc.rect(180, initialYAxis+((pageIndex + 1) * 50) - 25, 60, 25).fillAndStroke("#669966", "black");
					}
					if(reports[i].tests.failures.value != 0){
						doc.rect(240, initialYAxis+((pageIndex + 1) * 50) - 25, 60, 25).fillAndStroke("#990000", "black");
					}else{
						doc.rect(240, initialYAxis+((pageIndex + 1) * 50) - 25, 60, 25).fillAndStroke("#669966", "black");
					}
					if(reports[i].tests.errors.value != 0){
						doc.rect(300, initialYAxis+((pageIndex + 1) * 50) - 25, 60, 25).fillAndStroke("#990000", "black");
					}else{
						doc.rect(300, initialYAxis+((pageIndex + 1) * 50) - 25, 60, 25).fillAndStroke("#669966", "black");
					}
					doc.fontSize(10).fillColor('black').text(reports[i].tests.all.value, 65, initialYAxis+((pageIndex + 1)  * 50) - 25 + 5);
					doc.fontSize(10).fillColor('black').text(reports[i].tests.passes.value, 125, initialYAxis+((pageIndex + 1)  * 50) - 25 + 5);
					doc.fontSize(10).fillColor('black').text(reports[i].tests.regressions.value, 185, initialYAxis+((pageIndex + 1)  * 50) - 25 + 5);
					doc.fontSize(10).fillColor('black').text(reports[i].tests.failures.value, 245, initialYAxis+((pageIndex + 1)  * 50) - 25 + 5);
					doc.fontSize(10).fillColor('black').text(reports[i].tests.errors.value, 305, initialYAxis+((pageIndex + 1)  * 50) - 25 + 5);
				}
				
				//Failing test log messages
				doc.addPage();
				var logPage = doc.bufferedPageRange().count -1;
				initialYAxis = 150;
				doc.fontSize(30).fillColor('black').text('Message Logs');
				for(var i = 0; i < reports.length; i++){
					doc.addPage();	
					doc.fontSize(20).fillColor('black').text(reports[i].name);
					doc.moveDown();
					doc.fontSize(12).fillColor('black').text('Tests', {underline:true, continued: true}).text(': '+reports[i].tests.all.value, {underline:false});
					doc.fontSize(12).fillColor('black').text('Pass', {underline:true, continued: true}).text(': '+(reports[i].tests.passes.value), {underline:false});
					doc.fontSize(12).fillColor('black').text('Regressions', {underline:true, continued: true}).text(': '+(reports[i].tests.regressions.value), {underline:false});
					doc.fontSize(12).fillColor('black').text('Failures', {underline:true, continued: true}).text(': '+reports[i].tests.failures.value, {underline:false});
					doc.fontSize(12).fillColor('black').text('Errors', {underline:true, continued: true}).text(': '+reports[i].tests.errors.value, {underline:false});
					doc.fontSize(12).fillColor('black').text('Run Time', {underline:true, continued: true}).text(': '+batam_util.durationToStr(reports[i].duration.value), {underline:false});
					doc.moveDown();
					doc.fontSize(9).text(reports[i].description == null ? "No description available" : reports[i].description, {underline:false});
						
					for(var j = 0; j < tests.length; j++){
						//fetch test that belongs to the current report
						if(tests[j].report_id == reports[i].id){
							doc.addPage();
							doc.fontSize(10).fillColor('black').text('Test Name', {underline:true, continued: true}).text(": "+tests[j].name, {underline:false});
							doc.moveDown();
							doc.fontSize(9).text(tests[j].description == null ? "No description available" : tests[j].description, {underline:false, continued: false});
							
							doc.rect(100, initialYAxis+(0 * 25), 100, 25).fillAndStroke("#F0F0F0", "black");
							if(tests[j].status != 'pass'){
								doc.rect(200, initialYAxis+(0 * 25), 300, 25).fillAndStroke("#990000", "black");
							}else{
								doc.rect(200, initialYAxis+(0 * 25), 300, 25).fillAndStroke("#669966", "black");
							}			
							doc.fontSize(9).fillColor('black').text("Status", 105, 150 + (0 * 25) + 5);
							doc.fontSize(9).fillColor('black').text(tests[j].status, 205, 150 + (0 * 25) + 5);
							
							doc.rect(100, initialYAxis+(1 * 25), 100, 25).fillAndStroke("#F0F0F0", "black");
							doc.rect(200, initialYAxis+(1 * 25), 300, 25).fillAndStroke("white", "black");			
							doc.fontSize(9).fillColor('black').text("Start Time", 105, 150 + (1 * 25) + 5);
							doc.fontSize(9).fillColor('black').text(tests[j].start_date+" ms", 205, 150 + (1 * 25) + 5);
							
							doc.rect(100, initialYAxis+(2 * 25), 100, 25).fillAndStroke("#F0F0F0", "black");
							doc.rect(200, initialYAxis+(2 * 25), 300, 25).fillAndStroke("white", "black");			
							doc.fontSize(9).fillColor('black').text("Duration", 105, 150 + (2 * 25) + 5);
							doc.fontSize(9).fillColor('black').text(batam_util.durationToStr(tests[j].duration.value), 205, 150 + (2 * 25) + 5);
							
							doc.moveDown();
							doc.fontSize(12).fillColor('black').text("Logs:", 65, 250);
							doc.fontSize(8).text(tests[j].log == null ? '' : tests[j].log);
								
						}
					}
				}
				
				//Finish table of content
				doc.switchToPage(1);
				doc.moveDown();
				doc.fillColor('black').fontSize(12).text('Summary',75, 150);
				doc.fillColor('black').fontSize(12).text('Page '+summaryPage, 450, 150);
				doc.fillColor('black').fontSize(12).text('Results By Functional Area',75, 170);
				doc.fillColor('black').fontSize(12).text('Page '+reportPage, 450, 170);
				doc.fillColor('black').fontSize(12).text('Results By Test',75, 190);
				doc.fillColor('black').fontSize(12).text('Page '+logPage, 450, 190);
				
				//Add page numbers
				var range = doc.bufferedPageRange();
				for(var i = range.start; i < range.start + range.count; i++){
					if(i != 0){
						doc.switchToPage(i);
						doc.fontSize(8).text("Page "+(i + 1)+" of "+range.count, 470, 700);
					}
				}
				
				
				// end and display the document in the iframe to the right
				doc.end();
			};
Example #3
0
module.exports = function(danfe, args, callback) {
    if(typeof args === 'function') {
        callback = args;
        args = pdfDefaults;
    }

    args = merge(pdfDefaults, args);

    var emitente = danfe.getEmitente(),
        destinatario = danfe.getDestinatario(),
        transportador = danfe.getTransportador(),
        impostos = danfe.getImpostos(),
        volumes = danfe.getVolumes(),
        protocolo = danfe.getProtocolo(),
        itens = danfe.getItens(),
        fatura = danfe.getFatura(),
        alturaDoBlocoFaturaDuplicatas = 0,
        duplicatas = danfe.getDuplicatas(),
        pdf = new Pdf({
            bufferPages: true,
            margin: 0,
            size: [
                args.larguraDaPagina,
                args.alturaDaPagina
            ],
            info: {
                Author: args.autor,
                Title: args.titulo,
                Creator: args.criador,
                Producer: 'http://github.com/brasil-js/danfe'
            }
        }),
        pdfTemporario = new Pdf({
            //TODO: Verificar se a criação deste pdf temporario
            //      está causando problemas de performance
            margin: 0,
            size: [
                args.larguraDaPagina,
                args.alturaDaPagina
            ]
        }),
        deveExibirQuadroDeCalculoDoIssqn =
            danfe.getValorTotalDosServicos() ||
            impostos.getBaseDeCalculoDoIssqn() ||
            impostos.getValorTotalDoIssqn();

    if(args.stream) {
        pdf.pipe(args.stream);
    }

    pdf.registerFont('normal', timesNewRoman);
    pdf.registerFont('negrito', timesNewRomanNegrito);
    pdf.registerFont('italico', timesNewRomanItalico);
    pdf.registerFont('negrito-italico', timesNewRomanNegritoItalico);
    pdf.registerFont('codigoDeBarras', barcode.code128.font);
    pdfTemporario.registerFont('normal', timesNewRoman);

    ///////// LAYOUT

    var grossuraDaLinha = 0.5,
        margemTopo = 2.8,
        margemEsquerda = 3,
        margemDireita = 589.65,
        larguraDoFormulario = margemDireita - margemEsquerda;

    pdf.lineWidth(grossuraDaLinha);

    function linhaHorizontal(x1, x2, y, cor) {
        y = margemTopo + args.ajusteY + y;
        x1 = margemEsquerda + args.ajusteX + x1;
        x2 = margemDireita + args.ajusteX + x2;

        return pdf.moveTo(x1, y).lineTo(x2, y).stroke();
    }

    function linhaHorizontalTracejada(x1, x2, y) {
        y = margemTopo + args.ajusteY + y;
        x1 = margemEsquerda + args.ajusteX + x1;
        x2 = margemDireita + args.ajusteX + x2;

        return pdf.moveTo(x1, y).lineTo(x2, y).dash(3, { space: 5 }).stroke();
    }

    function linhaVertical(y1, y2, x, cor) {
        x = margemEsquerda + args.ajusteX + x;
        y1 = margemTopo + args.ajusteY + y1;
        y2 = margemTopo + args.ajusteY + y2;

        return pdf.moveTo(x, y1).lineTo(x, y2).stroke();
    }

    function secao(string, x, y, largura, alinhamento, tamanho) {
        string = string || '';

        x = margemEsquerda + args.ajusteX + x;
        y = margemTopo + args.ajusteY + y;
        pdf.font('negrito')
            .fillColor(args.corDaSecao)
            .fontSize(tamanho || args.tamanhoDaFonteDaSecao)
            .text(string.toUpperCase(), x, y, {
                width: largura,
                align: 'left'
            });
    }

    function titulo(string, x, y, largura, alinhamento, tamanho) {
        string = typeof string !== 'undefined' && string !== null && string.toString() || '';

        x = margemEsquerda + args.ajusteX + x;
        y = margemTopo + args.ajusteY + y;

        pdf.font('normal')
            .fillColor(args.corDoTitulo)
            .fontSize(tamanho || args.tamanhoDaFonteDoTitulo)
            .text(string.toUpperCase(), x, y, {
                width: largura,
                align: alinhamento || args.alinhamentoDoTitulo
            });
    }

    function normal(string, x, y, largura, alinhamento, tamanho, _pdf) {
        string = string || '';

        (_pdf || pdf).font('normal')
            .fillColor(args.corDoTitulo)
            .fontSize(tamanho || 8)
            .text(string,
                margemEsquerda + args.ajusteX + x,
                margemTopo + args.ajusteY + y, {
                width: largura,
                align: alinhamento || 'center',
                lineGap: -1.5
            });
    }

    function italico(string, x, y, largura, alinhamento, tamanho) {
        string = string || '';

        pdf.font('italico')
            .fillColor(args.corDoTitulo)
            .fontSize(tamanho || 6)
            .text(string,
                margemEsquerda + args.ajusteX + x,
                margemTopo + args.ajusteY + y, {
                width: largura,
                align: alinhamento || 'center',
                lineGap: -1.5
            });
    }

    function negrito(string, x, y, largura, alinhamento, tamanho) {
        string = string || '';

        pdf.font('negrito')
            .fillColor(args.corDoTitulo)
            .fontSize(tamanho || 6)
            .text(string,
                margemEsquerda + args.ajusteX + x,
                margemTopo + args.ajusteY + y, {
                width: largura,
                align: alinhamento || 'center',
                lineGap: -1.5
            });
    }

    function campo(string, x, y, largura, alinhamento, tamanho) {
        string = string || '';

        pdf.font('negrito')
            .fillColor(args.corDoCampo)
            .fontSize(tamanho || args.tamanhoDaFonteDoCampo)
            .text(string,
                margemEsquerda + args.ajusteX + x,
                margemTopo + args.ajusteY + y, {
                width: largura,
                align: alinhamento || args.alinhamentoDoCampo
            });
    }

    function desenharPagina() {
        if(args.ambiente !== 'producao') {
            pdf.font('normal')
                .fillColor(args.corDoTitulo)
                .fontSize(50)
                .fillOpacity(args.opacidadeDaHomologacao)
                .text('HOMOLOGAÇÃO',
                    margemEsquerda + args.ajusteX + 0,
                    margemTopo + args.ajusteY + 400 + args.ajusteYDaHomologacao, {
                    width: larguraDoFormulario,
                    align: 'center'
                });

            pdf.font('normal')
                .fillColor(args.corDoTitulo)
                .fontSize(25)
                .fillOpacity(args.opacidadeDaHomologacao)
                .text('SEM VALOR FISCAL',
                    margemEsquerda + args.ajusteX + 0,
                    margemTopo + args.ajusteY + 450 + args.ajusteYDaHomologacao, {
                    width: larguraDoFormulario,
                    align: 'center'
                });
        }

        //RECIBO
        linhaHorizontal(0, 0, 0);
        linhaHorizontal(0, -110.5, 28.3);
        linhaHorizontal(0, 0, 51.1);

        linhaVertical(0, 51.1, 0);
        linhaVertical(28.3, 51.1, 99.2);
        linhaVertical(0, 51.1, 476);
        linhaVertical(0, 51.1, 0);
        linhaVertical(0, 51.1, larguraDoFormulario);

        //PRIMEIRO BLOCO
        //QUADRADO DO TIPO (ENTRADA OU SAIDA)
        linhaHorizontal(317.4, -255, 96.4);
        linhaVertical(96.4,  116.2, 317.4);
        linhaHorizontal(317.4, -255, 116.2);
        linhaVertical(96.4,  116.2, 331.55);

        linhaHorizontal(0, 0, 59.55);
        linhaHorizontal(340.05, 0, 104.8);
        linhaHorizontal(340.05, 0, 127.4);
        linhaHorizontal(0, 0, 150.2);
        linhaHorizontal(0, 0, 170);
        linhaHorizontal(0, 0, 190);

        linhaVertical(59.55, 190, 0);
        linhaVertical(59.55, 150.2, 240.75);
        linhaVertical(59.55, 170, 340.05);
        linhaVertical(59.55, 190, larguraDoFormulario);
        linhaVertical(170, 190, 195.55);
        linhaVertical(170, 190, 391);

        //SEGUNDO BLOCO
        linhaHorizontal(0, 0, 201.2);
        linhaHorizontal(0, 0, 221);
        linhaHorizontal(0, 0, 241);
        linhaHorizontal(0, 0, 261);

        linhaVertical(201.2, 261, 0);
        linhaVertical(201.2, 221, 357.1);
        linhaVertical(221, 261, 274.9);
        linhaVertical(241, 261, 297.6);
        linhaVertical(221, 261, 396.75);
        linhaVertical(201.2, 261, 493.1);
        linhaVertical(201.2, 261, larguraDoFormulario);

        //TERCEIRO BLOCO
        linhaHorizontal(0, 0, 269);
        linhaHorizontal(0, 0, 289);
        linhaHorizontal(0, 0, 309);

        linhaVertical(269, 309, 0);
        linhaVertical(269, 309, 87.7);
        linhaVertical(269, 309, (87.7 * 2) + 0.3);
        linhaVertical(269, 309, (87.7 * 3) + 0.4);
        linhaVertical(269, 309, (87.7 * 4) + 0.4);
        linhaVertical(269, 309, (87.7 * 5) + 0.6);
        linhaVertical(269, 309, (87.7 * 5) + 51.8);
        linhaVertical(269, 309, larguraDoFormulario);

        //QUARTO BLOCO
        linhaHorizontal(0, 0, 320);
        linhaHorizontal(0, 0, 340);
        linhaHorizontal(0, 0, 360);
        linhaHorizontal(0, 0, 380);

        linhaVertical(320, 380, 0);
        linhaVertical(320, 340, 170);
        linhaVertical(320, 340, 346);
        linhaVertical(320, 360, 434);
        linhaVertical(320, 360, 456.65);
        linhaVertical(320, 380, 258);
        linhaVertical(360, 380, 59.6);
        linhaVertical(360, 380, 158.6);
        linhaVertical(360, 380, 357);
        linhaVertical(360, 380, 473.3);
        linhaVertical(320, 380, larguraDoFormulario);

        //QUINTO BLOCO - LISTA DE PRODUTOS
        var alturaInicialDoQuadroDeItens = 391,
            alturaInicialDoQuadroDeDuplicatas = alturaInicialDoQuadroDeItens,
            alturaDeLinhaDeDuplicata = 23,
            duplicatasPorLinha = 8,
            larguraDaDuplicata = larguraDoFormulario / duplicatasPorLinha,
            segundaLinhaDoQuadroDeItens,
            linhasDeDuplicatas = 0;

        if(fatura) {
            alturaDoBlocoFaturaDuplicatas += args.tamanhoDaFonteDoTitulo;
            alturaInicialDoQuadroDeDuplicatas += 6.5;
        }

        if(duplicatas.length) {
            linhasDeDuplicatas = Math.ceil(duplicatas.length / duplicatasPorLinha);
            alturaDoBlocoFaturaDuplicatas += (linhasDeDuplicatas * alturaDeLinhaDeDuplicata) + 10;
        } else {
            alturaDoBlocoFaturaDuplicatas += args.tamanhoDaFonteDoTitulo + 3;
        }

        duplicatas = gammautils.array.chop(duplicatas, duplicatasPorLinha);

        var margemDeCimaDaDuplicata = 2,
            margemEsquerdaDaDuplicata = 2,
            larguraDaDuplicataComMargem = larguraDaDuplicata - margemEsquerdaDaDuplicata - 1;

        duplicatas.forEach(function(linha, indiceDaLinha) {
            var x1, x2, y;

            linha.forEach(function(duplicata, indiceDaDuplicata) {
                x1 = indiceDaDuplicata * larguraDaDuplicata;
                x2 = x1 + larguraDaDuplicata - larguraDoFormulario;
                y = alturaInicialDoQuadroDeDuplicatas + (indiceDaLinha * alturaDeLinhaDeDuplicata);

                linhaHorizontal(x1, x2, y);
                linhaVertical(y, y + alturaDeLinhaDeDuplicata, x1);

                titulo('NÚM.', x1 + margemEsquerdaDaDuplicata, y + margemDeCimaDaDuplicata, larguraDaDuplicataComMargem);
                titulo(duplicata.getNumero(), x1 + margemEsquerdaDaDuplicata, y + margemDeCimaDaDuplicata, larguraDaDuplicataComMargem, 'right');

                titulo('VENC.', x1 + margemEsquerdaDaDuplicata, y + margemDeCimaDaDuplicata + args.tamanhoDaFonteDoTitulo, larguraDaDuplicataComMargem, 'left');
                titulo(duplicata.getVencimentoFormatado(), x1 + margemEsquerdaDaDuplicata, y + margemDeCimaDaDuplicata + args.tamanhoDaFonteDoTitulo, larguraDaDuplicataComMargem, 'right');

                titulo('VALOR', x1 + margemEsquerdaDaDuplicata, y + margemDeCimaDaDuplicata + (2 * args.tamanhoDaFonteDoTitulo), larguraDaDuplicataComMargem, 'left');
                titulo(duplicata.getValorFormatado(), x1 + margemEsquerdaDaDuplicata, y + margemDeCimaDaDuplicata + (2 * args.tamanhoDaFonteDoTitulo), larguraDaDuplicataComMargem, 'right');
            });

            linhaVertical(y, y + alturaDeLinhaDeDuplicata, x1 + larguraDaDuplicata);
            linhaHorizontal(0, x2, y + alturaDeLinhaDeDuplicata);
        });

        //

        alturaInicialDoQuadroDeItens += alturaDoBlocoFaturaDuplicatas;
        segundaLinhaDoQuadroDeItens = alturaInicialDoQuadroDeItens + 14.2;

        linhaHorizontal(0, 0, alturaInicialDoQuadroDeItens);
        linhaHorizontal(0, 0, segundaLinhaDoQuadroDeItens);
        linhaHorizontal(0, 0, 751);

        linhaVertical(alturaInicialDoQuadroDeItens, 751, 0);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 53.8);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 235.3);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 269.3);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 292);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 314.5);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 331.6);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 371.2);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 405.4);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 439.3);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 473.2);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 507.2);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 535.6);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, 555.4);
        linhaVertical(alturaInicialDoQuadroDeItens, 751, larguraDoFormulario);

        var alturaInicialDoSetimoBloco = 793.6;

        //SEXTO BLOCO
        if(deveExibirQuadroDeCalculoDoIssqn) {
            linhaHorizontal(0, 0, 762.2);
            linhaHorizontal(0, 0, 782.2);

            linhaVertical(762.2, 782.2, 0);
            linhaVertical(762.2, 782.2, 136.1);
            linhaVertical(762.2, 782.2, (136.1 * 2) - 0.1);
            linhaVertical(762.2, 782.2, (136.1 * 3) - 0.1);
            linhaVertical(762.2, 782.2, larguraDoFormulario);
        } else {
            alturaInicialDoSetimoBloco = 762.2;
        }

        // SÉTIMO BLOCO
        linhaHorizontal(0, 0, alturaInicialDoSetimoBloco); // x1, x2, y
        linhaHorizontal(0, 0, 821.8);

        linhaVertical(alturaInicialDoSetimoBloco, 821.8, 0);
        linhaVertical(alturaInicialDoSetimoBloco, 821.8, 388.25);
        linhaVertical(alturaInicialDoSetimoBloco, 821.8, larguraDoFormulario);

        //  Deve ser a última linha pois não estou conseguindo
        //  retirar o tracejado após utiliza-lo pela primeira vez
        linhaHorizontalTracejada(0, 0, 55.32);

        // MARGENS DA IMPRESSORA (ÚTIL PARA DEBUG)
        // linhaHorizontal(0, args.larguraDaPagina, 18, 'red');
        // linhaHorizontal(0, args.larguraDaPagina, args.alturaDaPagina - 18, 'red');
        // linhaVertical(0, args.alturaDaPagina, 18, 'red');
        // linhaVertical(0, args.alturaDaPagina, args.larguraDaPagina - 22, 'red');

        normal([
            'Recebemos de',
            emitente.getNome(),
            'os produtos e/ou serviços constantes da nota',
            'fiscal eletrônica indicada abaixo.',
            'Emissão:',
            danfe.getDataDaEmissaoFormatada(),
            '- Valor Total:',
            danfe.getValorTotalDaNotaFormatado(),
            '- Destinatário:',
            destinatario.getNome(),
            '- Endereço:',
            destinatario.getEndereco().getPrimeiraLinha()
        ].join(' ').toUpperCase(), 1.5, 3, 472.5, 'justify', 6.9);

        titulo('DANFE', 266.5, 63.5, 197, 'left', 14);
        normal('NF-e', 476.6, 1.8, 110, 'center', 14);
        normal(danfe.getNumeroFormatado(), 476.6, 22, 110, 'center', 10);
        normal(danfe.getSerieFormatada(), 476.6, 31.5, 110, 'center', 10);

        italico('IDENTIFICAÇÃO DO EMITENTE', 1, 60, 238);

        var temLogotipo = emitente.getLogotipo(),
            identificacaoDoEmitenteY = temLogotipo ? 78 : 84,
            identificacaoDoEmitenteX = temLogotipo ? 67 : 1.5,
            identificacaoDoEmitenteLargura = temLogotipo ? 172 : 237,//
            identificacaoDoEmitenteFonte = temLogotipo ? 0 : 1.5;

        if(temLogotipo) {
            var caminhoDoLogotipo = emitente.getLogotipo();
            pdf.image(caminhoDoLogotipo, margemEsquerda + args.ajusteX + 4.5, margemTopo + args.ajusteY + args.ajusteYDoLogotipo + 78, {
                fit: [60, 60]
            });
        }

        negrito(emitente.getNome(), identificacaoDoEmitenteX, identificacaoDoEmitenteY + args.ajusteYDaIdentificacaoDoEmitente, identificacaoDoEmitenteLargura, 'center', 8 + identificacaoDoEmitenteFonte);

        if(emitente.getEndereco().getPrimeiraLinha()) {
            normal(emitente.getEndereco().getPrimeiraLinha(),
                identificacaoDoEmitenteX,
                pdf.y - margemTopo + 2,
            identificacaoDoEmitenteLargura, 'center', 6 + identificacaoDoEmitenteFonte);
        }

        if(emitente.getEndereco().getSegundaLinha()) {
            normal(emitente.getEndereco().getSegundaLinha(),
                identificacaoDoEmitenteX,
                pdf.y - margemTopo,
            identificacaoDoEmitenteLargura, 'center', 6 + identificacaoDoEmitenteFonte);
        }

        var jaAdicionouEspacamento = false;

        if(emitente.getTelefone()) {
            jaAdicionouEspacamento = true;

            normal('Telefone: ' + emitente.getTelefoneFormatado(),
                identificacaoDoEmitenteX,
                pdf.y - margemTopo + 2,
            identificacaoDoEmitenteLargura, 'center', 6 + identificacaoDoEmitenteFonte);
        }

        if(emitente.getEmail()) {
            normal('Email: ' + emitente.getEmail(),
                identificacaoDoEmitenteX,
                pdf.y - margemTopo + (jaAdicionouEspacamento ? 0 : 2),
            identificacaoDoEmitenteLargura, 'center', 6 + identificacaoDoEmitenteFonte);
        }

        normal('Documento Auxiliar da Nota Fiscal Eletrônica', 241.5, 77, 99.5);

        normal('0 - ENTRADA', 248, 100, 99.5, 'left');
        normal('1 - SAÍDA', 248, 108.5, 99.5, 'left');
        negrito(danfe.getTipoFormatado(), 317.5, 96.8, 14.5, 'center', 18);

        // CAMPO OPCIONAL 1 - FSDA
        var formularioDeSeguranca = danfe.getFormularioDeSeguranca();

        if(protocolo.getFormatacao()) {
            normal('Consulta de autenticidade no portal nacional da NF-e', 340.5, 130, 244);
            normal('www.nfe.fazenda.gov.br/portal ou no site da Sefaz Autorizadora', 340.5, 138, 244);
        } else if(formularioDeSeguranca) {
            pdf.font('codigoDeBarras')
                .fontSize(18.5)
                .text(barcode.code128.encode(formularioDeSeguranca.getDadosDaNfe()), 341.5, 131.5, {
                    align: 'center',
                    width: 250
                });
        }

        var informacoesComplementares = [
            danfe.getInformacoesComplementares()
        ];

        if(formularioDeSeguranca) {
            informacoesComplementares.unshift([
                'DANFE EM CONTINGÊNCIA, ',
                'IMPRESSO EM DECORRÊNCIA DE PROBLEMAS TÉCNICOS: ',
                formularioDeSeguranca.getJustificativa().toUpperCase(),
            ].join(''));
        }

        normal(informacoesComplementares.join(' - '), 1, alturaInicialDoSetimoBloco + 7.5, 386, 'justify', 6);
        normal(danfe.getNumeroFormatado(), 241.2, 119.5, 98.5, 'center', 10);
        normal(danfe.getSerieFormatada(), 241.2, 129.5, 98.5, 'center', 10);

        //RECIBO
        titulo('DATA DE RECEBIMENTO', 1.5, 29, 97);
        titulo('IDENTIFICAÇÃO E ASSINATURA DO RECEBEDOR', 100.5, 29, 374);

        var codigoDeBarrasCodificado = barcode.code128.encode(danfe.getChaveDeAcesso());
        if(danfe.getChaveDeAcesso()) {
            pdf.font('codigoDeBarras')
                .fontSize(args.tamanhoDoCodigoDeBarras)
                .text(codigoDeBarrasCodificado, args.ajusteX + margemEsquerda + 339, args.ajusteY + margemTopo + 65, {
                    align: 'center',
                    width: 249
                });
        }

        //PRIMEIRO BLOCO
        titulo('CHAVE DE ACESSO', 341.5, 105.5, 244);
        campo(danfe.getChaveDeAcessoFormatada(), 341.5, 114, 244);

        if(protocolo.getFormatacao()) {
            titulo('PROTOCOLO DE AUTORIZAÇÃO DE USO', 341.5, 151, 244);
            campo(protocolo.getFormatacao(), 341.5, 158.4, 244);
        } else if(formularioDeSeguranca) {
            titulo('DADOS DA NFE', 341.5, 151, 244);
            campo(formularioDeSeguranca.getDadosDaNfeFormatado(), 341.5, 158.4, 244);
        }

        titulo('NATUREZA DA OPERAÇÃO', 1.5, 151, 338);
        campo(danfe.getNaturezaDaOperacao(), 1.5, 158.4, 338);

        titulo('INSCRIÇÃO ESTADUAL', 1.5, 171, 192.5);
        campo(emitente.getInscricaoEstadual(), 1.5, 178.4, 192.5);

        titulo('INSCRIÇÃO ESTADUAL DO SUBST. TRIBUT.', 197, 171, 192.5);
        campo(danfe.getInscricaoEstadualDoSubstitutoTributario(), 197, 178.4, 192.5);

        titulo('CNPJ', 392.5, 171, 192.5);
        campo(emitente.getRegistroNacionalFormatado(), 392.5, 178.4, 192.5);

        //SEGUNDO BLOCO
        secao('DESTINATÁRIO / REMETENTE', 1.5, 194);
        titulo('NOME / RAZÃO SOCIAL', 1.5, 202, 353.5);
        campo(destinatario.getNome(), 1.5, 210, 353.5, 'left');

        titulo('CNPJ / CPF', 358, 202, 133.5);
        campo(destinatario.getRegistroNacionalFormatado(), 358, 210, 133.5);

        titulo('DATA DA EMISSÃO', 495, 202, 90);
        campo(danfe.getDataDaEmissaoFormatada(), 495, 210, 90);

        titulo('ENDEREÇO', 1.5, 222, 272);
        campo(destinatario.getEndereco().getPrimeiraLinha(), 1.5, 230, 272, 'left', args.tamanhoDaFonteDoCampo - 0.5);

        titulo('BAIRRO / DISTRITO', 276, 222, 119);
        campo(destinatario.getEndereco().getBairro(), 276, 230, 119);

        titulo('CEP', 398, 222, 93);
        campo(destinatario.getEndereco().getCepFormatado(), 398, 230, 93);

        titulo('DATA DA SAÍDA', 495, 222, 90);
        campo(danfe.getDataDaEntradaOuSaidaFormatada(), 495, 230, 90);

        titulo('MUNICÍPIO', 1.5, 242, 272);
        campo(destinatario.getEndereco().getMunicipio(), 1.5, 250, 272, 'left');

        titulo('UF', 276, 242, 20);
        campo(destinatario.getEndereco().getUf(), 276, 250, 20);

        titulo('FONE / FAX', 299, 242, 96);
        campo(destinatario.getTelefoneFormatado(), 299, 250, 96);

        titulo('INSCRIÇÃO ESTADUAL', 398, 242, 93);
        campo(destinatario.getInscricaoEstadual(), 398, 250, 93);

        titulo('HORA DA SAÍDA', 495, 242, 90);
        campo(danfe.getHorarioDaEntradaOuSaida(), 495, 250, 90);

        //TERCEIRO BLOCO
        secao('CÁLCULO DO IMPOSTO', 1.5, 261.5);
        titulo('BASE DE CÁLCULO DO ICMS', 1.5, 270, 84);
        campo(impostos.getBaseDeCalculoDoIcmsFormatada(), 1.5, 278, 84,  'right');

        titulo('VALOR DO ICMS', 89, 270, 84);
        campo(impostos.getValorDoIcmsFormatado(), 89, 278, 84, 'right');

        titulo('BASE DE CÁLC. ICMS S.T.', 177, 270, 84);
        campo(impostos.getBaseDeCalculoDoIcmsStFormatada(), 177, 278, 84, 'right');

        titulo('VALOR DO ICMS SUBST.', 265, 270, 84);
        campo(impostos.getValorDoIcmsStFormatado(), 265, 278, 84, 'right');

        titulo('VALOR IMP. IMPORTAÇÃO', 353, 270, 84);
        campo(impostos.getValorDoImpostoDeImportacaoFormatado(), 353, 278, 84, 'right');

        titulo('VALOR DO PIS', 441, 270, 47);
        campo(impostos.getValorDoPisFormatado(), 441, 278, 47, 'right');

        titulo('VALOR TOTAL DOS PRODUTOS', 492, 270, 93);
        campo(danfe.getValorTotalDosProdutosFormatado(), 492, 278, 93, 'right');

        titulo('VALOR DO FRETE', 1.5, 290, 84);
        campo(danfe.getValorDoFreteFormatado(), 1.5, 298, 84, 'right');

        titulo('VALOR DO SEGURO', 89, 290, 84);
        campo(danfe.getValorDoSeguroFormatado(), 89, 298, 84, 'right');

        titulo('DESCONTO', 177, 290, 84);
        campo(danfe.getDescontoFormatado(), 177, 298, 84, 'right');

        titulo('OUTRAS DESPESAS', 265, 290, 84);
        campo(danfe.getOutrasDespesasFormatado(), 265, 298, 84, 'right');

        titulo('VALOR TOTAL DO IPI', 353, 290, 84);
        campo(impostos.getValorTotalDoIpiFormatado(), 353, 298, 84, 'right');

        titulo('VALOR DA COFINS', 440.5, 290.5, 47, null, args.tamanhoDaFonteDoTitulo - 1);
        campo(impostos.getValorDaCofinsFormatado(), 440.5, 298, 47, 'right');

        titulo('VALOR TOTAL DA NOTA', 492, 290, 93);
        campo(danfe.getValorTotalDaNotaFormatado(false), 492, 298, 93, 'right');

        //QUARTO BLOCO
        secao('TRANSPORTADOR / VOLUMES TRANSPORTADOS', 1.5, 312.5);
        titulo('NOME / RAZÃO SOCIAL', 1.5, 321, 166.5);
        campo(transportador.getNome(), 1.5, 329, 166.5, 'left');

        titulo('FRETE POR CONTA', 171.5, 321, 85);
        campo(danfe.getModalidadeDoFreteFormatada(), 171.5, 329, 85);

        titulo('CÓDIGO ANTT', 259.5, 321, 84);
        campo(transportador.getCodigoAntt(), 259.5, 329, 84);

        titulo('PLACA DO VEÍCULO', 347.5, 321, 84);
        campo(transportador.getPlacaDoVeiculoFormatada(), 347.5, 329, 84);

        titulo('UF', 435.5, 321, 19.5);
        campo(transportador.getUfDaPlacaDoVeiculo(), 435.5, 329, 19.5);

        titulo('CNPJ / CPF', 458, 321, 126.5);
        campo(transportador.getRegistroNacionalFormatado(), 458, 329, 126.5);

        titulo('ENDEREÇO', 1.5, 341, 254);
        campo(transportador.getEndereco().getPrimeiraLinha(), 1.5, 349, 254, 'left', args.tamanhoDaFonteDoCampo - 0.5);

        titulo('MUNICÍPIO', 259.5, 341, 172);
        campo(transportador.getEndereco().getMunicipio(), 259.5, 349, 172);

        titulo('UF', 435.5, 341, 19.5);
        campo(transportador.getEndereco().getUf(), 435.5, 349, 19.5);

        titulo('INSCRIÇÃO ESTADUAL', 458, 341, 126.5);
        campo(transportador.getInscricaoEstadual(), 458, 349, 126.5);

        titulo('QUANTIDADE', 1.5, 361, 56.5);
        campo(volumes.getQuantidadeFormatada(), 1.5, 369, 56.5);

        titulo('ESPÉCIE', 60.8, 361, 96);
        campo(volumes.getEspecie(), 60.8, 369, 96);

        titulo('MARCA', 160, 361, 96);
        campo(volumes.getMarca(), 160, 369, 96);

        titulo('NUMERAÇÃO', 259.5, 361, 96);
        campo(volumes.getNumeracao(), 259.5, 369, 96);

        titulo('PESO BRUTO', 358.5, 361, 112.5);
        campo(volumes.getPesoBruto(), 358.5, 369, 112.5);

        titulo('PESO LÍQUIDO', 474.5, 361, 110.5);
        campo(volumes.getPesoLiquido(), 474.5, 369, 110.5);

        var alturaDaSecaoDosItens = 383,
            alturaDosTitulosDosItens;

        if(fatura || duplicatas.length) {
            secao('FATURA / DUPLICATAS', 1.5, 383);
            alturaDaSecaoDosItens += alturaDoBlocoFaturaDuplicatas;
        }

        if(fatura) {
            var dadosDaFatura = [];

            if(fatura.getNumero()) {
                dadosDaFatura.push('NÚMERO: ' + fatura.getNumero());
            }

            if(fatura.getNumero()) {
                dadosDaFatura.push('VALOR ORIGINAL: ' + fatura.getValorOriginalFormatado());
            }

            if(fatura.getNumero()) {
                dadosDaFatura.push('VALOR DO DESCONTO: ' + fatura.getValorDoDescontoFormatado());
            }

            if(fatura.getNumero()) {
                dadosDaFatura.push('VALOR LÍQUIDO: ' + fatura.getValorLiquidoFormatado());
            }

            if(fatura.getFormaDePagamento()) {
                dadosDaFatura.push('PAGAMENTO: ' + fatura.getFormaDePagamento());
            }

            dadosDaFatura = dadosDaFatura.join(' - ');

            if(dadosDaFatura) {
                negrito(dadosDaFatura, 1.5, 390, larguraDoFormulario, 'left');
            }
        }

        alturaDosTitulosDosItens = alturaDaSecaoDosItens + 12;

        // QUINTO BLOCO - LISTA DE PRODUTOS
        secao('DADOS DOS PRODUTOS / SERVIÇOS', 1.5, alturaDaSecaoDosItens);
        titulo('CÓDIGO', 1.5, alturaDosTitulosDosItens, 50.5, args.alinhamentoDoTituloDaTabela);
        titulo('DESCRIÇÃO DO PRODUTO / SERVIÇO', 55, alturaDosTitulosDosItens, 179, args.alinhamentoDoTituloDaTabela);
        titulo('NCM/SH', 236.5, alturaDosTitulosDosItens, 31.5, args.alinhamentoDoTituloDaTabela);
        titulo('O/CST', 270.5, alturaDosTitulosDosItens, 20, args.alinhamentoDoTituloDaTabela);
        titulo('CFOP', 293.5, alturaDosTitulosDosItens, 19.5, args.alinhamentoDoTituloDaTabela);
        titulo('UN.', 316, alturaDosTitulosDosItens, 14.5, args.alinhamentoDoTituloDaTabela);
        titulo('QUANT.', 333, alturaDosTitulosDosItens, 37, args.alinhamentoDoTituloDaTabela);
        titulo('VALOR UNIT.', 373, alturaDosTitulosDosItens - 4, 31.5, args.alinhamentoDoTituloDaTabela);
        titulo('VALOR TOTAL', 407.5, alturaDosTitulosDosItens - 4, 31.5, args.alinhamentoDoTituloDaTabela);
        titulo('B. CÁLC. ICMS', 441.5, alturaDosTitulosDosItens - 4, 31.5, args.alinhamentoDoTituloDaTabela);
        titulo('VALOR ICMS', 475, alturaDosTitulosDosItens - 4, 31.5, args.alinhamentoDoTituloDaTabela);
        titulo('VALOR IPI', 508, alturaDosTitulosDosItens - 4, 28, args.alinhamentoDoTituloDaTabela);
        titulo('ALÍQ. ICMS', 532, alturaDosTitulosDosItens - 4, 28, args.alinhamentoDoTituloDaTabela);
        titulo('ALÍQ. IPI', 557, alturaDosTitulosDosItens, 28, args.alinhamentoDoTituloDaTabela);

        // SEXTO BLOCO
        if(deveExibirQuadroDeCalculoDoIssqn) {
            secao('CÁLCULO DO ISSQN', 1.5, 754.5);
            titulo('INSCRIÇÃO MUNICIPAL', 1.5, 763, 132.5);
            campo(emitente.getInscricaoMunicipal(), 1.5, 771, 132.5, 'left');

            titulo('VALOR TOTAL DOS SERVIÇOS', 137.5, 763, 132.5);
            campo(danfe.getValorTotalDosServicosFormatado(), 137.5, 771, 132.5, 'right');

            titulo('BASE DE CÁLCULO DO ISSQN', 273.5, 763, 132.5);
            campo(impostos.getBaseDeCalculoDoIssqnFormatada(), 273.5, 771, 132.5, 'right');

            titulo('VALOR TOTAL DO ISSQN', 409.5, 763, 175.5);
            campo(impostos.getValorTotalDoIssqnFormatado(), 409.5, 771, 175.5, 'right');
        }

        var alturaDaSecaoDoSetimoBloco = 786,
            alturaDosTitulosDoSetimoBloco;

        if(!deveExibirQuadroDeCalculoDoIssqn) {
            alturaDaSecaoDoSetimoBloco = 754;
        }

        alturaDosTitulosDoSetimoBloco = alturaDaSecaoDoSetimoBloco + 9;

        // SÉTIMO BLOCO
        secao('DADOS ADICIONAIS', 1.5, alturaDaSecaoDoSetimoBloco);
        titulo('INFORMAÇÕES COMPLEMENTARES', 1.5, alturaDosTitulosDoSetimoBloco, 385);
        titulo('RESERVADO AO FISCO', 390, alturaDosTitulosDoSetimoBloco, 195);

        if(args.creditos) {
            italico(args.creditos, 1.5, 827, larguraDoFormulario);
        }
    }

    desenharPagina();

    var numeroDePaginas = 1,
        yInicialDosItens = 406 + alturaDoBlocoFaturaDuplicatas,
        yDoItemAtual = yInicialDosItens,
        alturaAtual = 0;

    itens.forEach(function(item) {
        function renderizarLinha(pdf) {
            normal(item.getCodigo(), 1.5, yDoItemAtual, 51, 'center', args.tamanhoDaFonteDosItens, pdf);
            var maiorY = pdf.y;

            var descricao = item.getDescricao();
            if(item.getInformacoesAdicionais()) {
                descricao += '\n' + item.getInformacoesAdicionais();
            }

            normal(descricao, 55.5, yDoItemAtual, 178, 'justify', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getNcmSh(), 235.5, yDoItemAtual, 32.5, 'center', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getOCst(), 270, yDoItemAtual, 21, 'center', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getCfop(), 293.5, yDoItemAtual, 21, 'center', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getUnidade(), 315, yDoItemAtual, 16.5, 'center', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getQuantidadeFormatada(), 332.5, yDoItemAtual, 37.5, 'right', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getValorUnitarioFormatado(), 372, yDoItemAtual, 32.5, 'right', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getValorTotalFormatado(), 407, yDoItemAtual, 31, 'right', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getBaseDeCalculoDoIcmsFormatada(), 440, yDoItemAtual, 32.5, 'right', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getBaseDeCalculoDoIcmsFormatada(), 440, yDoItemAtual, 32.5, 'right', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getValorDoIcmsFormatado(), 474.5, yDoItemAtual, 32, 'right', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getValorDoIpiFormatado(), 508.5, yDoItemAtual, 26, 'right', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getAliquotaDoIcmsFormatada(), 536, yDoItemAtual + 0.65, 19, 'center', args.tamanhoDaFonteDosItens - 1, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            normal(item.getAliquotaDoIpiFormatada(), 556.5, yDoItemAtual, 29, 'center', args.tamanhoDaFonteDosItens, pdf);
            maiorY = Math.max(maiorY, pdf.y);

            if(args.separadorDeItens) {
                linhaHorizontalTracejada(0, 0, maiorY);
            }

            return maiorY + (args.separadorDeItens ? 2 : 0);
        }

        var altura = renderizarLinha(pdfTemporario) - yDoItemAtual;

        if(alturaAtual + altura > (751 - yInicialDosItens)) {
            numeroDePaginas += 1;
            pdf.addPage();
            yDoItemAtual = yInicialDosItens;
            alturaAtual = 0;

            desenharPagina();
        }

        renderizarLinha(pdf);


        alturaAtual += altura;
        yDoItemAtual = yDoItemAtual + altura;
    });

    var paginas = pdf.bufferedPageRange();

    for(var i = paginas.start; i < paginas.start + paginas.count; i++) {
        pdf.switchToPage(i);
        italico('FOLHA ' + (i + 1) + '/' + numeroDePaginas, 241.2, 141.2, 98.5, 'center', 8);
    }

    pdf.flushPages();
    pdf.end();

    callback(null, pdf);
};
Example #4
0
        lwip.open(Logo, function(err, image) {
            if (!err) {
                var ratio = 1;
                if (image.width() > widthLogo) ratio = widthLogo / image.width();
                heightLogo = image.height() * ratio;
            } // else no logo or not readable

            // -----------------------------------------------------------------------------
            // START
            var docinfo = {
                Producer: "PDFKit",
                Creator: param.ownerObj.ownerClean + " " + param.ownerObj.companyLegal,
                CreationDate: new Date(),
                Title: (param.quotationObj.quotationType == -1 ? "Devis n° " : "Facture n° ") + param.quotationObj.quotationRef,
                Author: param.ownerObj.username,
                Subject: (param.quotationObj.quotationType == -1 ? "Devis" : "Facture"),
                Keywords: "Devis,Facture," + param.ownerObj.ownerClean,
                ModDate: new Date()
            };
            var thedoc = new pdf( { bufferPages: true, margin: margin, size: "A4", layout: "portrait", info: docinfo });
            addTheHeader(thedoc, param);

            // -----------------------------------------------------------------------------
            // MAIN PART
            addHeaderTable(thedoc, param);

            addContentTable(thedoc, param);

            // can we add Tables on the current page ?
            if ((getHTotalTable() + startTTC >= maxA4Y - margin - 6 * bigSize) || (getHPaymentTable(param) + startTTC >= maxA4Y - margin - 6 * bigSize)) {
                // NO
                console.log("New Page because of total tables");
                // 1 finish last page
                addTheFooter(thedoc, param);
                // 2 start new page
                thedoc.addPage( { margin: margin, size: "A4", layout: "portrait" } );
                range = thedoc.bufferedPageRange();
                thedoc.switchToPage(range.start + range.count - 1); // go to the last page
                addTheHeader(thedoc, param);

                startTTC = startTab + normalSize * 2.5;
            }
            addTotalTable(thedoc, param);
            addPaymentTable(thedoc, param);

            addTheFooter(thedoc, param);


            range = thedoc.bufferedPageRange();

            console.log("RANGE = " + util.inspect(range, false, null));

            // -----------------------------------------------------------------------------
            // FOOTER
            for(var np = range.start; np < range.start + range.count; np++) {
                thedoc.switchToPage(np);
                thedoc.font(normal).fontSize(normalSize).text("Page " + (np + 1) + " / " + range.count, maxA4X - 200 - margin, headerSecondLineY + betweenHeaderTableY, { width: 200, align: 'right' });
            }
            // FINISH
            thedoc.flushPages()
            thedoc.end();
            var docName = "/doc/" + param.quotationObj.quotationRef + "_" + param.quotationObj.quotationVersion + "_" + (new Date().getTime()) + ".pdf";
            thedoc.pipe(fs.createWriteStream("./client" + docName));
            self.insertUpdate(db, { quotationId: param.quotationId, docURL: docName }, function(err, ret) {
                if (ret.msg == "ok") {
                    if (already >= 0) {
                        // delete the old one
                        self.delById(db, { docId: param.quotationObj.quotationDocList[already].docId }, function (err, ret) {} );
                        fs.unlink("./client" + param.quotationObj.quotationDocList[already].docURL);
                    }
                    var generatedDoc = {};
                    lodash.assign(generatedDoc, { quotationId: param.quotationId, quotationRef: param.quotationObj.quotationRef, quotationVersion: param.quotationObj.quotationVersion, quotationCreationDt: (new Date(param.quotationObj.quotationCreationDt)).format("DD-MM-YYYY"), quotationUpdateDt: (new Date(param.quotationObj.quotationUpdateDt)).format("DD-MM-YYYY HH:mm"), quotationEndValidityDt: param.quotationObj.quotationEndValidityDt ? (new Date(param.quotationObj.quotaitonEndValidityDt)).format("DD-MM-YYYY") : null, docId: ret.docId, docURL: docName } );
                    callback(null, generatedDoc);
                } else callback(null, generatedDoc);
            });
        });