{"id":22394173,"url":"https://github.com/atlantis-software/salesdocument","last_synced_at":"2025-10-15T14:31:53.080Z","repository":{"id":53016144,"uuid":"146262520","full_name":"Atlantis-Software/salesDocument","owner":"Atlantis-Software","description":null,"archived":false,"fork":false,"pushed_at":"2021-04-09T14:22:45.000Z","size":897,"stargazers_count":0,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-08T07:51:21.510Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Atlantis-Software.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-27T07:31:09.000Z","updated_at":"2021-04-09T14:22:47.000Z","dependencies_parsed_at":"2022-09-08T08:25:00.614Z","dependency_job_id":null,"html_url":"https://github.com/Atlantis-Software/salesDocument","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Atlantis-Software/salesDocument","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Atlantis-Software%2FsalesDocument","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Atlantis-Software%2FsalesDocument/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Atlantis-Software%2FsalesDocument/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Atlantis-Software%2FsalesDocument/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Atlantis-Software","download_url":"https://codeload.github.com/Atlantis-Software/salesDocument/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Atlantis-Software%2FsalesDocument/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279085462,"owners_count":26100017,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-15T02:00:07.814Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-05T05:09:19.187Z","updated_at":"2025-10-15T14:31:52.549Z","avatar_url":"https://github.com/Atlantis-Software.png","language":"JavaScript","readme":"# salesDocument\n\nSalesDocument is a class that provide functions to create a sale document with a model using pdfmake and somes datas.\n\nWhen the sale document is created, anyone can modify the model to modify the look and feel of the document without modifying any code line.\n\nYou modify the model and use SalesDocument to regenerate the sale document with the new properties.\n\nYou can put in the sale document all the poperties which are located in the datas witout modifying code line.\n\nYou can let your customers modify the model or generate their own models of their documents.\n\nSalesDocument permit you to generate all the documents you have in head. For example you can generate follow up letters, order, order's picking, delivery, invoice, etc.\n\n## Installation\nJust do an npm install in your project folder :\n\n```\nnpm install salesDocument\n```\n\n## Run example\nYou need to install pdfmake in the project :\n```\nnpm install pdfmake\n```\nAfter that you need to go in example folders and use `node` commands :\n\n```\nnode basics.js\n```\n\nThat will create a pdf in pdfs folders. You can change model and data in corresponding files\n\n## Usage\nSalesDocument is a instantiable object.\n\nThe object take the pdfmake model and put the data into that.\n\nFor use SalesDocument we need to require or import the class :\n```javascript\nvar salesDocument = require('salesDocument');\n//or\nimport salesDocument from 'salesDocument'\n```\n\nNext we need to create the object :\n```javascript\nvar myObject = new salesDocument(model, data)\n```\n\nTo remove header in the first page , we can use removeHeaderFirstPage function :\n```javascript\nmyObject.removeHeaderFirstPage();\n```\n\nWe can change model or data after initialisation with setters :\n```javascript\nmyObject.setModel(model);\nmyObject.setData(data);\n```\n\nThe main function of class is `createPDFMakeDD`, that put data into model and create a pdfmake dd, then we can use pdfmake to create a pdf\nCall the first time with the first document with its data\nModify all document ( header and footer ) with the data\nPagination by document\n```javascript\nmyObject.createPDFMakeDD( function(dd) {\n  // some code\n});\n```\n\nAdd new document folowing the pdf\nFrom the second document we use this function\nThe data to modify in the new document is passed to it as a parameter\n```javascript\nmyObject.addDocument(data, function(dd) {\n  // some code\n});\n```\n## Create the model\nThe model is a document definition of pdfmake so we can use any features available in pdfmake.\n\nTo create a model with dynamic data we just need to use a tag with data we want to be modify. Per default the tag is sDoc\n\nTo display a image use tag sDocImage : it must be a buffer , only jpeg and png can be used.\n\n\nExample :\n```javascript\nvar dd = {\n  content: [\n    {\n      text: '\u003csDoc\u003edocument.date\u003c/sDoc\u003e'\n    },\n    {\n      image: '\u003csDocImage\u003eimage_buffer\u003c/sDocImage\u003e',\n      width: 510,\n      height: 100\n    }\n  ],\n  header: [\n    {\n      style: 'tableMargin10',\n      color: '#444',\n      table: {\n        widths: ['*', 100, 250],\n        body: [\n          [\n            {// ligne du haut\n              colSpan: 3,\n              text: '',\n              fillColor: \"#2e99cd\",\n              border: [false, false, false, false],\n              margin: [8, 0, 8, 0]\n            },\n            '',\n            ''\n          ]\n        ]\n      }\n    },\n    {\n      style: 'tableMargin10',\n      color: '#444',\n      table: {\n        widths: ['*', 1, 65],\n        body: [\n          [\n            [\n              'or a nested table',\n\t\t\t\t\t\t\t{\n                table: {\n                  body: [\n                    [ {text: '\u003csDoc\u003eclient.phone\u003c/sDoc\u003e'},  {text:'\u003csDoc\u003eclient.phone\u003c/sDoc\u003e'},  {text:'\u003ccurrentPage/\u003e'}],\n                    ['1pagecount', {text: 'pageeee count \u003cpageCount/\u003e'}, '3'],\n                    ['1', '2', '3']\n                  ]\n                },\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n            {\n              border: [false, false, false, false],\n              text: ''\n            },\n            { // titre du pdf\n              border: [false, false, false, false],\n              fillColor: \"#2e99cd\",\n              text: '\u003csDoc\u003edocument.date\u003c/sDoc\u003e' + \" \u003ccurrentPage/\u003e\" + ' / ' + \"\u003cpageCount/\u003e\",\n              color: '\u003csDoc\u003erose\u003c/sDoc\u003e',\n              margin: [5, 3, 0, 3],\n              fontSize: 12,\n              bold: true\n            }\n          ]\n        ]\n      }\n    }\n  ],\n  footer: {\n    text: '\u003csDoc\u003efooter\u003c/sDoc\u003e' + \" \u003ccurrentPage/\u003e\" + ' / ' + \"\u003cpageCount/\u003e\",\n    alignment: 'right',\n    margin: [10, 0, 12, 0]\n  }\n}\n\n```\nIn the header or the footer we can use the tag `\u003ccurrentPage/\u003e` to display current page and the tag  `\u003cpageCount/\u003e` to display the total number of pages.\n\nIn your model you can create a loop (`for`) in your table. For that you just need to add `forOrder` attribute.\n\nSalesDocument will loop all times is needed to fullfill the table with the datas. For every one line of datas, you determine the type of line model you want to be used by filling the \"type\" propertie in the data line and SalesDocument will used the correct linem model using the \"forOrder\" propertie which is in the model\n\nThat attribute is an array of string with in order the different type of line, like `orderline`, `commentline` ... It's important respecting order of type of line when you code the model.\n\nWARNING : we can't use type line `lot` , it's a reserved type\n\nSalesDocument need to know where it must search the datas for the table which must be fill up. To perform this, you need to fill the dataname propertie in the model. In the example below, the dataname is \"OrderLines\". You can name it with what you want. But the name must be the same in the model and in the datas.\n\nThe first description line of a table is the columns headers rows\n\nExample :\n```javascript\ntable : {\n  width : ...,\n  headerRows: 1,\n  forOrder: ['orderline', 'commentline', 'other'],\n  body : [\n    // The first line is the header\n    // headerRows define how many line we skip before model of line\n    [\n      {\n        //headerRow\n\t...\n      }\n    ],\n    //order line\n    [...],\n    //comment line\n    [...],\n    //other line\n    [...]\n  ]\n}\n```\n\nIf we want a column to take all rows we just need to put in line `rowSpan: x`, x is the number of model line and header line.\n\nIt will take automatically all the line.\n\nFor a component line , we must define a level. For each level with have a arrow in the first line.\n\nExample :\n```javascript\ntable: {\n  widths: ['*', 45, 15, 50, 50],\n  headerRows: 1, // the first x lines are headers ( in our case 1 header line)\n  keepWithHeaderRows: 1, //To replace the table headers on the following pages\n  dontBreakRows: true, // So that a line is not cut between 2 pages\n  forOrder: [\"orderline\", \"array\", \"component\", \"commentline\"],\n  dataname: \"OrderLines\",\n  body: [\n    [\n      // Header row\n      {text: 'DESIGNATION', alignment: 'left',\tstyle: 'smallbold', border: [true, true, true, true]},\n      {text: 'QTE A PREP', alignment: 'right',\tstyle: 'smallbold', border: [true, true, true, true]},\n      {text: 'U', alignment: 'center',\tstyle: 'smallbold', border: [true, true, true, true]},\n      {text: 'EMPLAC.', alignment: 'right',\tstyle: 'smallbold', border: [true, true, true, true]},\n      {text: 'RESTE', alignment: 'right',\tstyle: 'smallbold', border: [true, true, true, true]},\n    ],\n    [\n      //orderline\n      {\n        table: {\n          widths: ['*', 'auto'],\n          body: [\n            [\n              {text: '\u003csDoc\u003eligne.code\u003c/sDoc\u003e', alignment: 'left',\tstyle: 'StyleLigne', border: [false, false, false, false]},\n              {text: 'Ref Frs : \u003csDoc\u003eligne.code\u003c/sDoc\u003e', alignment: 'right',\tstyle: 'StyleLigne', border: [false, false, false, false]},\n            ],\n            [\n              {colSpan: 2, text: '\u003csDoc\u003eligne.designation\u003c/sDoc\u003e', alignment: 'left',\tstyle: 'StyleLigne', border: [false, false, false, false]},\n            ],\n            [\n              {colSpan: 2, text: 'Stock : \u003csDoc\u003eligne.unity\u003c/sDoc\u003e', alignment: 'left',\tstyle: 'StyleLigne', border: [false, false, false, false]},\n            ],\n          ]\n        }\n\n      },\n      {\tstyle: 'StyleLigne', text:'\u003csDoc\u003eligne.publicPrice\u003c/sDoc\u003e', alignment: 'right'},\n      {\tstyle: 'StyleLigne', text:'\u003csDoc\u003eligne.unity\u003c/sDoc\u003e'},\n      {\tstyle: 'StyleLigne', text:'\u003csDoc\u003eligne.netUnitPrice\u003c/sDoc\u003e'},\n      {\tstyle: 'StyleLigne', text:'\u003csDoc\u003eligne.totalExclTaxes\u003c/sDoc\u003e'},\n    ],\n    [\n     // array line\n     {\n        colSpan: 5,\n        table: {\n          widths: [150, 165, 35, 20, 35,35],\n          body: [\n            [\n              {text: '\u003csDoc\u003eline_array.code\u003c/sDoc\u003e'},\n              {text: '\u003csDoc\u003eline_array.designation\u003c/sDoc\u003e'},\n              {text: '\u003csDoc\u003eline_array.quantity\u003c/sDoc\u003e',alignment: 'right'},\n              {\tstyle: 'StyleLigne', text:'\u003csDoc\u003eligne.unity\u003c/sDoc\u003e'},\n\n              {text: '\u003csDoc\u003eline_array.T\u003c/sDoc\u003e'},\n              {text: '\u003csDoc\u003eline_array.totalExclTaxes\u003c/sDoc\u003e', alignment: 'right'}\n\n            ]\n          ]\n        },\n        layout: 'noBorders'\n      },\n      ''\n    ],\n    [\n      // component line\n      {\n        table: {\n          widths: [10, '*', 'auto'],\n          body: [\n            [\n              {text: '-\u003e', alignment: 'left',\tstyle: 'StyleLigne', border: [false, false, false, false]},\n              {text: '\u003csDoc\u003eligne.code\u003c/sDoc\u003e', alignment: 'left',\tstyle: 'StyleLigne', border: [false, false, false, false]},\n              {text: 'Ref Frs : \u003csDoc\u003eligne.code\u003c/sDoc\u003e', alignment: 'right',\tstyle: 'StyleLigne', border: [false, false, false, false]},\n            ],\n            [\n              {colSpan: 3, text: '\u003csDoc\u003eligne.designation\u003c/sDoc\u003e', alignment: 'left',\tstyle: 'StyleLigne', border: [false, false, false, false]},\n            ],\n            [\n              {colSpan: 3, text: 'Stock : \u003csDoc\u003eligne.unity\u003c/sDoc\u003e', alignment: 'left',\tstyle: 'StyleLigne', border: [false, false, false, false]},\n            ],\n          ]\n        }\n\n      },\n      {\tstyle: 'StyleLigne', text:'\u003csDoc\u003eligne.publicPrice\u003c/sDoc\u003e', alignment: 'right'},\n      {\tstyle: 'StyleLigne', text:'\u003csDoc\u003eligne.unity\u003c/sDoc\u003e'},\n      {\tstyle: 'StyleLigne', text:'\u003csDoc\u003eligne.netUnitPrice\u003c/sDoc\u003e'},\n      {\tstyle: 'StyleLigne', text:'\u003csDoc\u003eligne.totalExclTaxes\u003c/sDoc\u003e'},\n    ],\n    // commentline\n    [{colSpan: 5, border: [true, false, true, false], text: '\u003csDoc\u003eligne.comment\u003c/sDoc\u003e\\n'}, '']\n  ]\n}\n```\n\n## Example of data\n\n```javascript\nvar data = {\n  document : {\n    date: \"01/01/2018\",\n    ref : \"12345678\"\n  },\n  OrderLines : [\n    {\n      line_array: [\n        {\n          code:'1206008034',\n          designation:'LASER PRINTER (REF)',\n          quantity:'1.000',\n          unity:'U',\n          publicPrice:'',\n          R:'',\n          RC:'',\n          netUnitPrice:'353.31',\n          totalExclTaxes:'353.31',\n          T:'1'\n        }, {\n          designation:'- Ecotax',\n          totalExclTaxes:'2.50',\n        }\n      ],\n      type: \"array\"\n    },\n    {\n      code:'1206008034',\n      designation:'WOODEN DESK ',\n      quantity:'1.000',\n      unity:'U',\n      publicPrice:'20',\n      R:'',\n      RC:'',\n      netUnitPrice:'256.99',\n      totalExclTaxes:'256.99',\n      T:'1',\n      type: \"orderline\"\n    },\n    {\n      code:'1234',\n      designation:'COMPUTER',\n      quantity:'1.000',\n      unity:'U',\n      publicPrice:'',\n      R:'',\n      RC:'',\n      netUnitPrice:'1000.00',\n      totalExclTaxes:'1000.00',\n      T:'1',\n      type: \"orderline\"\n    },\n    {\n      code:'12341',\n      designation:'COMPUTER TOWER',\n      quantity:'1.000',\n      unity:'U',\n      T:'1',\n      level: 1,\n      type: \"component\"\n    },\n    {\n      code:'12342',\n      designation:'SCREEN',\n      quantity:'1.000',\n      unity:'U',\n      T:'1',\n      type: \"component\",\n      level: 3\n    },\n    {\n      comment: 'Deferred delivery for the rest of the invoice',\n      type: \"commentline\"\n    },\n    {\n      code:'1206008034',\n      designation:'OFFICE CHAIRS',\n      quantity:'2.000',\n      unity:'U',\n      publicPrice:'',\n      R:'',\n      RC:'',\n      netUnitPrice:'160.99',\n      totalExclTaxes:'160.99',\n      T:'1',\n      type: \"component\",\n      level: 2\n    }\n  ],\n  info : {\n    weight: \"5kg\",\n    week : \"10\"\n  }\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatlantis-software%2Fsalesdocument","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatlantis-software%2Fsalesdocument","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatlantis-software%2Fsalesdocument/lists"}