carboneio / carbone

Fast and simple report generator, from JSON to pdf, xslx, docx, odt...
https://carbone.io
Other
1.3k stars 193 forks source link

[Bug Report]: Combination of Conditioned output and Repetitions #97

Open Zucka opened 4 years ago

Zucka commented 4 years ago

Environment Carbone Version: 2.1.0 Node Version: 10.15.0 Browsers: none Desktop OS: Windows 10 - 2004

Expected Behaviour In a showBegin / showEnd section it was expected that other functionality like array repetitions would work. Such that if a paragraf is shown then the included repetitions would work.

Actual Behaviour When a showBegin/End pair is surrounding a repetition it gives an error about not being able to find the ending showEnd tag.

Steps to reproduce Steps to reproduce the bug: See the test data. Normal docx file with test code run directly from cli.

Reproduction Link / Code example Test Data

{
    "name": "Testing stuffs",
    "answers": [
        {
            "questionId": "f39c0e75",
            "value": "caba977c",
            "label": "Algeriet"
        },
        {
            "questionId": "f39c0e75",
            "value": "731717d0",
            "label": "Albanien"
        },
        {
            "questionId": "0a73e15d",
            "value": "452badaf",
            "label": "Yes"
        }
    ]
}

Test Document:

{d.answers[questionId='0a73e15d'].label:ifEQ('Yes'):showBegin}
Answers for Question f39c0e75:
•   {d.answers[i, questionId='f39c0e75'].label}
•   {d.answers[i+1, questionId='f39c0e75'].label}
{d.answers[questionId='0a73e15d'].label:ifEQ('Yes'):showEnd}

Test code:

const fs = require('fs');
const carbone = require('carbone');

// data object to inject
const data = require("./test.json")

// options object is used to pass more parameters to carbone render function 
let options = {
  convertTo: 'docx' //can be docx, txt, ...
}
// carbone.render('./DataBehandler.docx', data, options, (err, res) => {
  carbone.render('./test.docx', data, options, (err, res) => {
    if (err) {
      return console.log(err);
    }
    // fs is used to create the PDF file from the render result
    fs.writeFileSync('./result.docx', res);
    process.exit();
});

Error:

C:\Source\pdfTest>node .\pdfTest.js
Error: Missing at least one showEnd or hideEnd
    at findAndSetValidPositionOfConditionalBlocks (C:\Source\pdfTest\node_modules\carbone\lib\extracter.js:609:13)
    at Object.splitXml (C:\Source\pdfTest\node_modules\carbone\lib\extracter.js:373:5)
    at C:\Source\pdfTest\node_modules\carbone\lib\builder.js:43:43
    at Object.preprocessMarkers (C:\Source\pdfTest\node_modules\carbone\lib\parser.js:333:5)
    at C:\Source\pdfTest\node_modules\carbone\lib\builder.js:38:18
    at C:\Source\pdfTest\node_modules\carbone\lib\parser.js:86:7
    at process._tickCallback (internal/process/next_tick.js:61:11)

Other comments Expected output:

Answers for Question f39c0e75:
•   Algeriet
•   Albanien
dgrelaud commented 4 years ago

Ok, thank you for the bug report.

I think it could be fixed in the october sprint.

Zucka commented 3 years ago

Any updates on this?

SekmSet commented 3 years ago

Hello,

I need to make a conditional display. If a product have a specific category I need to display an information.

// My JSON 
const json = {
 "shopping" : {
  "sales": [
   {
     "product_name": "Apple",
     "product_price": 2,
     "product_category": "fruits",
     "comment": "",
   },
  {
     "product_name": "Coke",
     "product_price": 3,
     "product_category": "soda",
     "comment": "",
   },
   {
     "product_name": "Cucumber",
     "product_price": 1.5,
     "product_category": "vegetable",
     "comment": "",
   }, 
   {
     "product_name": "Vodka",
     "product_price": 15,
     "product_category": "Alcohol",
     "comment": "Dangerous for health, prohibited at least 18 years old",
   }, 
 ]
}

What I made on my document : |State | | :------------------------------------------------------------------------------:| |{json.shopping.sales[i].product_name} {json.shopping.sales[i].product_category(“Alcohol”):showBeggin} Information {json.shopping.sales[i].comment}{json.shopping.sales[i].product_category::showEnd}| |{json.shopping.sales[i+1].product_name} |

// OUTPUT expected
Apple
Coke
Vodka Dangerous for health, prohibited at least 18 years old

Is it possible to do this ? Because it's doesn't work and I did'nt find solution … Thank's 🙏

Zucka commented 3 years ago

@SekmSet Although that has nothing to do with the issue I originally described it seems that there might be multiple things wrong with your document specification.

So your JSON is malformed. Let's fix that.

{
  "shopping": {
    "sales": [
      {
        "product_name": "Apple",
        "product_price": 2,
        "product_category": "fruits",
        "comment": ""
      },
      {
        "product_name": "Coke",
        "product_price": 3,
        "product_category": "soda",
        "comment": ""
      },
      {
        "product_name": "Cucumber",
        "product_price": 1.5,
        "product_category": "vegetable",
        "comment": ""
      },
      {
        "product_name": "Vodka",
        "product_price": 15,
        "product_category": "Alcohol",
        "comment": "Dangerous for health, prohibited at least 18 years old"
      }
    ]
  }
}

In Carbone you specify access to the normal Data JSON with "d" so {d.shopping.sales[i=1].product_name} would get you the name of the second element in the sales array. Documentation

One way of doing what you want is the following. ( It at least give the "expected" output you gave )

{d.shopping.sales[i].product_name} {d.shopping.sales[i].product_category:ifEQ('Alcohol'):show(.comment):elseShow()}
{d.shopping.sales[i+1].product_name}

Documentation You can test this with Carbone Studio ( there is a free edition ) https://studio.carbone.io/