Skip to content
This repository was archived by the owner on Feb 10, 2025. It is now read-only.

Commit 9d125a1

Browse files
committed
add pb import
1 parent 3a486ed commit 9d125a1

File tree

3 files changed

+227
-2
lines changed

3 files changed

+227
-2
lines changed

package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
"health-check": "node src/scripts/health-check.js"
1616
},
1717
"dependencies": {
18-
"@actual-app/crdt": "2.1.0",
19-
"@actual-app/web": "24.5.0",
18+
"@actual-app/api": "file:../actual3/packages/api",
19+
"@actual-app/crdt": "file:../actual3/packages/crdt",
20+
"@actual-app/web": "file:../actual3/packages/desktop-client",
2021
"bcrypt": "^5.1.0",
2122
"better-sqlite3": "^9.1.1",
2223
"body-parser": "^1.20.1",
2324
"cors": "^2.8.5",
25+
"dayjs": "^1.11.8",
2426
"date-fns": "^2.30.0",
2527
"debug": "^4.3.4",
2628
"express": "4.19.2",

src/app.js

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as syncApp from './app-sync.js';
1111
import * as goCardlessApp from './app-gocardless/app-gocardless.js';
1212
import * as simpleFinApp from './app-simplefin/app-simplefin.js';
1313
import * as secretApp from './app-secrets.js';
14+
import * as pbSync from './pb_transactions.js';
1415

1516
const app = express();
1617

src/pb_transactions.js

+222
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
debugger;
2+
import express from 'express';
3+
import errorMiddleware from './util/error-middleware.js';
4+
5+
import axios from 'axios';
6+
import dayjs from 'dayjs';
7+
import customParseFormat from 'dayjs/plugin/customParseFormat.js';
8+
dayjs.extend(customParseFormat);
9+
10+
let app = express();
11+
app.use(errorMiddleware);
12+
13+
const pb_api = axios.create({
14+
baseURL: 'https://next.privat24.ua/api/p24/',
15+
headers: { 'content-type': 'application/json' },
16+
});
17+
18+
const config = {
19+
headers: { 'Content-Type': 'text/xml' },
20+
};
21+
22+
const id = '210601';
23+
const passwd = '9frS30798l5L2d610R3A2VBeV4c5nDB4';
24+
const card = '5363542320592448';
25+
26+
/**
27+
3c1699a5-522a-435e-86dc-93d900a14f0e Income 1 2E1F5BDB-209B-43F9-AF2C-3CE28E380C00 49152.0 0
28+
6bbd8472-25d4-4cee-8a11-5bd9f7e83d61 Savings 0 a137772f-cf2f-4089-9432-822d2ddc1466 32768.0 0
29+
7ce5f256-661e-4836-be39-2d4cbb6d4ad2 Кафешки 0 fc3825fd-b982-4b72-b768-5b30844cf832 192.0 0
30+
712d8a09-c25b-4f6d-87ab-264866e1e466 Продукти 0 fc3825fd-b982-4b72-b768-5b30844cf832 160.0 0
31+
02500283-623b-4fb2-a811-f3ece649e193 Послуги 0 fc3825fd-b982-4b72-b768-5b30844cf832 2048.0 0
32+
3455410d-fa56-4688-b9b3-8062aea1f423 Дитина 0 fc3825fd-b982-4b72-b768-5b30844cf832 1024.0 0
33+
4cd6e6a5-ef12-401a-96bd-06a4b3cd66b5 Комуналка 0 fc3825fd-b982-4b72-b768-5b30844cf832 5888.0 0
34+
0b367cbf-98dd-43fd-9b2f-615d28b1b5b7 Їжа 0 fc3825fd-b982-4b72-b768-5b30844cf832 176.0 0
35+
12006b23-1eda-4329-804b-df5128bd5e88 Одяг 0 fc3825fd-b982-4b72-b768-5b30844cf832 22528.0 0
36+
32f85af2-a5b4-43a9-a799-175e7868d2c7 Медецина 0 fc3825fd-b982-4b72-b768-5b30844cf832 3072.0 0
37+
783ae42d-2b13-4157-8a2a-5979cec744d7 Кішка 0 fc3825fd-b982-4b72-b768-5b30844cf832 4096.0 0
38+
2d1808fb-a5c5-400c-a402-151b1c1e78c9 техніка 0 fc3825fd-b982-4b72-b768-5b30844cf832 5632.0 0
39+
4945e7c6-2458-42ea-944c-58163d887efe Інше 0 fc3825fd-b982-4b72-b768-5b30844cf832 5120.0 0
40+
2c96e78a-5750-43e1-a7b8-52f549fa4367 Пальне 0 fc3825fd-b982-4b72-b768-5b30844cf832 38912.0 0
41+
*/
42+
const mapCategories = {
43+
ОККО: '2c96e78a-5750-43e1-a7b8-52f549fa4367',
44+
SOLIDOL: '02500283-623b-4fb2-a811-f3ece649e193',
45+
КАФЕРИНОК: '712d8a09-c25b-4f6d-87ab-264866e1e466',
46+
'CAFE RYNOK': '712d8a09-c25b-4f6d-87ab-264866e1e466',
47+
SPAR: '712d8a09-c25b-4f6d-87ab-264866e1e466',
48+
'ГудФуд Вдома': '0b367cbf-98dd-43fd-9b2f-615d28b1b5b7',
49+
'Bolt Food': '0b367cbf-98dd-43fd-9b2f-615d28b1b5b7',
50+
'McDonald’s': '0b367cbf-98dd-43fd-9b2f-615d28b1b5b7',
51+
avocado: '0b367cbf-98dd-43fd-9b2f-615d28b1b5b7',
52+
ZOOРОДИНА: '783ae42d-2b13-4157-8a2a-5979cec744d7',
53+
Аптека: '32f85af2-a5b4-43a9-a799-175e7868d2c7',
54+
Aптека: '32f85af2-a5b4-43a9-a799-175e7868d2c7',
55+
LIUKSOPTYKA: '32f85af2-a5b4-43a9-a799-175e7868d2c7',
56+
NOA: '0b367cbf-98dd-43fd-9b2f-615d28b1b5b7',
57+
АТБ: '712d8a09-c25b-4f6d-87ab-264866e1e466',
58+
'РОДИННА КОВБАСКА': '712d8a09-c25b-4f6d-87ab-264866e1e466',
59+
REMIX: '12006b23-1eda-4329-804b-df5128bd5e88',
60+
Сільпо: '712d8a09-c25b-4f6d-87ab-264866e1e466',
61+
WINETIME: '712d8a09-c25b-4f6d-87ab-264866e1e466',
62+
'MAGAZYN KOMORA, LVIV': '712d8a09-c25b-4f6d-87ab-264866e1e466',
63+
PARASKEVA: '32f85af2-a5b4-43a9-a799-175e7868d2c7',
64+
MONAKO: '3455410d-fa56-4688-b9b3-8062aea1f423',
65+
іграшок: '3455410d-fa56-4688-b9b3-8062aea1f423',
66+
CHICCO: '3455410d-fa56-4688-b9b3-8062aea1f42',
67+
Антошка: '3455410d-fa56-4688-b9b3-8062aea1f423',
68+
'ANTOSHKA ': '3455410d-fa56-4688-b9b3-8062aea1f423',
69+
'MY PLAY': '3455410d-fa56-4688-b9b3-8062aea1f423',
70+
Кафе: '7ce5f256-661e-4836-be39-2d4cbb6d4ad2',
71+
KYIVSTAR: '4cd6e6a5-ef12-401a-96bd-06a4b3cd66b5',
72+
"Oplata komunal'nykh posluh": '4cd6e6a5-ef12-401a-96bd-06a4b3cd66b5',
73+
'АТ Львівгаз': '4cd6e6a5-ef12-401a-96bd-06a4b3cd66b5',
74+
Львівтеплоенерго: '4cd6e6a5-ef12-401a-96bd-06a4b3cd66b5',
75+
'ГК Нафтогаз України, ТОВ': '4cd6e6a5-ef12-401a-96bd-06a4b3cd66b5',
76+
'Воля, ТОВ(Volia)': '4cd6e6a5-ef12-401a-96bd-06a4b3cd66b5',
77+
vodopostachannia: '4cd6e6a5-ef12-401a-96bd-06a4b3cd66b5',
78+
Львівенергозбут: '4cd6e6a5-ef12-401a-96bd-06a4b3cd66b5',
79+
MITTE: '7ce5f256-661e-4836-be39-2d4cbb6d4ad2',
80+
'МЯСНА ІМПЕРІЯ ДОБРА ОСЕЛЯ': '712d8a09-c25b-4f6d-87ab-264866e1e466',
81+
'LA П"ЄЦ': '0b367cbf-98dd-43fd-9b2f-615d28b1b5b7',
82+
"Вук Мар'яна Ярославівна": '712d8a09-c25b-4f6d-87ab-264866e1e466',
83+
MYPLAY: '3455410d-fa56-4688-b9b3-8062aea1f423',
84+
KEBAB: '0b367cbf-98dd-43fd-9b2f-615d28b1b5b7',
85+
'NOYIV KOVCHEH': '0b367cbf-98dd-43fd-9b2f-615d28b1b5b7',
86+
'Магазин Будинок Iграшок': '3455410d-fa56-4688-b9b3-8062aea1f423',
87+
'КОНДИТЕРСЬКА-ПЕКАРНЯ BISCOTTI': '7ce5f256-661e-4836-be39-2d4cbb6d4ad2',
88+
якVdoma: '712d8a09-c25b-4f6d-87ab-264866e1e466',
89+
REIMA: '3455410d-fa56-4688-b9b3-8062aea1f423',
90+
'MAGAZYN RODYNNA KOVBAS, m. Lviv': '712d8a09-c25b-4f6d-87ab-264866e1e466',
91+
'Rodynna kovbas': '712d8a09-c25b-4f6d-87ab-264866e1e466',
92+
'Калаталюк-Мельник Тетяна Іванівна': '712d8a09-c25b-4f6d-87ab-264866e1e466',
93+
'WINETIME, LVIV': '712d8a09-c25b-4f6d-87ab-264866e1e466',
94+
'Prytula Dental': '32f85af2-a5b4-43a9-a799-175e7868d2c7',
95+
MEDIKAVER: '32f85af2-a5b4-43a9-a799-175e7868d2c7',
96+
Лікарня: '32f85af2-a5b4-43a9-a799-175e7868d2c7',
97+
BraBraBra: '12006b23-1eda-4329-804b-df5128bd5e88',
98+
INTERTOP: '12006b23-1eda-4329-804b-df5128bd5e88',
99+
'PLANETA KINO': '7ce5f256-661e-4836-be39-2d4cbb6d4ad2',
100+
СпортМастер: '12006b23-1eda-4329-804b-df5128bd5e88',
101+
SKECHERS: '12006b23-1eda-4329-804b-df5128bd5e88',
102+
Креденс: '7ce5f256-661e-4836-be39-2d4cbb6d4ad2',
103+
'Магазин Білка': '7ce5f256-661e-4836-be39-2d4cbb6d4ad2',
104+
KRUASANY: '7ce5f256-661e-4836-be39-2d4cbb6d4ad2',
105+
ПАПАПА: '02500283-623b-4fb2-a811-f3ece649e193',
106+
Bolt: '02500283-623b-4fb2-a811-f3ece649e193',
107+
'ЕКО МОЛОКО': '712d8a09-c25b-4f6d-87ab-264866e1e466',
108+
'Нова Пошта': '02500283-623b-4fb2-a811-f3ece649e193',
109+
ЗООРодина: '783ae42d-2b13-4157-8a2a-5979cec744d7',
110+
Зоомагазин: '783ae42d-2b13-4157-8a2a-5979cec744d7',
111+
};
112+
113+
async function getTransactions({ dateFrom, dateTo, skey, xref }) {
114+
const transactions = [];
115+
116+
try {
117+
let finalPortion = false;
118+
let pageNumber = 1;
119+
120+
while (!finalPortion) {
121+
const result = await pb_api.post(
122+
'activity/get',
123+
{
124+
xref,
125+
action: 'get',
126+
scheme: '1',
127+
pointType: 'statements',
128+
portionNumber: pageNumber,
129+
lang: 'ua',
130+
cardIds: ['0QE7T1NGTR9EVLOG4Z3'],
131+
dateFrom,
132+
dateTo,
133+
_: 1685912881119,
134+
},
135+
{
136+
headers: {
137+
cookie: `skey=${skey};`,
138+
},
139+
withCredentials: true,
140+
},
141+
);
142+
143+
const { status, data } = result;
144+
145+
if (status === 200) {
146+
const { status, data: hints } = data;
147+
if (status === 'success') {
148+
const { activities, finalPortion: final } = hints;
149+
150+
for (const transaction of activities) {
151+
const { amount, date, details } = transaction;
152+
153+
const item = {
154+
amount: parseInt(amount * 100),
155+
date: dayjs(date, 'DD.MM.YYYY HH:mm:ss').format('YYYY-MM-DD'),
156+
notes: details,
157+
payee_name: undefined,
158+
};
159+
160+
for (const [name, category] of Object.entries(mapCategories)) {
161+
if (details.toLowerCase().indexOf(name.toLowerCase()) >= 0) {
162+
item.category = category;
163+
}
164+
}
165+
166+
transactions.push(item);
167+
}
168+
169+
finalPortion = final; // Update flag to check if we're done paging
170+
pageNumber++; // Move to next page if we're not finished yet
171+
} else {
172+
throw new Error('Wrong code');
173+
}
174+
} else {
175+
throw new Error('wrong response');
176+
}
177+
}
178+
} catch (e) {
179+
console.error(e);
180+
throw e;
181+
}
182+
183+
return transactions;
184+
}
185+
186+
app.get('/get-transactions', (req, res) => {
187+
getTransactions({
188+
dateFrom: req.query.dateFrom,
189+
dateTo: req.query.dateTo,
190+
xref: req.query.xref,
191+
skey: req.query.skey,
192+
})
193+
.then((trs) => {
194+
res.send({
195+
status: 'ok',
196+
data: trs,
197+
});
198+
})
199+
.catch((err) => {
200+
res.send({
201+
status: 'error',
202+
data: err,
203+
});
204+
});
205+
});
206+
207+
//module.exports = getTransactions;
208+
// getTransactions({
209+
// xref: '',
210+
// skey: '',
211+
// dateFrom: '',
212+
// dateTo: ''
213+
// });
214+
215+
export { app as handlers };
216+
217+
// getTransactions({
218+
// dateFrom: '01.05.2023',
219+
// dateTo: '31.05.2023',
220+
// xref: '',
221+
// skey: '',
222+
// });

0 commit comments

Comments
 (0)