js-klikvet-logic-worker 2.3.19 → 2.3.21
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/delete.mjs +33 -0
- package/dist/worker.d.mts +511 -0
- package/dist/worker.d.mts.map +1 -0
- package/dist/worker.mjs +1338 -0
- package/dist/worker.mjs.map +1 -0
- package/package.json +11 -8
- package/{worker.mjs → pre_ts_worker.mjs} +39 -16
- package/reload.mjs +33 -0
- package/restart.mjs +33 -0
- package/src/worker.mts +1534 -0
- package/start.mjs +83 -0
- package/startOne.mjs +12 -0
- package/tsconfig.json +74 -0
- package/.vscode/launch.json +0 -17
- package/index.mjs +0 -20
package/src/worker.mts
ADDED
|
@@ -0,0 +1,1534 @@
|
|
|
1
|
+
|
|
2
|
+
import assert from 'assert'
|
|
3
|
+
import clonedeep from 'lodash.clonedeep'
|
|
4
|
+
import makeDir from 'make-dir'
|
|
5
|
+
import fs from 'fs'
|
|
6
|
+
import path from 'path'
|
|
7
|
+
import { Worker, Client } from 'cry-ebus2'
|
|
8
|
+
import { Mongo } from 'cry-db'
|
|
9
|
+
import { arrayToObject, dedup, Log, serialize, sleep } from 'cry-helpers'
|
|
10
|
+
import { ArtikelOsnova, Blagajna, Blagovnica, Cepljenje, Lokacija, Narocen, Nastavitve, Poslovalnica, PostavkaRacuna, Racun, Skladisce, VrstaPoslovnegaDogodka, VrstaRazknjizbeZdravila, VsotaDobavZaObdobje, anonimizirajPodatke, certs, createMongoForAnonimizacija, dobavaZdravil, ensureIndexes, karticaArtikla, koledarVeterinarja, mojPromet, pobrisiNeuporabljeno, podatkiRejca, poisciBlagovnice, poisciNeuporabljeno, porabaInProdajaZdravil, porabaZaDobavnico, prodajaZdravil, prodano, prodanoInPorabljeno, promet, racuni, racunovodji, razknjiziBlagovnico, razknjiziDobavnico, smsCepljen, smsCepljenjaNaDan, smsNarocen, smsNaroceniNaDan, spremembaZalogeZaObdobje, spremeniZalogoNaPodlagiRacuna, stranke, updateOpombeRejca, updatePotrditevBrejosti, updatePresusitve, updateStatusOsemenitve, vrniPopravekDobavniceCeNiZaPorabo, zakljucekBlagajne, zakljucekPolneInventureSestaviInZapisi, zalogaNaDan, zalogaPoDnevih, zaracunajDobavnice, zdruziStranke } from 'cry-klikvet-logic'
|
|
11
|
+
import { OsemenitevGoveda, StatusOsemenitve } from 'cry-klikvet-logic/dist/types/teren.mjs'
|
|
12
|
+
import { RacunZaKnjizbo } from 'cry-klikvet-logic/dist/spremeniZalogo.mjs'
|
|
13
|
+
import { Dobavnica } from 'cry-klikvet-logic/dist/types/Dobavnica.mjs'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
const DEFAULT_SERVICE_NAME = 'klikvet'
|
|
17
|
+
let log = new Log(['KLIKVET'])
|
|
18
|
+
|
|
19
|
+
type Obj = Record<string,any>
|
|
20
|
+
|
|
21
|
+
export type KlikvetClientRequest = "ping"
|
|
22
|
+
| { operation: "ping" }
|
|
23
|
+
| { operation: "promet-get-config" }
|
|
24
|
+
| { operation: "promet-create-pipeline", spec: Obj }
|
|
25
|
+
| { operation: "racuni-isci-create-pipeline", spec: Obj }
|
|
26
|
+
| { operation: "promet-exec-pipeline", tenant: string, pipeline?: Obj, spec?: Obj }
|
|
27
|
+
| { operation: "racuni-isci-exec-pipeline", tenant: string, pipeline: Obj, spec?: Obj }
|
|
28
|
+
| { operation: "porocilo-racunovodji", tenant: string, odDne: Date, doDne: Date, racuniPravnim?: boolean, racuniOdlozeno?: boolean }
|
|
29
|
+
| { operation: "zakljucek-blagajne", tenant: string, odDne: Date; doDne: Date; rounding: number; stevilka?: string; }
|
|
30
|
+
| { operation: "moj-promet", tenant: string, username: string, odDne: Date, doDne: Date }
|
|
31
|
+
| { operation: "prodano", tenant: string, username: string, odDne: Date, doDne: Date }
|
|
32
|
+
| { operation: "prodano-porabljeno", tenant: string; poArtiklih: boolean; poSkladiscih: boolean; poVrstah: boolean; poDst: boolean; timeQuery?: string; skladisca?: string[]; vrste?: VrstaPoslovnegaDogodka[]; }
|
|
33
|
+
| { operation: "skupine-izdelkov", tenant: string }
|
|
34
|
+
| { operation: "skupine-strank", tenant: string }
|
|
35
|
+
| { operation: "stranka-info", tenant: string, _id: string }
|
|
36
|
+
| { operation: "get-certs", tenant: string }
|
|
37
|
+
| { operation: "get-certs-valid", tenant: string, query?: Obj }
|
|
38
|
+
| { operation: "furs-register-cert", tenant: string, certBase64: string, certPass: string }
|
|
39
|
+
| { operation: "furs-remove-cert", certId: string, taxNo: string }
|
|
40
|
+
| { operation: "furs-register-premise", poslovniProstor: string, Premise: Obj, DursEnv: string, tenant: string, taxNo: string }
|
|
41
|
+
| { operation: "furs-register-invoice", tenant: string, env: string, _id: string }
|
|
42
|
+
| { operation: "furs-register-all-invoices", tenant: string, env: string }
|
|
43
|
+
| { operation: "racun-storno", tenant: string, id?: string, _id?: string }
|
|
44
|
+
| { operation: "razknjizi-racun", tenant: string, _id: string }
|
|
45
|
+
| { operation: "razknjizi-racune", tenant: string, }
|
|
46
|
+
| { operation: "razknjizi-blagovnice", tenant: string, }
|
|
47
|
+
| { operation: "razknjizi-blagovnico", tenant: string, _id: string }
|
|
48
|
+
| { operation: "porabe-za-dobavnice", tenant: string, username: string }
|
|
49
|
+
| { operation: "kartica", tenant: string, _id: string, razknjizba: VrstaRazknjizbeZdravila, skladisca_ids: string[] }
|
|
50
|
+
| { operation: "blagovnice", tenant: string, odDne: Date, doDne: Date }
|
|
51
|
+
| { operation: "dobava-zdravil", tenant: string, odDne: Date, doDne: Date }
|
|
52
|
+
| { operation: "poraba-prodaja-zdravil", tenant: string, odDne: Date, doDne: Date }
|
|
53
|
+
| { operation: "prodaja-zdravil", tenant: string, odDne: Date, doDne: Date }
|
|
54
|
+
| { operation: "ensure-indexes", tenant: string }
|
|
55
|
+
| { operation: "zaloga-na-dan", tenant: string, skladisca?: string[], samoKonsignacija?: boolean, datum: Date }
|
|
56
|
+
| { operation: "zaloga-po-dnevih", tenant: string, skladisca?: string[], samoKonsignacija?: boolean, datum: Date }
|
|
57
|
+
| { operation: "neuporabljeno-poisci", tenant: string, od: Date }
|
|
58
|
+
| { operation: "neuporabljeno-pobrisi", tenant: string, od: Date }
|
|
59
|
+
| { operation: "sprememba-zaloge-za-obdobje", tenant: string, odDne: Date, doDne: Date }
|
|
60
|
+
| { operation: "polna-inventura", tenant: string, od: Date, razknjizba: VrstaRazknjizbeZdravila, skladisce_id: string, izvedel: string, izlociTisteBrezZaloge: boolean, }
|
|
61
|
+
| { operation: "moj-koledar", tenant: string, id: string }
|
|
62
|
+
| { operation: "sms-narocen", tenant: string, id: string }
|
|
63
|
+
| { operation: "poslji-sms-narocenemu", tenant: string, id: string, narocen: Narocen, nacin: string }
|
|
64
|
+
| { operation: "poslji-smse-narocenim", tenant: string, id: string, dan: Date, nacin: string }
|
|
65
|
+
| { operation: "poslji-sms-cepljenja", tenant: string, cepljenje_id?: string, cepljenje?: Cepljenje, pacient_id: string, nacin: string }
|
|
66
|
+
| { operation: "poslji-smse-cepljenim", tenant: string, dan: Date, dniPrej?: number, nacin: string }
|
|
67
|
+
| { operation: "seznam-narocenih-za-sms", tenant: string, dan: Date, dniPrej?: number, nacin: string }
|
|
68
|
+
| { operation: "seznam-cepljenj-za-sms", tenant: string, dan: Date, dniPrej?: number }
|
|
69
|
+
| { operation: "potrditev-brejosti", tenant: string, _id: string, kdo: string, db?: string , breja: boolean}
|
|
70
|
+
| { operation: "v-presusitev", tenant: string, presusitev?: boolean, db?: string, _id:string, kdo: string}
|
|
71
|
+
| { operation: "status-osemenitve", tenant: string, db?: string, _id:string, kdo: string, status: StatusOsemenitve }
|
|
72
|
+
| { operation: "opomba-rejca-osemenitve", tenant: string, db?: string, _id: string, kdo: string, opomba: string }
|
|
73
|
+
| { operation: "podatki-rejca", tenant: string, rejciGeslo: string, rejciKoda: string }
|
|
74
|
+
| { operation: "zaracunaj-dobavnice", tenant: string, dobavnice_ids: string[], lokacija_id: string, naprava_id: string, izdal: string,}
|
|
75
|
+
| { operation: "anonimiziraj-podatke", tenant: string, letNazaj?: number }
|
|
76
|
+
| { operation: "razknjizi-dobavnico", tenant: string, _id: string }
|
|
77
|
+
| { operation: "zdruzi-stranke", tenant: string, v: string, iz: string[] }
|
|
78
|
+
;
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
function round(num: number, dec = 2)
|
|
83
|
+
{
|
|
84
|
+
return Number(num.toFixed(dec))
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
export class KlikvetLogicWorker extends Worker {
|
|
89
|
+
|
|
90
|
+
private client: Client | undefined = undefined
|
|
91
|
+
private gsm: string = ""
|
|
92
|
+
private mongo: Mongo | undefined
|
|
93
|
+
private razknjizujem = false
|
|
94
|
+
|
|
95
|
+
constructor({ tenant, gsm }: {
|
|
96
|
+
tenant: string,
|
|
97
|
+
gsm?: string,
|
|
98
|
+
}, opts: any) {
|
|
99
|
+
|
|
100
|
+
if (tenant==="klikvet") tenant=""
|
|
101
|
+
const asService = (tenant
|
|
102
|
+
? `${DEFAULT_SERVICE_NAME}-${tenant}`
|
|
103
|
+
: DEFAULT_SERVICE_NAME);
|
|
104
|
+
|
|
105
|
+
super(asService, opts)
|
|
106
|
+
|
|
107
|
+
this.client = new Client({ clientChecksBrokerWithHeartbeat: false });
|
|
108
|
+
this.gsm = gsm || "";
|
|
109
|
+
|
|
110
|
+
console.log("starting klikvet as", asService)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async publishMsg(what: { channel: string, payload: any }) {
|
|
114
|
+
try {
|
|
115
|
+
await super.publish(what.channel, what.payload)
|
|
116
|
+
} catch (err) {
|
|
117
|
+
console.log('publish failed, continue working', err.message);
|
|
118
|
+
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async resetMongo() {
|
|
123
|
+
if (this.mongo) await this.mongo.close()
|
|
124
|
+
this.mongo = new Mongo()
|
|
125
|
+
this.mongo.useSoftDelete(true)
|
|
126
|
+
this.mongo.useRevisions(true)
|
|
127
|
+
this.mongo.useAuditing(true)
|
|
128
|
+
this.mongo.emitPublishEvents(true)
|
|
129
|
+
this.mongo.on('publish', this.publishMsg.bind(this))
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async closeMongo() {
|
|
133
|
+
if (this.mongo) await this.mongo.close()
|
|
134
|
+
this.mongo = undefined;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async onError(err: any, req: any, opts: any) {
|
|
138
|
+
console.error("klikvet logic error: follow err, req, opts");
|
|
139
|
+
console.dir(err, { depth: 10 });
|
|
140
|
+
console.dir(req, { depth: 10 });
|
|
141
|
+
console.dir(opts, { depth: 10 });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async process(data: KlikvetClientRequest) : Promise<any> {
|
|
145
|
+
let ret
|
|
146
|
+
try {
|
|
147
|
+
await this.resetMongo()
|
|
148
|
+
ret = await this.processLogic(data);
|
|
149
|
+
} catch (err) {
|
|
150
|
+
console.log('klikvet/process error', err);
|
|
151
|
+
throw err
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
await this.closeMongo()
|
|
155
|
+
|
|
156
|
+
return ret;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async processLogic(data: KlikvetClientRequest) : Promise<any> {
|
|
160
|
+
|
|
161
|
+
log.debug(`klikvet worker request of type ${typeof data}`, data)
|
|
162
|
+
|
|
163
|
+
// console.log('data', data);
|
|
164
|
+
|
|
165
|
+
if (data === 'ping') {
|
|
166
|
+
return 'pong from ' + this.service;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (typeof data === "string" && (data as string)?.match?.(/^ping/i)) {
|
|
170
|
+
let ms = (data as string).match(/\d+/)?.[0]
|
|
171
|
+
console.log('ms', ms);
|
|
172
|
+
|
|
173
|
+
if (ms) await sleep(parseInt(ms))
|
|
174
|
+
return 'pong from ' + this.service + (ms ? ` after ${ms}ms` : '')
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (data.operation === 'ping') {
|
|
178
|
+
return { ping: 'pong' }
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
assert(data.operation, 'must specify operation')
|
|
182
|
+
assert(this.client, 'missing EbusClient')
|
|
183
|
+
|
|
184
|
+
if (data.operation === 'promet-get-config') {
|
|
185
|
+
return promet;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (data.operation === 'promet-create-pipeline') {
|
|
189
|
+
assert(data.spec, 'must specify data.spec')
|
|
190
|
+
return promet.createAggregationPipeline(data.spec)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (data.operation === 'racuni-isci-create-pipeline') {
|
|
194
|
+
assert(data.spec, 'must specify data.spec')
|
|
195
|
+
return racuni.isci.createAggregationPipeline(data.spec)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (data.operation === 'promet-exec-pipeline') {
|
|
199
|
+
assert(data.tenant, 'must specify tenant')
|
|
200
|
+
assert(data.pipeline || data.spec, 'must specify data.spec or data.pipeline')
|
|
201
|
+
if (!data.pipeline) data.pipeline = await promet.createAggregationPipeline(data.spec!)
|
|
202
|
+
let res = await promet.execPipeline(data.pipeline.pipeline || data.pipeline, data.tenant)
|
|
203
|
+
// res.pipeline = data.pipeline;
|
|
204
|
+
return res;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (data.operation === 'racuni-isci-exec-pipeline') {
|
|
208
|
+
assert(data.tenant, 'must specify tenant')
|
|
209
|
+
assert(data.pipeline || data.spec, 'must specify data.spec or data.pipeline')
|
|
210
|
+
if (!data.pipeline) data.pipeline = await racuni.isci.createAggregationPipeline(data.spec!)
|
|
211
|
+
let res = await racuni.isci.execPipeline(data.tenant, data.pipeline.pipeline || data.pipeline)
|
|
212
|
+
//res.pipeline = data.pipeline;
|
|
213
|
+
return res;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (data.operation === 'porocilo-racunovodji') {
|
|
217
|
+
assert(data.tenant, 'must tenant')
|
|
218
|
+
assert(data.odDne, 'must odDne')
|
|
219
|
+
assert(data.doDne, 'must doDne')
|
|
220
|
+
|
|
221
|
+
let pipeline = racunovodji.createAggregationPipeline(data)
|
|
222
|
+
let podatki = await racunovodji.execPipeline(pipeline.pipeline, data.tenant)
|
|
223
|
+
let prviZadnji = await racunovodji.getFirstLastBills(data.tenant, pipeline.match)
|
|
224
|
+
let kategorije = await racunovodji.getCategories(data.tenant, pipeline.match)
|
|
225
|
+
let racuniPravnim = data.racuniPravnim ? await racunovodji.getTaxBills(data.tenant, pipeline.match) : []
|
|
226
|
+
let racuniOdlozeno = data.racuniOdlozeno ? await racunovodji.getTrrBills(data.tenant, pipeline.match) : []
|
|
227
|
+
let stornirani = await zakljucekBlagajne.storniraniRacuni(pipeline.match, data.tenant)
|
|
228
|
+
let placila = await zakljucekBlagajne.sestevekPlacil(data.tenant, { ...data, rounding: 2 });
|
|
229
|
+
let pred = await zalogaNaDan({ datum: new Date(new Date(data.odDne).valueOf() - 24 * 60 * 60 * 1000), tenant: data.tenant })
|
|
230
|
+
let po = await zalogaNaDan({ datum: new Date(data.doDne), tenant: data.tenant })
|
|
231
|
+
let predKonsignacija = await zalogaNaDan({ datum: new Date(new Date(data.odDne).valueOf() - 24 * 60 * 60 * 1000), tenant: data.tenant, samoKonsignacija: true })
|
|
232
|
+
let poKonsignacija = await zalogaNaDan({ datum: new Date(data.doDne), tenant: data.tenant, samoKonsignacija: true })
|
|
233
|
+
let spremembaZaloge = await spremembaZalogeZaObdobje({ ...data, poVrstah: true })
|
|
234
|
+
let spremembaKonsignacije = await spremembaZalogeZaObdobje({ ...data, poVrstah: true, samoKonsignacija: true })
|
|
235
|
+
let vsotaDobav = await VsotaDobavZaObdobje({ ...data })
|
|
236
|
+
|
|
237
|
+
return { podatki, racuniOdlozeno, racuniPravnim, kategorije, stornirani, placila, zaloga: { pred, po }, konsignacija: { pred: predKonsignacija, po: poKonsignacija }, spremembaZaloge, spremembaKonsignacije, vsotaDobav, prviZadnji };
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (data.operation === 'zakljucek-blagajne') {
|
|
241
|
+
let pipeline = zakljucekBlagajne.createAggregationPipeline(data)
|
|
242
|
+
let zakljucek = await zakljucekBlagajne.execPipeline(pipeline.pipeline, data.tenant)
|
|
243
|
+
let stornirani = await zakljucekBlagajne.storniraniRacuni(pipeline.match, data.tenant)
|
|
244
|
+
return { zakljucek, stornirani };
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (data.operation === 'moj-promet') {
|
|
248
|
+
assert(data.username, 'must specify username')
|
|
249
|
+
assert(data.odDne, 'must specify odDne')
|
|
250
|
+
assert(data.doDne, 'must specify doDne')
|
|
251
|
+
|
|
252
|
+
let pipeline = mojPromet.createAggregationPipeline(data)
|
|
253
|
+
let podatki = await mojPromet.execPipeline(pipeline.pipeline, data.tenant)
|
|
254
|
+
return podatki;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (data.operation === 'prodano') {
|
|
258
|
+
assert(data.tenant, 'must specify tenant')
|
|
259
|
+
assert(data.odDne, 'must specify odDne')
|
|
260
|
+
assert(data.doDne, 'must specify doDne')
|
|
261
|
+
|
|
262
|
+
let pipeline = prodano.createAggregationPipeline(data)
|
|
263
|
+
let podatki = await prodano.execPipeline(pipeline.pipeline, data.tenant)
|
|
264
|
+
return podatki;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (data.operation === 'prodano-porabljeno') {
|
|
268
|
+
assert(data.tenant, 'must specify tenant')
|
|
269
|
+
let podatki = await prodanoInPorabljeno(data)
|
|
270
|
+
return podatki;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (data.operation === 'skupine-izdelkov') {
|
|
274
|
+
let res = await this.dbFind(data.tenant, "skupineArtiklov", {}, { sort: { skupina: 1 } })
|
|
275
|
+
return res;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (data.operation === 'skupine-strank') {
|
|
279
|
+
let res = await this.dbFind(data.tenant, "skupineStrank", {}, { sort: { skupina: 1 } })
|
|
280
|
+
return res;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (data.operation === 'stranka-info') {
|
|
284
|
+
let res = await stranke.infoStranke(data.tenant, data._id)
|
|
285
|
+
return res;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (data.operation === 'get-certs') {
|
|
289
|
+
let res = await certs.getAll(data.tenant)
|
|
290
|
+
return res;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (data.operation === 'get-certs-valid') {
|
|
294
|
+
let res = await certs.getValid(data.tenant, data.query)
|
|
295
|
+
return res;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (data.operation === 'furs-register-cert') {
|
|
299
|
+
assert(data.certBase64, "must specify certBase64")
|
|
300
|
+
assert(data.certPass, "must specify certPass")
|
|
301
|
+
assert(this.client)
|
|
302
|
+
let timeoutError = ""
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
timeoutError = "furs/cert: FURS podsistem se ni odzval."
|
|
306
|
+
let res: { certSerial: string, certTaxNo: number, certName: string, certValidUntil: Date, certIssuer: string } | undefined = (await this.client.request('durs', { operation: 'add cert', data: { cert: data.certBase64, password: data.certPass } }, { receiveTimeout: 2000 }));
|
|
307
|
+
log.debug('furs-reg-cert: durs add cert returned“', res);
|
|
308
|
+
|
|
309
|
+
if (!res) {
|
|
310
|
+
return { certMessage: "furs/cert ni nič vrnil", certOk: false }
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
timeoutError = "furs/cert: spodletelo je pisanje v bazo."
|
|
314
|
+
|
|
315
|
+
await this.client.request('db', {
|
|
316
|
+
operation: 'hardDeleteOne',
|
|
317
|
+
collection: 'certifikati',
|
|
318
|
+
db: data.tenant,
|
|
319
|
+
query: { serijskaStevilka: res.certSerial }
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
let req = {
|
|
323
|
+
operation: 'upsert',
|
|
324
|
+
collection: 'certifikati',
|
|
325
|
+
db: data.tenant,
|
|
326
|
+
query: { serijskaStevilka: res.certSerial },
|
|
327
|
+
update: {
|
|
328
|
+
certOk: true,
|
|
329
|
+
davcnaStevilka: res.certTaxNo,
|
|
330
|
+
podjetje: res.certName,
|
|
331
|
+
serijskaStevilka: res.certSerial,
|
|
332
|
+
veljaDo: res.certValidUntil,
|
|
333
|
+
izdajatelj: res.certIssuer,
|
|
334
|
+
certBase64: data.certBase64,
|
|
335
|
+
certPass: data.certPass,
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
let cert = (await this.client.request('db', req, { receiveTimeout: 2000 }));
|
|
339
|
+
log.debug('furs-reg-cert: cert saved to db', cert);
|
|
340
|
+
|
|
341
|
+
if (!cert) return {
|
|
342
|
+
certMessage: "Pisanje v bazo je spodletelo. Ponovno dodajte potrdilo.",
|
|
343
|
+
certOk: false,
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
let ret = {
|
|
347
|
+
certOk: true,
|
|
348
|
+
certMessage: "digitalno potrdilo sprejeto",
|
|
349
|
+
cert,
|
|
350
|
+
tenant: data.tenant,
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
log.info("furs-reg-cert returns", ret)
|
|
354
|
+
|
|
355
|
+
return ret;
|
|
356
|
+
|
|
357
|
+
} catch (err) {
|
|
358
|
+
|
|
359
|
+
// console.log('err',err);
|
|
360
|
+
|
|
361
|
+
if (err.reason === "reject" && err.data.message && /Invalid password/gi.test(err.data.message)) {
|
|
362
|
+
return {
|
|
363
|
+
certMessage: "Napačno geslo.",
|
|
364
|
+
certOk: false,
|
|
365
|
+
}
|
|
366
|
+
} else if (err.reason === "timeout") {
|
|
367
|
+
return {
|
|
368
|
+
certMessage: timeoutError,
|
|
369
|
+
certOk: false,
|
|
370
|
+
}
|
|
371
|
+
} else {
|
|
372
|
+
log.error("furs-reg-cert", err.message)
|
|
373
|
+
return {
|
|
374
|
+
certMessage: "furs/cert: " + (err.reason),
|
|
375
|
+
certOk: false,
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (data.operation === 'furs-remove-cert') {
|
|
383
|
+
|
|
384
|
+
assert(data.certId, "must specify certId")
|
|
385
|
+
assert(data.taxNo, "must specify taxNo")
|
|
386
|
+
|
|
387
|
+
log.debug('removing cert', data);
|
|
388
|
+
|
|
389
|
+
let result = await this.client.request('durs',
|
|
390
|
+
{ operation: 'remove cert', data: { taxNo: data.taxNo, } }, { receiveTimeout: 2000 });
|
|
391
|
+
|
|
392
|
+
log.trace('cert removed', result);
|
|
393
|
+
|
|
394
|
+
return {
|
|
395
|
+
ok: true,
|
|
396
|
+
result: result
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if (data.operation === "furs-register-premise") {
|
|
402
|
+
|
|
403
|
+
assert(data.poslovniProstor, "must specify poslovniProstor (its _id)")
|
|
404
|
+
assert(data.Premise, "must specify Premise")
|
|
405
|
+
assert(data.DursEnv, "must specify DursEnv")
|
|
406
|
+
assert(data.tenant, "must specify tenant")
|
|
407
|
+
assert(data.taxNo, "must specify taxNo")
|
|
408
|
+
let timeoutError = ""
|
|
409
|
+
|
|
410
|
+
try {
|
|
411
|
+
timeoutError = "furs/pp: FURS podsistem se ni odzval."
|
|
412
|
+
let res: { success?: boolean, error?: string, result?: any } | undefined = (await this.client.request('durs', {
|
|
413
|
+
operation: 'register premise',
|
|
414
|
+
data: { Premise: data.Premise, DursEnv: data.DursEnv, tenant: data.tenant, }
|
|
415
|
+
}, { receiveTimeout: 4000 }));
|
|
416
|
+
log.debug('furs-register-premise: durs register premise returned', res);
|
|
417
|
+
if (!res) return {
|
|
418
|
+
success: false,
|
|
419
|
+
message: `Furs worker ni vrnil podatkov.`
|
|
420
|
+
}
|
|
421
|
+
if (res.success === false && /ENOENT\: no such file or directory/.test(res?.error || "")) {
|
|
422
|
+
// no cert, try to register it
|
|
423
|
+
let certData: { certBase64: string, certPass: string } | undefined = (await this.client.request('db', {
|
|
424
|
+
operation: 'findOne',
|
|
425
|
+
collection: 'certifikati',
|
|
426
|
+
db: data.tenant,
|
|
427
|
+
query: { davcnaStevilka: Number(data.taxNo) }
|
|
428
|
+
}));
|
|
429
|
+
if (!certData) return {
|
|
430
|
+
success: false,
|
|
431
|
+
message: `Digitalno potrdilo za ${data.taxNo} ni registrirano niti ga ni v bazi.`
|
|
432
|
+
}
|
|
433
|
+
let certRes: { certSerial: string } | undefined = (await this.client.request('durs', { operation: 'add cert', data: { cert: certData.certBase64, password: certData.certPass } }, { receiveTimeout: 2000 }));
|
|
434
|
+
log.trace("... certRes", certRes)
|
|
435
|
+
if (!certRes || !certRes.certSerial) return {
|
|
436
|
+
success: false,
|
|
437
|
+
message: `Ponovna namestitev digitalnega potrdila ${data.taxNo} je spodletela.`
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
res = (await this.client.request('durs', {
|
|
441
|
+
operation: 'register premise',
|
|
442
|
+
data: { Premise: data.Premise, DursEnv: data.DursEnv }
|
|
443
|
+
}, { receiveTimeout: 2000 }));
|
|
444
|
+
log.debug('furs-register-premise: durs register premise RETRY returned', res);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (!res?.success) return res;
|
|
448
|
+
|
|
449
|
+
timeoutError = "furs/pp: spodletelo je pisanje v bazo."
|
|
450
|
+
|
|
451
|
+
let dbres = (await this.client.request('db', {
|
|
452
|
+
operation: 'upsert',
|
|
453
|
+
collection: 'poslovalnice',
|
|
454
|
+
db: data.tenant,
|
|
455
|
+
query: { _id: data.poslovniProstor },
|
|
456
|
+
update: {
|
|
457
|
+
potrditevFurs: JSON.stringify(res?.result)
|
|
458
|
+
}
|
|
459
|
+
}, { receiveTimeout: 2000 }));
|
|
460
|
+
log.debug('furs-register-premise: premise saved to db', dbres);
|
|
461
|
+
|
|
462
|
+
if (!dbres) return {
|
|
463
|
+
message: "Pisanje v bazo je spodletelo. Ponovno prijavite poslovni prostor.",
|
|
464
|
+
success: false,
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
let ret = {
|
|
468
|
+
success: true,
|
|
469
|
+
message: "poslovni prostor je prijavljen FURS",
|
|
470
|
+
poslovalnica: dbres
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
log.info("furs-registger-premise returns", ret)
|
|
474
|
+
|
|
475
|
+
return ret;
|
|
476
|
+
|
|
477
|
+
} catch (err) {
|
|
478
|
+
|
|
479
|
+
// console.log('err', err);
|
|
480
|
+
|
|
481
|
+
if (err.reason === "reject" && err.data.message && /Invalid password/gi.test(err.data.message)) {
|
|
482
|
+
return {
|
|
483
|
+
message: "Napačno geslo.",
|
|
484
|
+
success: false,
|
|
485
|
+
}
|
|
486
|
+
} else if (err.reason === "timeout") {
|
|
487
|
+
return {
|
|
488
|
+
message: timeoutError,
|
|
489
|
+
success: false,
|
|
490
|
+
}
|
|
491
|
+
} else {
|
|
492
|
+
log.error("furs-register-premise", err.message)
|
|
493
|
+
return {
|
|
494
|
+
message: "furs/pp: " + (err.message || err.data && err.data.message),
|
|
495
|
+
success: false,
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
if (data.operation === "furs-register-invoice") {
|
|
502
|
+
let res = await this.registerInvoice(data);
|
|
503
|
+
setTimeout(async () => {
|
|
504
|
+
await this.resetMongo();
|
|
505
|
+
await this.registerAllInvoices(data);
|
|
506
|
+
await this.razknjiziRacune(data);
|
|
507
|
+
await this.closeMongo();
|
|
508
|
+
}, 2000);
|
|
509
|
+
return res
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
if (data.operation === "furs-register-all-invoices") {
|
|
513
|
+
let all = await this.registerAllInvoices(data);
|
|
514
|
+
setTimeout(async () => {
|
|
515
|
+
await this.resetMongo();
|
|
516
|
+
await this.razknjiziRacune(data);
|
|
517
|
+
await this.closeMongo();
|
|
518
|
+
}, 4000)
|
|
519
|
+
return all
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
if (data.operation === "racun-storno") {
|
|
523
|
+
assert(data.tenant, "must specify tenant")
|
|
524
|
+
assert(data, "must specify data")
|
|
525
|
+
assert(data._id, "must specify _id of the invoice")
|
|
526
|
+
return await this.storno(data.tenant, data.id || data._id)
|
|
527
|
+
};
|
|
528
|
+
|
|
529
|
+
if (data.operation === "razknjizi-racun") {
|
|
530
|
+
assert(data.tenant, "must specify tenant")
|
|
531
|
+
assert(data._id, "must specify _id of the invoice")
|
|
532
|
+
return await this.razknjiziRacun(data);
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
if (data.operation === "razknjizi-racune") {
|
|
536
|
+
assert(data.tenant, "must specify tenant")
|
|
537
|
+
return await this.razknjiziRacune(data);
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
if (data.operation === "razknjizi-blagovnice") {
|
|
541
|
+
assert(data.tenant, "must specify tenant")
|
|
542
|
+
return await this.razknjiziBlagovnice(data);
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
if (data.operation === "porabe-za-dobavnice") {
|
|
546
|
+
assert(data.tenant, "must specify tenant")
|
|
547
|
+
let ret = await this.porabeZaDobavnice(data);
|
|
548
|
+
await this.razknjiziBlagovnice(data);
|
|
549
|
+
return ret;
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
if (data.operation === "razknjizi-dobavnico") {
|
|
553
|
+
assert(data._id, "must specify _id of Dobavnica")
|
|
554
|
+
assert(data.tenant, "must specify tenant")
|
|
555
|
+
await this.razknjiziDobavnico(data._id, data.tenant)
|
|
556
|
+
|
|
557
|
+
setImmediate(async () => {
|
|
558
|
+
await this.resetMongo();
|
|
559
|
+
await this.razknjiziDobavnice(data);
|
|
560
|
+
await this.closeMongo();
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
return { ok: true }
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
if (data.operation === "razknjizi-blagovnico") {
|
|
567
|
+
assert(data._id, "must specify _id of the Blagovnica")
|
|
568
|
+
assert(data.tenant, "must specify tenant")
|
|
569
|
+
await this.razknjiziBlagovnico(data._id, data.tenant)
|
|
570
|
+
|
|
571
|
+
setImmediate(async () => {
|
|
572
|
+
await this.resetMongo();
|
|
573
|
+
await this.razknjiziBlagovnice(data);
|
|
574
|
+
await this.closeMongo();
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
return { ok: true }
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
if (data.operation === "kartica") {
|
|
581
|
+
assert(data.tenant, "must specify tenant")
|
|
582
|
+
assert(data._id, "must specify _id of Artikel")
|
|
583
|
+
assert(data.razknjizba, "must specify razknjizba")
|
|
584
|
+
|
|
585
|
+
return await karticaArtikla(data._id, data.tenant, data.razknjizba, data.skladisca_ids)
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
if (data.operation === "blagovnice") {
|
|
589
|
+
assert(data.tenant, "must specify tenant")
|
|
590
|
+
return await poisciBlagovnice(data)
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
if (data.operation === "dobava-zdravil") {
|
|
594
|
+
assert(data.tenant, "must specify tenant")
|
|
595
|
+
return await dobavaZdravil(data)
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
if (data.operation === "poraba-prodaja-zdravil") {
|
|
599
|
+
assert(data.tenant, "must specify tenant")
|
|
600
|
+
return await porabaInProdajaZdravil(data)
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
if (data.operation === "prodaja-zdravil") {
|
|
604
|
+
assert(data.tenant, "must specify tenant")
|
|
605
|
+
return await prodajaZdravil(data)
|
|
606
|
+
};
|
|
607
|
+
|
|
608
|
+
if (data.operation === "ensure-indexes") {
|
|
609
|
+
assert(data.tenant, "must specify tenant")
|
|
610
|
+
return await ensureIndexes(data.tenant)
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
if (data.operation === "zaloga-na-dan") {
|
|
614
|
+
assert(data.tenant, "must specify tenant")
|
|
615
|
+
return await zalogaNaDan(data)
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
if (data.operation === "zaloga-po-dnevih") {
|
|
619
|
+
assert(data.tenant, "must specify tenant")
|
|
620
|
+
return await zalogaPoDnevih(data)
|
|
621
|
+
};
|
|
622
|
+
|
|
623
|
+
if (data.operation === "neuporabljeno-poisci") {
|
|
624
|
+
assert(data.tenant, "must specify tenant")
|
|
625
|
+
assert(data.od, "must specify od")
|
|
626
|
+
return await poisciNeuporabljeno(data)
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
if (data.operation === "neuporabljeno-pobrisi") {
|
|
630
|
+
assert(data.tenant, "must specify tenant")
|
|
631
|
+
assert(data.od, "must specify od")
|
|
632
|
+
return await pobrisiNeuporabljeno(data)
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
if (data.operation === "sprememba-zaloge-za-obdobje") {
|
|
636
|
+
assert(data.tenant, "must specify tenant")
|
|
637
|
+
assert(data.odDne, "must specify odDne")
|
|
638
|
+
assert(data.doDne, "must specify doDne")
|
|
639
|
+
return await spremembaZalogeZaObdobje(data)
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
if (data.operation === "polna-inventura") {
|
|
643
|
+
assert(data.tenant, "must specify tenant")
|
|
644
|
+
assert(data.od, "must specify od")
|
|
645
|
+
assert(data.razknjizba, "must specify razknjizba")
|
|
646
|
+
assert(data.skladisce_id, "must specify skladisce_id")
|
|
647
|
+
assert(data.izvedel, "must specify izvedel")
|
|
648
|
+
assert(data.izlociTisteBrezZaloge !== undefined, "must specify izlociTisteBrezZaloge")
|
|
649
|
+
return await zakljucekPolneInventureSestaviInZapisi(data);
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
if (data.operation === "moj-koledar") {
|
|
653
|
+
assert(data.tenant, "must specify tenant")
|
|
654
|
+
assert(data.id, "must specify id")
|
|
655
|
+
return await koledarVeterinarja(data.tenant, data.id);
|
|
656
|
+
};
|
|
657
|
+
|
|
658
|
+
if (data.operation === "sms-narocen") {
|
|
659
|
+
assert(data.tenant, "must specify tenant")
|
|
660
|
+
assert(data.id, "must specify id")
|
|
661
|
+
return await smsNarocen({ tenant: data.tenant, id: data.id });
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
if (data.operation === "poslji-sms-narocenemu") {
|
|
665
|
+
assert(data.tenant, "must specify tenant")
|
|
666
|
+
assert(data.id || data.narocen, "must specify id or narocen")
|
|
667
|
+
assert(data.nacin, "must specify nacin")
|
|
668
|
+
let n: { smsText: string, posiljatelj: string, narocen: Narocen, zaKdaj: Date } | undefined = await smsNarocen({ tenant: data.tenant, id: data.id, narocen: data.narocen }) as { smsText: string, posiljatelj: string, narocen: Narocen, zaKdaj: Date };
|
|
669
|
+
if (!n) return undefined;
|
|
670
|
+
return await this.posljiSmsNarocenemu(data, n, this.gsm);
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
if (data.operation === "poslji-smse-narocenim") {
|
|
674
|
+
assert(data.tenant, "must specify tenant")
|
|
675
|
+
assert(data.nacin, "must specify nacin")
|
|
676
|
+
let naroceni = await smsNaroceniNaDan({ tenant: data.tenant, dan: data.dan || new Date() });;
|
|
677
|
+
if (!naroceni?.length) return undefined;
|
|
678
|
+
let res = []
|
|
679
|
+
for await (let n of naroceni) {
|
|
680
|
+
try {
|
|
681
|
+
res.push(await this.posljiSmsNarocenemu(data, n as any, this.gsm));
|
|
682
|
+
} catch (e) {
|
|
683
|
+
console.error("poslji-smse-narocenim resuming", e);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
return res;
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
if (data.operation === "poslji-sms-cepljenja") {
|
|
690
|
+
assert(data.tenant, "must specify tenant")
|
|
691
|
+
assert(data.cepljenje_id || data.cepljenje, "must specify cepljenje_id or cepljenje")
|
|
692
|
+
assert(data.pacient_id, "must specify pacient_id")
|
|
693
|
+
assert(data.nacin, "must specify nacin")
|
|
694
|
+
let n = await smsCepljen({ tenant: data.tenant, cepljenje_id: data.cepljenje_id || data.cepljenje?._id!, pacient_id: data.pacient_id, cepljenje: data.cepljenje });
|
|
695
|
+
if (!n) return undefined;
|
|
696
|
+
return await this.posljiSmsNCepljenjemu(data, n, this.gsm);
|
|
697
|
+
};
|
|
698
|
+
|
|
699
|
+
if (data.operation === "poslji-smse-cepljenim") {
|
|
700
|
+
assert(data.tenant, "must specify tenant")
|
|
701
|
+
assert(data.nacin, "must specify nacin")
|
|
702
|
+
let cepiti = await smsCepljenjaNaDan({ tenant: data.tenant, dan: data.dan || new Date(), dniPrej: data.dniPrej });;
|
|
703
|
+
if (!cepiti?.length) return undefined;
|
|
704
|
+
let res = []
|
|
705
|
+
for await (let n of cepiti) {
|
|
706
|
+
try {
|
|
707
|
+
res.push(await this.posljiSmsNCepljenjemu(data, n, this.gsm));
|
|
708
|
+
} catch (e) {
|
|
709
|
+
console.error("poslji-smse-narocenim resuming", e);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
return res;
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
if (data.operation === "seznam-cepljenj-za-sms") {
|
|
716
|
+
assert(data.tenant, "must specify tenant")
|
|
717
|
+
return await smsCepljenjaNaDan({ tenant: data.tenant, dan: data.dan || new Date(), dniPrej: data.dniPrej });;
|
|
718
|
+
};
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
if (data.operation === "seznam-narocenih-za-sms") {
|
|
722
|
+
assert(data.tenant, "must specify tenant")
|
|
723
|
+
return await smsNaroceniNaDan({ tenant: data.tenant, dan: data.dan || new Date() });;
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
if (data.operation === "potrditev-brejosti") {
|
|
727
|
+
assert(data.tenant, "must specify tenant")
|
|
728
|
+
assert(data._id, "must specify _id")
|
|
729
|
+
assert(data.kdo, "must specify kdo")
|
|
730
|
+
let osemenitevGoveda = (await this.dbFindById(data.tenant || data.db || "", "osemenitevGoveda", data._id)) as OsemenitevGoveda;
|
|
731
|
+
if (osemenitevGoveda) {
|
|
732
|
+
let update = updatePotrditevBrejosti(osemenitevGoveda, data.breja, data.kdo);
|
|
733
|
+
if (update)
|
|
734
|
+
return await this.dbUpdateById(data.tenant || data.db || "", "osemenitevGoveda", data._id, update)
|
|
735
|
+
}
|
|
736
|
+
return undefined
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
if (data.operation === "v-presusitev") {
|
|
740
|
+
assert(data.tenant, "must specify tenant")
|
|
741
|
+
assert(data._id, "must specify _id")
|
|
742
|
+
assert(data.kdo, "must specify kdo")
|
|
743
|
+
let osemenitevGoveda = (await this.dbFindById(data.tenant || data.db || "", "osemenitevGoveda", data._id)) as OsemenitevGoveda;
|
|
744
|
+
if (osemenitevGoveda) {
|
|
745
|
+
if (osemenitevGoveda) {
|
|
746
|
+
let update = updatePresusitve(osemenitevGoveda, data.presusitev, data.kdo);
|
|
747
|
+
if (update)
|
|
748
|
+
return await this.dbUpdateById(data.tenant || data.db || "", "osemenitevGoveda", data._id, update)
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
return undefined
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
if (data.operation === "status-osemenitve") {
|
|
755
|
+
assert(data.tenant, "must specify tenant")
|
|
756
|
+
assert(data._id, "must specify _id")
|
|
757
|
+
assert(data.kdo, "must specify kdo")
|
|
758
|
+
let osemenitevGoveda = (await this.dbFindById(data.tenant || data.db || "", "osemenitevGoveda", data._id)) as OsemenitevGoveda;
|
|
759
|
+
if (osemenitevGoveda) {
|
|
760
|
+
let update = updateStatusOsemenitve(osemenitevGoveda, data.status, data.kdo);
|
|
761
|
+
if (update)
|
|
762
|
+
return await this.dbUpdateById(data.tenant || data.db || "", "osemenitevGoveda", data._id, update)
|
|
763
|
+
}
|
|
764
|
+
return undefined
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
if (data.operation === "opomba-rejca-osemenitve") {
|
|
768
|
+
assert(data.tenant, "must specify tenant")
|
|
769
|
+
assert(data._id, "must specify _id")
|
|
770
|
+
assert(data.kdo, "must specify kdo")
|
|
771
|
+
let osemenitevGoveda = (await this.dbFindById(data.tenant || data.db || "", "osemenitevGoveda", data._id)) as OsemenitevGoveda;
|
|
772
|
+
if (osemenitevGoveda) {
|
|
773
|
+
let update = updateOpombeRejca(osemenitevGoveda, data.opomba, data.kdo);
|
|
774
|
+
if (update)
|
|
775
|
+
return await this.dbUpdateById(data.tenant || data.db || "", "osemenitevGoveda", data._id, update)
|
|
776
|
+
}
|
|
777
|
+
return undefined
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
if (data.operation === "podatki-rejca") {
|
|
781
|
+
assert(data.tenant, "must specify tenant")
|
|
782
|
+
assert(data.rejciGeslo, "must specify rejciGeslo")
|
|
783
|
+
assert(data.rejciKoda, "must specify rejciKoda")
|
|
784
|
+
return await podatkiRejca(data);
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
if (data.operation === "zaracunaj-dobavnice") {
|
|
788
|
+
assert(data.tenant, "must specify tenant")
|
|
789
|
+
assert(data.dobavnice_ids, "must specify dobavnice_ids");
|
|
790
|
+
assert(data.lokacija_id, "must specify lokacija_id");
|
|
791
|
+
assert(data.naprava_id, "must specify naprava_id");
|
|
792
|
+
assert(data.izdal, "must specify izdal");
|
|
793
|
+
return await zaracunajDobavnice(data);
|
|
794
|
+
};
|
|
795
|
+
|
|
796
|
+
if (data.operation === "anonimiziraj-podatke") {
|
|
797
|
+
assert(data.tenant, "must specify tenant")
|
|
798
|
+
assert(["demo", "demo2", "dev", "test"].includes(data.tenant), "cnly valid for demo, dev, test");
|
|
799
|
+
assert(data.letNazaj, "must specify letNazaj");
|
|
800
|
+
|
|
801
|
+
return await anonimizirajPodatke(createMongoForAnonimizacija(data.tenant), parseInt(data.letNazaj.toString() || "1"));
|
|
802
|
+
};
|
|
803
|
+
|
|
804
|
+
if (data.operation === "zdruzi-stranke") {
|
|
805
|
+
assert(data.tenant, "must specify tenant")
|
|
806
|
+
assert(data.v, "must specify v");
|
|
807
|
+
assert(data.iz, "must specify iz");
|
|
808
|
+
|
|
809
|
+
return await this.zdruziStranke(data);
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
assert(false, 'unsupported operation ' + (data as { operation: string }).operation)
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
/** PRIVATE */
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
async dbNastavitve(tenant: string) {
|
|
820
|
+
this.mongo!.setDb(tenant)
|
|
821
|
+
return (await this.mongo!.findOne("nastavitve", {})) as Nastavitve;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
async dbFindById<T>(db: string, collection: string, _id: string) {
|
|
825
|
+
this.mongo!.setDb(db)
|
|
826
|
+
return await this.mongo!.findById(collection, _id) as T
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
async dbFind<T>(db: string, collection: string, query: Obj, opts?: Obj) {
|
|
830
|
+
this.mongo!.setDb(db)
|
|
831
|
+
return await this.mongo!.find(collection, query, opts) as T[]
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
async dbUpdateById(db: string, collection: string, _id: string, update: Obj) {
|
|
835
|
+
this.mongo!.setDb(db)
|
|
836
|
+
return await this.mongo!.updateOne(collection, { _id }, update)
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
async dbUpsert(db: string, collection: string, _id: string, update: Obj) {
|
|
840
|
+
this.mongo!.setDb(db)
|
|
841
|
+
return await this.mongo!.upsert(collection, { _id }, update)
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
async posljiSmsNarocenemu(data: Obj, n: { smsText: string, posiljatelj: string, narocen: Narocen, zaKdaj: Date }, gsm: string) {
|
|
845
|
+
|
|
846
|
+
let res: { res: Obj } | undefined = (await this.client?.request('sms', {
|
|
847
|
+
operation: 'send',
|
|
848
|
+
text: n.smsText,
|
|
849
|
+
sender: n.posiljatelj,
|
|
850
|
+
gsm: gsm || n.narocen.opomnikStevilka,
|
|
851
|
+
}, { receiveTimeout: 2000 }));
|
|
852
|
+
|
|
853
|
+
let smsRes = res?.res;
|
|
854
|
+
let sentOk = smsRes?.Packet.Body?.Item?.Content === "Message sent";
|
|
855
|
+
let napaka = !sentOk ? smsRes?.Packet.Body?.Item?.Content : undefined;;
|
|
856
|
+
let _id = smsRes?.Packet.Header?.ID;
|
|
857
|
+
console.dir(smsRes, { depth: 20 });
|
|
858
|
+
|
|
859
|
+
if (_id) {
|
|
860
|
+
this.mongo!.setDb(data.tenant)
|
|
861
|
+
await this.mongo!.upsert("smsOddaje", { _id }, {
|
|
862
|
+
besedilo: n.smsText,
|
|
863
|
+
datum: new Date(),
|
|
864
|
+
status: sentOk ? "oddano" : "napaka",
|
|
865
|
+
napaka,
|
|
866
|
+
nacin: data.nacin,
|
|
867
|
+
kdo: data.kdo,
|
|
868
|
+
gsm,
|
|
869
|
+
narocen_id: n.narocen._id,
|
|
870
|
+
pacient_id: n.narocen.pacient_id,
|
|
871
|
+
stranka_id: n.narocen.stranka_id,
|
|
872
|
+
zaKdaj: n.zaKdaj,
|
|
873
|
+
} as Obj);
|
|
874
|
+
if (data.nacin === "samodejno") {
|
|
875
|
+
await this.mongo!.upsert("naroceni", { _id: n.narocen._id },
|
|
876
|
+
(napaka ? { smsOddaja_napaka: { _id, napaka, } } : { smsOddaja_id: _id, }) as Obj
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
return smsRes
|
|
881
|
+
}
|
|
882
|
+
async posljiSmsNCepljenjemu(data: Obj, n: Obj, gsm: string) {
|
|
883
|
+
let res: { res: Obj } | undefined = (await this.client?.request('sms', {
|
|
884
|
+
operation: 'send',
|
|
885
|
+
text: n.smsText,
|
|
886
|
+
sender: n.posiljatelj,
|
|
887
|
+
gsm: gsm || n.cepljenje.opomnikStevilka,
|
|
888
|
+
}, { receiveTimeout: 4000 }));
|
|
889
|
+
|
|
890
|
+
let smsRes = res?.res;
|
|
891
|
+
let sentOk = smsRes?.Packet.Body?.Item?.Content === "Message sent";
|
|
892
|
+
let napaka = !sentOk ? smsRes?.Packet.Body?.Item?.Content : undefined;;
|
|
893
|
+
let _id = smsRes?.Packet.Header?.ID;
|
|
894
|
+
console.dir(smsRes, { depth: 20 });
|
|
895
|
+
|
|
896
|
+
if (_id) {
|
|
897
|
+
this.mongo!.setDb(data.tenant)
|
|
898
|
+
await this.mongo!.upsert("smsOddaje", { _id }, {
|
|
899
|
+
besedilo: n.smsText,
|
|
900
|
+
datum: new Date(),
|
|
901
|
+
status: sentOk ? "oddano" : "napaka",
|
|
902
|
+
napaka,
|
|
903
|
+
nacin: data.nacin,
|
|
904
|
+
kdo: data.kdo,
|
|
905
|
+
gsm,
|
|
906
|
+
cepljenje_id: n.cepljenje._id,
|
|
907
|
+
pacient_id: n.pacient._id,
|
|
908
|
+
stranka_id: n.pacient.stranka_id,
|
|
909
|
+
zaKdaj: n.zaKdaj,
|
|
910
|
+
} as Obj)
|
|
911
|
+
if (data.nacin === "samodejno" && !napaka) {
|
|
912
|
+
if (!napaka) n.pacient.cepljenja[n.cepljenje._id].smsOddaja_id = _id;
|
|
913
|
+
else n.pacient.cepljenja[n.cepljenje._id].smsOddaja_napaka = { napaka, _id };
|
|
914
|
+
await this.mongo!.upsert("pacienti", { _id: n.pacient._id }, {
|
|
915
|
+
cepljenja: n.pacient.cepljenja
|
|
916
|
+
} as Obj)
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return smsRes
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
async razknjiziRacun(data: { tenant: string, _id: string }) {
|
|
923
|
+
if (this.razknjizujem) return { ok: false, error: "worker že razknjižuje" };
|
|
924
|
+
this.razknjizujem = true;
|
|
925
|
+
try {
|
|
926
|
+
let racun = await this.dbFindById<Racun>(data.tenant, "racuni", data._id) as Racun;
|
|
927
|
+
if (!racun) return
|
|
928
|
+
let nastavitve = await this.dbNastavitve(data.tenant);
|
|
929
|
+
if (racun.razknjizen) return;
|
|
930
|
+
if (racun.razknjizbaPreskocena) return;
|
|
931
|
+
if (racun.neRazknjizi==="zbirnika") return;
|
|
932
|
+
this.mongo!.setDb(data.tenant)
|
|
933
|
+
this.mongo!.setAudit({ tenant: data.tenant, app: "klikvet/razknjiziRacun" })
|
|
934
|
+
await spremeniZalogoNaPodlagiRacuna(racun, nastavitve, this.mongo as any)
|
|
935
|
+
await this.pobrisiZalogoNaDan(data.tenant, [racun.datum])
|
|
936
|
+
this.razknjizujem = false;
|
|
937
|
+
return { ok: true }
|
|
938
|
+
} catch (err) {
|
|
939
|
+
console.error("razknjiziRacun", data.tenant, err?.message || err)
|
|
940
|
+
this.razknjizujem = false;
|
|
941
|
+
return { ok: false, error: err?.message || err }
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
async zdruziStranke(data: {
|
|
946
|
+
tenant: string,
|
|
947
|
+
v: string,
|
|
948
|
+
iz: string[],
|
|
949
|
+
}) {
|
|
950
|
+
this.mongo!.setDb(data.tenant)
|
|
951
|
+
this.mongo!.setAudit({ tenant: data.tenant, app: "klikvet/razknjiziDobavnice" })
|
|
952
|
+
return await zdruziStranke(data.iz, data.v, this.mongo!);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
async razknjiziRacune(data: { tenant: string }) {
|
|
956
|
+
if (this.razknjizujem) return { ok: false, error: "worker že razknjižuje" };
|
|
957
|
+
this.razknjizujem = true;
|
|
958
|
+
try {
|
|
959
|
+
this.mongo!.setDb(data.tenant)
|
|
960
|
+
this.mongo!.setAudit({ tenant: data.tenant, app: "klikvet/razknjiziRacune" })
|
|
961
|
+
|
|
962
|
+
let dni = 14 * 24 * 60 * 60 * 1000; // 14 dni
|
|
963
|
+
let od = new Date(new Date().valueOf() - dni);
|
|
964
|
+
let racuni = await this.mongo!.find("racuni", {
|
|
965
|
+
datum: { $gte: od },
|
|
966
|
+
razknjizen: { $not: { $type: "date" } },
|
|
967
|
+
razknjizbaPreskocena: { $exists: false },
|
|
968
|
+
}, {}) as RacunZaKnjizbo[] | undefined;
|
|
969
|
+
let nastavitve = await this.dbNastavitve(data.tenant);
|
|
970
|
+
let datumi = []
|
|
971
|
+
for await (let racun of racuni || []) {
|
|
972
|
+
datumi.push(racun.datum)
|
|
973
|
+
await spremeniZalogoNaPodlagiRacuna(racun, nastavitve, this.mongo as any)
|
|
974
|
+
console.log('z zamikom razknjižen račun št. ', racun.stevilka);
|
|
975
|
+
}
|
|
976
|
+
await this.pobrisiZalogoNaDan(data.tenant, datumi)
|
|
977
|
+
this.razknjizujem = false;
|
|
978
|
+
return { ok: true, racuni }
|
|
979
|
+
|
|
980
|
+
} catch (err) {
|
|
981
|
+
console.error("razknjiziRacune", data.tenant, err?.message || err)
|
|
982
|
+
this.razknjizujem = false;
|
|
983
|
+
return { ok: false, error: err?.message || err, racuni: [] }
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
async pobrisiZalogoNaDan(db: string, datumi: Date[]) {
|
|
988
|
+
try {
|
|
989
|
+
if (!datumi) return;
|
|
990
|
+
if (!Array.isArray(datumi)) datumi = []
|
|
991
|
+
if (!datumi.length) return;
|
|
992
|
+
let od = new Date(Math.min(...datumi.map(d => d.valueOf())) - 24 * 60 * 60 * 1000);
|
|
993
|
+
this.mongo!.setDb(db)
|
|
994
|
+
this.mongo!.setAudit({ tenant: db, app: "klikvet/pobrisiZalogoNaDan" })
|
|
995
|
+
|
|
996
|
+
if (od.valueOf() > 0) await this.mongo!.hardDelete("zalogaNaDan", { datum: { $gte: od } });
|
|
997
|
+
else console.log("pobrisiZalogoNaDan napačni datumi", datumi)
|
|
998
|
+
} catch (err) {
|
|
999
|
+
console.log("pobrisiZalogoNaDan error", err);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
async skladisceLokacije(lokacija_id: string, tenant: string) {
|
|
1004
|
+
let vsa: Skladisce[] = (await this.dbFind(tenant, "skladisca", { _deleted: { $exists: false } })) as Skladisce[];
|
|
1005
|
+
let moje = vsa.filter(s => s.lokacija_id.toString() === lokacija_id);
|
|
1006
|
+
if (moje.length === 0) moje = vsa;
|
|
1007
|
+
if (moje.length == 0) console.error("Ni skladišča za lokacijo", lokacija_id);
|
|
1008
|
+
if (moje.length > 1) console.error("Več skladišč za lokacijo", lokacija_id);
|
|
1009
|
+
return moje?.[0]
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
async porabeZaDobavnice(data: { tenant: string, username: string }) {
|
|
1013
|
+
|
|
1014
|
+
let nastavitve = await this.dbNastavitve(data.tenant);
|
|
1015
|
+
let lokacije = await this.dbFind<Lokacija>(data.tenant, "lokacije", {});
|
|
1016
|
+
let od = new Date(new Date().valueOf() - 365 * 24 * 60 * 60 * 1000);
|
|
1017
|
+
|
|
1018
|
+
let nerazknijzene = await this.dbFind<Dobavnica>(data.tenant, "dobavnice", {
|
|
1019
|
+
datumDokumenta: { $gte: od },
|
|
1020
|
+
status: { $in: ["izdana", "zaračunana"] },
|
|
1021
|
+
poraba_id: { $exists: false },
|
|
1022
|
+
razknjizbaPreskocena: { $exists: false },
|
|
1023
|
+
_deleted: { $exists: false }
|
|
1024
|
+
}, { sort: { datumDokumenta: 1 } });
|
|
1025
|
+
|
|
1026
|
+
let artikel_ids = dedup(nerazknijzene.map(d => d.postavke.map(p => p.artikel_id?.toString())).flat());
|
|
1027
|
+
|
|
1028
|
+
let artikli = await this.dbFind<ArtikelOsnova>(data.tenant, "artikli", {
|
|
1029
|
+
_id: { $in: artikel_ids }
|
|
1030
|
+
})
|
|
1031
|
+
|
|
1032
|
+
let vse = 0, razknjizene = 0
|
|
1033
|
+
let napake = []
|
|
1034
|
+
for await (let dobavnica of nerazknijzene) {
|
|
1035
|
+
let lokacija = lokacije.find(l => l._id.toString() === dobavnica.lokacija_id.toString());
|
|
1036
|
+
if (!lokacija) continue;
|
|
1037
|
+
let zaPorabo = vrniPopravekDobavniceCeNiZaPorabo({
|
|
1038
|
+
dobavnica,
|
|
1039
|
+
nastavitve,
|
|
1040
|
+
lokacija
|
|
1041
|
+
})
|
|
1042
|
+
if (zaPorabo === false) continue;
|
|
1043
|
+
if (zaPorabo && typeof zaPorabo === "object" && zaPorabo.razknjizbaPreskocena) {
|
|
1044
|
+
await this.dbUpsert(data.tenant, "dobavnice", dobavnica._id, zaPorabo );
|
|
1045
|
+
continue
|
|
1046
|
+
}
|
|
1047
|
+
if (!dobavnica.lokacija_id) console.error("dobavnica nima lokacije", dobavnica._id, dobavnica.stevilka)
|
|
1048
|
+
try {
|
|
1049
|
+
let skladisce_id = dobavnica.skladisce_id || ((await this.skladisceLokacije(dobavnica.lokacija_id, data.tenant))._id);
|
|
1050
|
+
vse++
|
|
1051
|
+
let poraba = await porabaZaDobavnico({
|
|
1052
|
+
dobavnica,
|
|
1053
|
+
nastavitve,
|
|
1054
|
+
skladisce_id,
|
|
1055
|
+
lokacija_id: dobavnica.lokacija_id,
|
|
1056
|
+
username: data.username,
|
|
1057
|
+
artikli: arrayToObject(artikli, "_id"),
|
|
1058
|
+
});
|
|
1059
|
+
|
|
1060
|
+
console.log('poraba', poraba);
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
if (poraba) {
|
|
1064
|
+
poraba.status = "zaključena"
|
|
1065
|
+
let p = await this.dbUpsert(data.tenant, "odprteBlagovnice", poraba._id, poraba);
|
|
1066
|
+
await this.dbUpsert(data.tenant, "dobavnice", dobavnica._id, { poraba_id: p._id, poraba_sestavljena: new Date() });
|
|
1067
|
+
}
|
|
1068
|
+
if (poraba === null) {
|
|
1069
|
+
await this.dbUpsert(data.tenant, "dobavnice", dobavnica._id, { poraba_id: null, poraba_preskocena: new Date() });
|
|
1070
|
+
}
|
|
1071
|
+
razknjizene++
|
|
1072
|
+
} catch (err) {
|
|
1073
|
+
napake.push(err)
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
return { ok: vse === razknjizene, vse, razknjizene, napake }
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
async razknjiziBlagovnice(data: {tenant:string}) {
|
|
1080
|
+
this.mongo!.setDb(data.tenant)
|
|
1081
|
+
this.mongo!.setAudit({ tenant: data.tenant, app: "klikvet/razknjiziBlagovnice" })
|
|
1082
|
+
|
|
1083
|
+
let od = new Date(new Date().valueOf() - 60 * 24 * 60 * 60 * 1000);
|
|
1084
|
+
|
|
1085
|
+
// poišči tiste, ki bi morale že biti razknjižene, pa niso
|
|
1086
|
+
{
|
|
1087
|
+
let od = new Date(new Date().valueOf() - 3 * 60 * 24 * 60 * 60 * 1000);
|
|
1088
|
+
let vpisane = await this.dbFind<Blagovnica>(data.tenant, "blagovnice", { datum: { $gte: od } }, { project: { _id: 1, status: 1 } });
|
|
1089
|
+
let idjiVpisanih = vpisane.map(b => b._id.toString());
|
|
1090
|
+
|
|
1091
|
+
let zaPovrnit = await this.dbFind<Blagovnica>(data.tenant, "odprteBlagovnice", { _deleted: { $ne: "hack" }, status: "zaključena", datum: { $gte: od }, _id: { $nin: idjiVpisanih } }, { project: { status: 1, dokumentDobavitelja: 1, vrsta: 1 } });
|
|
1092
|
+
|
|
1093
|
+
for await (let b of zaPovrnit) {
|
|
1094
|
+
console.log("vračam blagovnico v razkljižno", data.tenant, b)
|
|
1095
|
+
await this.dbUpsert(data.tenant, "odprteBlagovnice", b._id, { razknjizena: undefined, _deleted: undefined, _vrnjenoVRazknjizbo: new Date() });
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
let nerazknijzene = await this.dbFind<Dobavnica>(data.tenant, "odprteBlagovnice",
|
|
1100
|
+
{ datum: { $gte: od }, status: "zaključena", razknjizena: { $exists: false } },
|
|
1101
|
+
{ sort: { datum: 1 } }
|
|
1102
|
+
);
|
|
1103
|
+
let vse = 0, razknjizene = 0
|
|
1104
|
+
let napake = []
|
|
1105
|
+
for await (let dobavnica of nerazknijzene) {
|
|
1106
|
+
try {
|
|
1107
|
+
vse++
|
|
1108
|
+
await this.razknjiziBlagovnico(dobavnica._id.toString(), data.tenant)
|
|
1109
|
+
razknjizene++
|
|
1110
|
+
} catch (err) {
|
|
1111
|
+
napake.push(err)
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
return { ok: vse === razknjizene, vse, razknjizene, napake }
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
async razknjiziDobavnice(data: { tenant: string }) {
|
|
1118
|
+
|
|
1119
|
+
this.mongo!.setDb(data.tenant)
|
|
1120
|
+
this.mongo!.setAudit({ tenant: data.tenant, app: "klikvet/razknjiziDobavnice" })
|
|
1121
|
+
|
|
1122
|
+
let od = new Date(new Date().valueOf() - 60 * 24 * 60 * 60 * 1000)
|
|
1123
|
+
let nerazknijzene = await this.dbFind<Dobavnica>(data.tenant, "dobavnice",
|
|
1124
|
+
{
|
|
1125
|
+
datum: { $gte: od }, status: "izdana",
|
|
1126
|
+
razknjizena: { $not: { $type: "date" } },
|
|
1127
|
+
razknjizbaPreskocena: { $exists: false },
|
|
1128
|
+
},
|
|
1129
|
+
{ sort: { datum: 1 } }
|
|
1130
|
+
);
|
|
1131
|
+
let vse = 0, razknjizene = 0
|
|
1132
|
+
let napake = []
|
|
1133
|
+
for await (let blagovnica of nerazknijzene) {
|
|
1134
|
+
try {
|
|
1135
|
+
vse++
|
|
1136
|
+
await this.razknjiziDobavnico(blagovnica._id.toString(), data.tenant)
|
|
1137
|
+
razknjizene++
|
|
1138
|
+
} catch (err) {
|
|
1139
|
+
napake.push(err)
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
return { ok: vse === razknjizene, vse, razknjizene, napake }
|
|
1143
|
+
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// async razknjiziBlagovnico(_id, tenant)
|
|
1147
|
+
// {
|
|
1148
|
+
// let nastavitve = await dbNastavitve(tenant);
|
|
1149
|
+
// this.mongo!.setDb(tenant)
|
|
1150
|
+
// this.mongo!.setAudit({ tenant, app: "klikvet/razknjiziBlagovnico/1" })
|
|
1151
|
+
|
|
1152
|
+
// await logic.zakljuciBlagovnico(_id, this.mongo);
|
|
1153
|
+
|
|
1154
|
+
// /** @type {Blagovnica}} */
|
|
1155
|
+
// let blagovnica = (/** @type {Blagovnica} */ await this.dbFindById(tenant, "blagovnice", _id))
|
|
1156
|
+
// if (!blagovnica) throw new Error(`ne morem razknjižiti blagovnice, ki je ni: ${_id}, tenant ${tenant}`)
|
|
1157
|
+
|
|
1158
|
+
// this.mongo!.setDb(tenant)
|
|
1159
|
+
// this.mongo!.setAudit({ tenant, app: "klikvet/razknjiziBlagovnico/2" })
|
|
1160
|
+
|
|
1161
|
+
// await logic.spremeniZalogoNaPodlagiBlagovnice(blagovnica, nastavitve, this.mongo);
|
|
1162
|
+
// await pobrisiZalogoNaDan(tenant, [ blagovnica.datum ]);
|
|
1163
|
+
// }
|
|
1164
|
+
|
|
1165
|
+
async razknjiziBlagovnico(_id: string, tenant: string) {
|
|
1166
|
+
|
|
1167
|
+
if (this.razknjizujem) return;
|
|
1168
|
+
this.razknjizujem = true;
|
|
1169
|
+
try {
|
|
1170
|
+
this.mongo!.setDb(tenant)
|
|
1171
|
+
this.mongo!.setAudit({ tenant, app: "klikvet/razknjiziBlagovnico" })
|
|
1172
|
+
|
|
1173
|
+
let blagovnica = await razknjiziBlagovnico(_id, this.mongo as any);
|
|
1174
|
+
this.razknjizujem = false;
|
|
1175
|
+
return blagovnica
|
|
1176
|
+
} catch (err) {
|
|
1177
|
+
console.error("razknjiziBlagovnico", tenant)
|
|
1178
|
+
}
|
|
1179
|
+
this.razknjizujem = false;
|
|
1180
|
+
return undefined
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
async razknjiziDobavnico(_id: string, tenant: string) {
|
|
1184
|
+
if (this.razknjizujem) return;
|
|
1185
|
+
this.razknjizujem = true;
|
|
1186
|
+
try {
|
|
1187
|
+
this.mongo!.setDb(tenant)
|
|
1188
|
+
this.mongo!.setAudit({ tenant, app: "klikvet/razknjiziDobavnico" })
|
|
1189
|
+
let dobavnica = await razknjiziDobavnico(_id, this.mongo as any);
|
|
1190
|
+
this.razknjizujem = false;
|
|
1191
|
+
return dobavnica
|
|
1192
|
+
} catch (err) {
|
|
1193
|
+
console.error("razknjiziDobavnico", tenant, err?.message || err)
|
|
1194
|
+
}
|
|
1195
|
+
this.razknjizujem = false;
|
|
1196
|
+
return undefined
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
async registerAllInvoices(data: { tenant: string, env: string, }) {
|
|
1200
|
+
if (this.razknjizujem) return { nall: 0, nok: 0, napake: ["worker že razknjižuje"] };
|
|
1201
|
+
this.razknjizujem = true;
|
|
1202
|
+
try {
|
|
1203
|
+
assert(data.tenant, "must specify tenant")
|
|
1204
|
+
|
|
1205
|
+
let err = null;
|
|
1206
|
+
let napake = new Set()
|
|
1207
|
+
try {
|
|
1208
|
+
|
|
1209
|
+
err = "Podsistem db ni dosegljiv."
|
|
1210
|
+
|
|
1211
|
+
this.mongo!.setDb(data.tenant)
|
|
1212
|
+
this.mongo!.setAudit({ tenant: data.tenant, app: "klikvet/registerAllInvoices" })
|
|
1213
|
+
|
|
1214
|
+
let myquery = { eor: null, negotovinski: { $ne: true }, leto: { $gte: 2022 } };
|
|
1215
|
+
let env = data.env || (await this.mongo!.findOne<Nastavitve>("nastavitve", {}))?.okolje || "error"
|
|
1216
|
+
|
|
1217
|
+
let all = await this.mongo!.find<Racun>("racuni", myquery, { project: { _id: 1 }, limit: 1000, })
|
|
1218
|
+
err = "Napaka pri potrjevanju računov."
|
|
1219
|
+
|
|
1220
|
+
let n = 0;
|
|
1221
|
+
try {
|
|
1222
|
+
for await (let r of all) {
|
|
1223
|
+
let res = await this.registerInvoice({ tenant: data.tenant, env, _id: r._id.toString() }, true);
|
|
1224
|
+
if (res instanceof Error || typeof res === "string") {
|
|
1225
|
+
console.error("cannot register invoice (1)",data.tenant,r._id,res)
|
|
1226
|
+
} else {
|
|
1227
|
+
if (res.eor) n++;
|
|
1228
|
+
if (res.fursError) napake.add(res.fursError)
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
} catch (e) {
|
|
1232
|
+
err = e.message;
|
|
1233
|
+
console.log('err', err);
|
|
1234
|
+
throw new Error()
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
this.razknjizujem = false;
|
|
1238
|
+
return { nall: all.length, nok: n, napake: [...napake] };
|
|
1239
|
+
|
|
1240
|
+
} catch (err) {
|
|
1241
|
+
console.error('registerAllInvoices', err);
|
|
1242
|
+
this.razknjizujem = false;
|
|
1243
|
+
throw new Error(err);
|
|
1244
|
+
}
|
|
1245
|
+
} catch (err) {
|
|
1246
|
+
console.error("registerAllInvoices", data.tenant, err?.message || err)
|
|
1247
|
+
this.razknjizujem = false;
|
|
1248
|
+
return { nall: 0, nok: 0, napake: [err.message || err] };
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
async registerCert(db: string, davcnaStevilka: string) {
|
|
1253
|
+
let cert = (await this.client?.request('db', {
|
|
1254
|
+
operation: 'findOne',
|
|
1255
|
+
db,
|
|
1256
|
+
collection: "certifikati",
|
|
1257
|
+
query: { davcnaStevilka }
|
|
1258
|
+
}, { receiveTimeout: 3000 })) as { certBase64: string, certPass: string };
|
|
1259
|
+
|
|
1260
|
+
let res = (await this.client?.request('durs', { operation: 'add cert', data: { cert: cert.certBase64, password: cert.certPass } }, { receiveTimeout: 4000 }));
|
|
1261
|
+
return res
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
async registerInvoice(data: { env:string, tenant: string, _id: string}, kasneje = false) {
|
|
1265
|
+
this.mongo!.setAudit({ tenant: data.tenant, app: "klikvet/registerInvoice" })
|
|
1266
|
+
|
|
1267
|
+
assert(data._id, "must specify _id of racun")
|
|
1268
|
+
assert(["error", "production", "test"].includes(data.env), "must specify env")
|
|
1269
|
+
assert(data.tenant, "must specify tenant")
|
|
1270
|
+
|
|
1271
|
+
let timeoutError = "";
|
|
1272
|
+
try {
|
|
1273
|
+
// poišči račun
|
|
1274
|
+
timeoutError = "Db podsistem se ni odzval."
|
|
1275
|
+
let racun = await this.dbFindById<Racun>(data.tenant, "racuni", data._id)
|
|
1276
|
+
if (!racun) return `registerInvoice for ${data.tenant}: ni računa ${data._id}`
|
|
1277
|
+
if (racun.negotovinski) return "negotovinski račun ne bo fiskaliziran";
|
|
1278
|
+
|
|
1279
|
+
let blagajna = await this.dbFindById<Blagajna>(data.tenant, "blagajne", racun.blagajna_id)
|
|
1280
|
+
if (!blagajna) throw new Error("cannot locate blagajna: " + racun.blagajna_id)
|
|
1281
|
+
let poslovalnica = await this.dbFindById<Poslovalnica>(data.tenant, "poslovalnice", blagajna.poslovalnica_id)
|
|
1282
|
+
if (!blagajna) throw new Error("cannot locate poslovalnica: " + racun.blagajna_id)
|
|
1283
|
+
let veterina = await this.dbFindById<Nastavitve>(data.tenant, "nastavitve", poslovalnica.veterina_id)
|
|
1284
|
+
if (!veterina) throw new Error("cannot locate poslovalnica: " + poslovalnica.veterina_id)
|
|
1285
|
+
if (!racun.izdalDs) throw new Error("Uporabnik verjetno nima vpisane davčne številke.")
|
|
1286
|
+
|
|
1287
|
+
// če gre za popravek računa, poveži izvorni račun na ta popravek
|
|
1288
|
+
if (racun.predhodniRacun && racun.predhodniRacun._id ) {
|
|
1289
|
+
this.dbUpdateById(data.tenant, "racuni", racun.predhodniRacun._id.toString(), {
|
|
1290
|
+
naslednjiRacun: {
|
|
1291
|
+
_id: data._id.toString(),
|
|
1292
|
+
datum: racun.datum,
|
|
1293
|
+
stevilka: racun.stevilka,
|
|
1294
|
+
}
|
|
1295
|
+
})
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
let TaxNumber = (veterina.dsCertifikata || veterina.davcnaStevilka)
|
|
1299
|
+
TaxNumber = parseInt(TaxNumber.toString().match(/\d+/)?.toString()||"0");
|
|
1300
|
+
if (!TaxNumber) return new Error("no TaxNumber for "+data.tenant)
|
|
1301
|
+
|
|
1302
|
+
let Invoice = {
|
|
1303
|
+
TaxNumber,
|
|
1304
|
+
IssueDateTime: new Date(racun.datum),
|
|
1305
|
+
NumberingStructure: "B",
|
|
1306
|
+
InvoiceIdentifier: {
|
|
1307
|
+
BusinessPremiseID: poslovalnica.koda,
|
|
1308
|
+
ElectronicDeviceID: blagajna.nazivZaIzpis,
|
|
1309
|
+
InvoiceNumber: racun.stRacuna.toString(),
|
|
1310
|
+
},
|
|
1311
|
+
InvoiceAmount: round(racun.mpc),
|
|
1312
|
+
PaymentAmount: round(racun.mpc),
|
|
1313
|
+
TaxesPerSeller: [{
|
|
1314
|
+
VAT: racun.davki.map(d => {
|
|
1315
|
+
return {
|
|
1316
|
+
TaxRate: round(d.dst * 100),
|
|
1317
|
+
TaxableAmount: round(d.osnova),
|
|
1318
|
+
TaxAmount: round(d.davek),
|
|
1319
|
+
}
|
|
1320
|
+
})
|
|
1321
|
+
}],
|
|
1322
|
+
OperatorTaxNumber: Number(racun.izdalDs),
|
|
1323
|
+
//ProtectedID: null,
|
|
1324
|
+
SubsequentSubmit: kasneje,
|
|
1325
|
+
// ReferenceInvoice: [{
|
|
1326
|
+
// ReferenceInvoiceIdentifier: {
|
|
1327
|
+
// BusinessPremiseID: "36CF",
|
|
1328
|
+
// ElectronicDeviceID: "BLAG2",
|
|
1329
|
+
// InvoiceNumber: "144"
|
|
1330
|
+
// },
|
|
1331
|
+
// ReferenceInvoiceIssueDateTime: new Date()
|
|
1332
|
+
// }],
|
|
1333
|
+
};
|
|
1334
|
+
if (racun.predhodniRacun) {
|
|
1335
|
+
let s = racun.predhodniRacun.stevilka.split("-");
|
|
1336
|
+
(Invoice as any).ReferenceInvoice = [{
|
|
1337
|
+
ReferenceInvoiceIdentifier: {
|
|
1338
|
+
BusinessPremiseID: s[2],
|
|
1339
|
+
ElectronicDeviceID: s[1],
|
|
1340
|
+
InvoiceNumber: s[0],
|
|
1341
|
+
},
|
|
1342
|
+
ReferenceInvoiceIssueDateTime: racun.predhodniRacun.datum,
|
|
1343
|
+
}];
|
|
1344
|
+
}
|
|
1345
|
+
let DursEnv = veterina.okolje;
|
|
1346
|
+
if (DursEnv !== data.env) throw new Error(`data.env (${data.env}) !== veterina.okolje (${veterina.okolje})`);
|
|
1347
|
+
|
|
1348
|
+
// console.dir(Invoice, {depth:10});
|
|
1349
|
+
|
|
1350
|
+
// davčno potrdi račun
|
|
1351
|
+
let furs: { error?: string, EOR?: string, ZOI?: string, QR?: string } = {};
|
|
1352
|
+
let napaka : string|undefined = ""
|
|
1353
|
+
try {
|
|
1354
|
+
|
|
1355
|
+
timeoutError = "FURS podsistem se ni odzval."
|
|
1356
|
+
|
|
1357
|
+
furs = ((await this.client!.request('durs', {
|
|
1358
|
+
operation: 'register invoice',
|
|
1359
|
+
data: { Invoice, DursEnv, tenant: data.tenant }
|
|
1360
|
+
}, { receiveTimeout: 4000 })) as { Durs: { error?:string } })?.Durs;
|
|
1361
|
+
|
|
1362
|
+
try {
|
|
1363
|
+
console.log("register invoice", data.tenant, Invoice.TaxNumber, `${Invoice?.InvoiceIdentifier?.BusinessPremiseID}-${Invoice?.InvoiceIdentifier?.ElectronicDeviceID}-${Invoice?.InvoiceIdentifier?.InvoiceNumber}`, Invoice.InvoiceAmount, furs.EOR);
|
|
1364
|
+
} catch (err) {
|
|
1365
|
+
console.error(`err logging furs response`);
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
if (furs?.error && furs.error.match(/no such file/g)) {
|
|
1369
|
+
console.warn("no certificate, register it");
|
|
1370
|
+
// register cert
|
|
1371
|
+
timeoutError = "Samodejna registracija digitalnega potrdila furs spodletela."
|
|
1372
|
+
|
|
1373
|
+
await this.registerCert(data.tenant, Invoice.TaxNumber?.toString());
|
|
1374
|
+
// re-submit invoice
|
|
1375
|
+
furs = (
|
|
1376
|
+
(await this.client!.request('durs', {
|
|
1377
|
+
operation: 'register invoice',
|
|
1378
|
+
data: { Invoice, DursEnv, tenant: data.tenant }
|
|
1379
|
+
}, { receiveTimeout: 4000 })) as { Durs: { error?: string } })?.Durs;
|
|
1380
|
+
}
|
|
1381
|
+
if (furs?.error && furs.error.match(/SSL alert number 40/gi)) {
|
|
1382
|
+
console.warn("certifikat potekel");
|
|
1383
|
+
timeoutError = "Je digitalno potrdilo FURS pretečeno?"
|
|
1384
|
+
throw new Error(furs.error)
|
|
1385
|
+
}
|
|
1386
|
+
if (furs?.error && furs.error.match(/no such file/g)) {
|
|
1387
|
+
console.warn("no certificate, register it");
|
|
1388
|
+
// register cert
|
|
1389
|
+
timeoutError = "Samodejna registracija digitalnega potrdila furs spodletela."
|
|
1390
|
+
|
|
1391
|
+
await this.registerCert(data.tenant, Invoice.TaxNumber?.toString());
|
|
1392
|
+
// re-submit invoice
|
|
1393
|
+
furs = ((await this.client!.request('durs', {
|
|
1394
|
+
operation: 'register invoice',
|
|
1395
|
+
data: { Invoice, DursEnv, tenant: data.tenant }
|
|
1396
|
+
}, { receiveTimeout: 4000 })) as { Durs: any }).Durs;
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
} catch (err) {
|
|
1400
|
+
console.error("Err calling durs register.invoice", err)
|
|
1401
|
+
napaka = `${timeoutError} (${err && err.data && err.data.message})`
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
napaka = napaka || furs?.error;
|
|
1405
|
+
if (!napaka && (!furs?.EOR || !furs?.ZOI)) napaka = "furs sistem ni vrnil EOR ali ZOI"
|
|
1406
|
+
let fursObj = napaka ? {
|
|
1407
|
+
zoi: furs?.ZOI,
|
|
1408
|
+
eor: furs?.EOR,
|
|
1409
|
+
qr: furs?.QR,
|
|
1410
|
+
fursError: `furs/račun: ${napaka}`,
|
|
1411
|
+
davcnoSpodletloPrvic: racun.davcnoSpodletloPrvic || new Date(),
|
|
1412
|
+
davcnoSpodletloZadnjic: new Date(),
|
|
1413
|
+
davcnoSpodletloPoskusov: (racun.davcnoSpodletloPoskusov || 0) + 1
|
|
1414
|
+
} : {
|
|
1415
|
+
zoi: furs.ZOI,
|
|
1416
|
+
eor: furs.EOR,
|
|
1417
|
+
qr: furs.QR,
|
|
1418
|
+
davcnoPotrjeno: new Date(),
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
// posodobi račun
|
|
1422
|
+
timeoutError = "Napaka pri vpisu davčno potrjenega računa: Db podsistem se ne odziva več."
|
|
1423
|
+
let updated = await this.dbUpdateById(data.tenant, "racuni", data._id, fursObj);
|
|
1424
|
+
|
|
1425
|
+
try {
|
|
1426
|
+
let dir = path.join('./racuni', new Date().getFullYear().toString(), data.tenant)
|
|
1427
|
+
!fs.existsSync(dir) && makeDir.sync(dir);
|
|
1428
|
+
fs.writeFileSync(path.join(dir, racun.stevilka), serialize.pack(clonedeep({ ...racun, ...updated }), false));
|
|
1429
|
+
} catch (err) {
|
|
1430
|
+
console.log("napaka pri zapisu izdanega računa na disk", err)
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
return updated;
|
|
1434
|
+
|
|
1435
|
+
} catch (err) {
|
|
1436
|
+
|
|
1437
|
+
return {
|
|
1438
|
+
fursError: `furs/račun: ${err.message || err}`,
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
};
|
|
1442
|
+
|
|
1443
|
+
/**
|
|
1444
|
+
* Stornira račun" tako, da kreira nov odprtRacun z negativnimi postavkami.
|
|
1445
|
+
* @param {string} db
|
|
1446
|
+
* @param {string} id
|
|
1447
|
+
*/
|
|
1448
|
+
async storno(db: string, id: string) {
|
|
1449
|
+
// poglej, če morda storno že poteka
|
|
1450
|
+
|
|
1451
|
+
this.mongo!.setDb(db)
|
|
1452
|
+
this.mongo!.setAudit({ tenant: db, app: "klikvet/storno/1" })
|
|
1453
|
+
|
|
1454
|
+
let obstojeci = await this.mongo!.findOne("odprtiRacuni", { "predhodniRacun._id": id })
|
|
1455
|
+
|
|
1456
|
+
// (await client.requestPromise('db', {
|
|
1457
|
+
// operation: 'findOne',
|
|
1458
|
+
// db: string,
|
|
1459
|
+
//: string collection: 'odprtiRacuni',
|
|
1460
|
+
// query: { "predhodniRacun._id": id }
|
|
1461
|
+
// }, null, 2000)).data;
|
|
1462
|
+
|
|
1463
|
+
if (obstojeci) return obstojeci;
|
|
1464
|
+
|
|
1465
|
+
let racun = clonedeep(await this.dbFindById<Racun>(db, "racuni", id));
|
|
1466
|
+
|
|
1467
|
+
if (!racun) throw new Error(`storno: ni računa ${id}`)
|
|
1468
|
+
|
|
1469
|
+
|
|
1470
|
+
// povezi racuna
|
|
1471
|
+
racun.predhodniRacun = {
|
|
1472
|
+
_id: racun._id,
|
|
1473
|
+
stevilka: racun.stevilka,
|
|
1474
|
+
datum: racun.datum
|
|
1475
|
+
};
|
|
1476
|
+
|
|
1477
|
+
// ustvari negativne postavke
|
|
1478
|
+
let flds: (keyof PostavkaRacuna)[] = ['kolicina', 'tpop', 'tnbc', 'tdav', 'tprc', 'tmpc'];
|
|
1479
|
+
racun.postavke.forEach(postavka => {
|
|
1480
|
+
flds.forEach( (f: keyof PostavkaRacuna) => {
|
|
1481
|
+
(postavka[f] as any) = -(postavka[f]||0)
|
|
1482
|
+
})
|
|
1483
|
+
});
|
|
1484
|
+
|
|
1485
|
+
// ustvari negativne vsote
|
|
1486
|
+
let rflds: (keyof Racun)[] = ['mpc', 'prc', 'dav', 'pop', 'nbc'];
|
|
1487
|
+
rflds.forEach(f => {
|
|
1488
|
+
(racun[f] as any) = -(racun[f]||0)
|
|
1489
|
+
});
|
|
1490
|
+
// zbrisi polja, ki jih ne sme biti na novem računu
|
|
1491
|
+
|
|
1492
|
+
// odstrani polja, ki so odvec
|
|
1493
|
+
|
|
1494
|
+
let dflds: (keyof Racun)[] =
|
|
1495
|
+
["zapSt", "stRacuna", "pripis", "izdal", "opomba", "zoi", "eor", "stKopij", "stevilka",
|
|
1496
|
+
"idIzdanegaRacuna", "valuta", "izdalDs", "razknjizen", "statusIzdaje",
|
|
1497
|
+
"odprt", "odprtIz", "naprava_id", "izPredracuna_id", "izPredracuna_st",
|
|
1498
|
+
"izDobavnice_id", "izDobavnice_st", "datum", "zbirnik",
|
|
1499
|
+
"opomba", "fursError", "davcnoPotrjeno", "davcnoSpodletloPrvic",
|
|
1500
|
+
"davcnoSpodletloZadnjic", "davcnoSpodletloPoskusov", "stKopij", "datumiKopij",
|
|
1501
|
+
"navodiloStranki", "kontrola", "vCrpDatum", "vCrpKdo", "vCrp",
|
|
1502
|
+
|
|
1503
|
+
];
|
|
1504
|
+
dflds.forEach(f => {
|
|
1505
|
+
delete racun[f]
|
|
1506
|
+
});
|
|
1507
|
+
|
|
1508
|
+
racun.datum = new Date();
|
|
1509
|
+
// tole nastavi GUI
|
|
1510
|
+
racun.placila = [];
|
|
1511
|
+
racun.davki = [];
|
|
1512
|
+
(racun._id as any) = undefined;
|
|
1513
|
+
|
|
1514
|
+
this.mongo!.setDb(db)
|
|
1515
|
+
this.mongo!.setAudit({ tenant: db, app: "klikvet/storno/2" })
|
|
1516
|
+
|
|
1517
|
+
let odprtiRacun = await this.mongo!.insert("odprtiRacuni", racun)
|
|
1518
|
+
|
|
1519
|
+
// (await client.requestPromise('db', {
|
|
1520
|
+
// operation: 'insert',
|
|
1521
|
+
// db: string,
|
|
1522
|
+
//: string collection: "odprtiRacuni",
|
|
1523
|
+
// insert: racun,
|
|
1524
|
+
// }, null, 2000)).data;
|
|
1525
|
+
|
|
1526
|
+
return odprtiRacun;
|
|
1527
|
+
};
|
|
1528
|
+
|
|
1529
|
+
|
|
1530
|
+
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
|
|
1534
|
+
|