parser-de-notas-de-corretagem 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -0
- package/notes-parser.d.ts +104 -0
- package/notes-parser.js +2 -0
- package/notes-parser.js.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Parse Brazilian brokerage notes PDFs (Inter and Clear holders available)
|
|
2
|
+
|
|
3
|
+
Easing the PITA of making IRRF
|
|
4
|
+
|
|
5
|
+
> Note: This is a JS/TS package. If you want the final-user solution, check the [Leitor de notas de corretagem](https://github.com/planetsLightningArrester/leitor-de-notas-de-corretagem)
|
|
6
|
+
|
|
7
|
+
## Example result
|
|
8
|
+
> The `price` and `average` fields already include the fees paid
|
|
9
|
+
```JSON
|
|
10
|
+
[
|
|
11
|
+
{
|
|
12
|
+
"number": "11111",
|
|
13
|
+
"buyTotal": "4054.58",
|
|
14
|
+
"sellTotal": "0.00",
|
|
15
|
+
"buyFees": "1.24",
|
|
16
|
+
"sellFees": "0.00",
|
|
17
|
+
"fees": "1.24",
|
|
18
|
+
"date": "02/02/2022",
|
|
19
|
+
"holder": "rico",
|
|
20
|
+
"deals": [
|
|
21
|
+
{
|
|
22
|
+
"type": "buy",
|
|
23
|
+
"code": "FLRY3",
|
|
24
|
+
"quantity": 62,
|
|
25
|
+
"average": "16.30",
|
|
26
|
+
"price": "1010.91",
|
|
27
|
+
"date": "02/02/2022",
|
|
28
|
+
"cnpj": "60.840.055/0001-31"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"type": "buy",
|
|
32
|
+
"code": "ALZR11",
|
|
33
|
+
"quantity": 5,
|
|
34
|
+
"average": "112.80",
|
|
35
|
+
"price": "564.02",
|
|
36
|
+
"date": "02/02/2022",
|
|
37
|
+
"cnpj": "00.000.000/0000-00"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"type": "buy",
|
|
41
|
+
"code": "HGRU11",
|
|
42
|
+
"quantity": 5,
|
|
43
|
+
"average": "112.03",
|
|
44
|
+
"price": "560.17",
|
|
45
|
+
"date": "02/02/2022",
|
|
46
|
+
"cnpj": "00.000.000/0000-00"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"type": "buy",
|
|
50
|
+
"code": "VISC11",
|
|
51
|
+
"quantity": 15,
|
|
52
|
+
"average": "97.38",
|
|
53
|
+
"price": "1460.69",
|
|
54
|
+
"date": "02/02/2022",
|
|
55
|
+
"cnpj": "00.000.000/0000-00"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"type": "buy",
|
|
59
|
+
"code": "XPML11",
|
|
60
|
+
"quantity": 5,
|
|
61
|
+
"average": "91.76",
|
|
62
|
+
"price": "458.79",
|
|
63
|
+
"date": "02/02/2022",
|
|
64
|
+
"cnpj": "00.000.000/0000-00"
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Install
|
|
72
|
+
> npm i parser-de-notas-de-corretagem
|
|
73
|
+
|
|
74
|
+
## Usage
|
|
75
|
+
|
|
76
|
+
### Full example
|
|
77
|
+
```Typescript
|
|
78
|
+
import fs from 'fs';
|
|
79
|
+
import path from 'path';
|
|
80
|
+
import { Deal, NoteParser } from 'parser-de-notas-de-corretagem';
|
|
81
|
+
|
|
82
|
+
async function main() {
|
|
83
|
+
|
|
84
|
+
console.log(`Leitor de Notas de Negociação - GNU GPLv3`);
|
|
85
|
+
|
|
86
|
+
const assets = new NoteParser();
|
|
87
|
+
try {
|
|
88
|
+
|
|
89
|
+
// Get all negotiation notes inside a PDF, even with password
|
|
90
|
+
const possiblePDFpasswords: string[] = ['123', '456'];
|
|
91
|
+
let pdfPassword = path.join(__dirname, 'note.pdf');
|
|
92
|
+
let parseResult = await assets.parseNote(pdfPassword, possiblePDFpasswords);
|
|
93
|
+
|
|
94
|
+
// Merge all negotiation notes
|
|
95
|
+
let allDeals: Deal[][] = [];
|
|
96
|
+
parseResult.forEach(note => {
|
|
97
|
+
note.deals.forEach(deal => {
|
|
98
|
+
let index = allDeals.findIndex(el => el.some(subEl => subEl.code === deal.code));
|
|
99
|
+
if (index === -1) {
|
|
100
|
+
allDeals.push([deal]);
|
|
101
|
+
} else {
|
|
102
|
+
allDeals[index].push(deal);
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
// Generate a .csv result
|
|
108
|
+
let result: string = `Código\tCNPJ\tData\tC/V\tQuantidade\tPreço+custos\n`;
|
|
109
|
+
allDeals.forEach(asset => {
|
|
110
|
+
asset.forEach(deal => {
|
|
111
|
+
result += `${deal.code}\t${deal.cnpj}\t${deal.date}\t${deal.type=='buy'?'C':'V'}\t${deal.quantity}\t${deal.price.replace(/\./g, ',')}\n`;
|
|
112
|
+
})
|
|
113
|
+
result += `\n`;
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
fs.writeFileSync(path.join(__dirname, '..', '..', 'Resultado.csv'), result);
|
|
117
|
+
|
|
118
|
+
console.log(`Todas as ${parseResult.length} notas foram processadas`);
|
|
119
|
+
console.log(`O arquivo "Resultado.csv" foi gerado no diretório atual.`);
|
|
120
|
+
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.log(error);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
main();
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Add a custom stock
|
|
130
|
+
```Typescript
|
|
131
|
+
const assets = new NoteParser();
|
|
132
|
+
// Old stocks aren't available by default, but you can add them
|
|
133
|
+
assets.defineStock('BIDI3', 'BANCO INTER ON');
|
|
134
|
+
assets.defineStock('BIDI11', 'BANCO INTER UNT');
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## P.S.
|
|
138
|
+
* Total values include fees
|
|
139
|
+
* The values can deviate from cents. It's always a good call to double-check if the result is as expected. Check the [License](#license)
|
|
140
|
+
* FIIs and custom stocks doesn't provide a valid CNPJ field
|
|
141
|
+
|
|
142
|
+
## Contributors
|
|
143
|
+
Thanks to whom sent me notes for the tests ❤️. Personal data is not stored neither used on tests, only the notes content.
|
|
144
|
+
|
|
145
|
+
## Thanks? U welcome
|
|
146
|
+
Consider thanking me: send a "Thanks!" 👋 by [PIX](https://www.bcb.gov.br/en/financialstability/pix_en) 😊
|
|
147
|
+
> a09e5878-2355-45f7-9f36-6df4ccf383cf
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
As license, this software is provided as is, free of charge, without any warranty whatsoever. Its author is not responsible for its usage. Use it by your own risk.
|
|
151
|
+
|
|
152
|
+
[GNU GPLv3](https://choosealicense.com/licenses/gpl-3.0/)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deal made in a `NegotiationNote` type
|
|
3
|
+
*/
|
|
4
|
+
export interface Deal {
|
|
5
|
+
/**
|
|
6
|
+
* Deal type
|
|
7
|
+
*/
|
|
8
|
+
type: 'buy' | 'sell';
|
|
9
|
+
/**
|
|
10
|
+
* Stock/FII code
|
|
11
|
+
*/
|
|
12
|
+
code: string;
|
|
13
|
+
/**
|
|
14
|
+
* Amount bought/sold
|
|
15
|
+
*/
|
|
16
|
+
quantity: number;
|
|
17
|
+
/**
|
|
18
|
+
* Average value bought/sold with fees applied
|
|
19
|
+
*/
|
|
20
|
+
average: string;
|
|
21
|
+
/**
|
|
22
|
+
* Total amount bought/sold with fees applied
|
|
23
|
+
*/
|
|
24
|
+
price: string;
|
|
25
|
+
/**
|
|
26
|
+
* Deal date in format yyyy-MM-dd
|
|
27
|
+
*/
|
|
28
|
+
date: string;
|
|
29
|
+
/**
|
|
30
|
+
* Asset's CNPJ
|
|
31
|
+
*/
|
|
32
|
+
cnpj: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A parsed Negotiation Note type
|
|
36
|
+
*/
|
|
37
|
+
export declare class NegotiationNote {
|
|
38
|
+
/**
|
|
39
|
+
* Negotiation note number
|
|
40
|
+
*/
|
|
41
|
+
number: string;
|
|
42
|
+
/**
|
|
43
|
+
* The total amount bought with fees applied
|
|
44
|
+
*/
|
|
45
|
+
buyTotal: string;
|
|
46
|
+
/**
|
|
47
|
+
* The total amount sold with fees applied
|
|
48
|
+
*/
|
|
49
|
+
sellTotal: string;
|
|
50
|
+
/**
|
|
51
|
+
* The total amount of buy fees
|
|
52
|
+
*/
|
|
53
|
+
buyFees: string;
|
|
54
|
+
/**
|
|
55
|
+
* The total amount of sell fees
|
|
56
|
+
*/
|
|
57
|
+
sellFees: string;
|
|
58
|
+
/**
|
|
59
|
+
* The total amount of fees
|
|
60
|
+
*/
|
|
61
|
+
fees: string;
|
|
62
|
+
/**
|
|
63
|
+
* Negotiation note date in format yyyy-MM-dd
|
|
64
|
+
*/
|
|
65
|
+
date: string;
|
|
66
|
+
/**
|
|
67
|
+
* Negotiation note holder
|
|
68
|
+
*/
|
|
69
|
+
holder: string;
|
|
70
|
+
/**
|
|
71
|
+
* Array of deals with buys and sells
|
|
72
|
+
*/
|
|
73
|
+
deals: Deal[];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Brokerage notes parser
|
|
77
|
+
*/
|
|
78
|
+
export declare class NoteParser {
|
|
79
|
+
/**
|
|
80
|
+
* Path to the JSON data file
|
|
81
|
+
*/
|
|
82
|
+
private stockParser;
|
|
83
|
+
/**
|
|
84
|
+
* Instantiate a new `NoteParser`
|
|
85
|
+
* @param autoUpdateLookUpList whether the application should auto-update
|
|
86
|
+
* the list of assets for new changes every week. Default is `false`. Require internet connection.
|
|
87
|
+
* Updating this package to the latest version also gets the latest infos
|
|
88
|
+
*/
|
|
89
|
+
constructor(autoUpdateLookUpList?: boolean);
|
|
90
|
+
/**
|
|
91
|
+
* Read and parse a given PDF negotiation note by its full path
|
|
92
|
+
* @param noteFullPath the full path to the PDF note to be parsed
|
|
93
|
+
* @returns an `Array` of `NegotiationNote`
|
|
94
|
+
*/
|
|
95
|
+
parseNote(noteFullPath: string, possiblePasswords?: string[]): Promise<NegotiationNote[]>;
|
|
96
|
+
/**
|
|
97
|
+
* Add stock definition
|
|
98
|
+
* @param code stock code
|
|
99
|
+
* @param name stock name
|
|
100
|
+
* @param cnpj stock CNPJ
|
|
101
|
+
*/
|
|
102
|
+
defineStock(code: string, name: string, cnpj?: string): void;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=notes-parser.d.ts.map
|