mediserv 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/mediserv/api/client.rb +33 -0
- data/lib/mediserv/api/encoder.rb +66 -0
- data/lib/mediserv/api/error.rb +13 -0
- data/lib/mediserv/api/format.rb +19 -0
- data/lib/mediserv/api/storage.rb +7 -0
- data/lib/mediserv/api/types.rb +378 -0
- data/lib/mediserv/api.rb +6 -0
- data/lib/mediserv.rb +3 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5204dd01be4fb9c2d2094f8d905239744bfbc3994a37af6a03ba9498ae26749c
|
4
|
+
data.tar.gz: ec11e152aef07451253f7833697957d1a314e5668c0a5c00de8bc5432781dd84
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a043815bb4d3162fb02476447f4f5651d3f6a567f84051a772932db0f32f181b19e8508c56af1c34611e96eac09c00296bb35d05945553cca149aae67753fd14
|
7
|
+
data.tar.gz: 0cdde28234817de97f0dd3425feba8c868d07766f4e7faa68c7e1c5b1b8ed57fc994bd1c605f2dbb110ed04982645b2a36fc0445f943459dd96f408f8996f196
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module MediServ::API
|
2
|
+
require 'toml-rb'
|
3
|
+
|
4
|
+
require_relative "encoder"
|
5
|
+
require_relative "error"
|
6
|
+
require_relative "types"
|
7
|
+
|
8
|
+
class Client
|
9
|
+
# * *Args* :
|
10
|
+
def initialize(clientId, storage)
|
11
|
+
@storage = storage
|
12
|
+
@encoder = MediServ::API::Encoder.new
|
13
|
+
@default_header = {
|
14
|
+
programm: 'MediServ gem',
|
15
|
+
programm_version: '0.0.1', # TODO: Load from gemspec
|
16
|
+
version: 'v2',
|
17
|
+
kundennummer: clientId,
|
18
|
+
stapelnummer: 0,
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def batch(id, invoices, created_at: DateTime.now)
|
23
|
+
b = MediServ::API::Batch.new({
|
24
|
+
allgemein: @default_header.merge({
|
25
|
+
stapelnummer: id,
|
26
|
+
}),
|
27
|
+
rechnungen: invoices,
|
28
|
+
created_at: created_at,
|
29
|
+
})
|
30
|
+
@storage.put(id, @encoder.encode(b.to_h))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module MediServ::API
|
2
|
+
require_relative "format"
|
3
|
+
|
4
|
+
class Encoder
|
5
|
+
def encode(h)
|
6
|
+
build_tree(Node.new, h).to_ini
|
7
|
+
end
|
8
|
+
|
9
|
+
def build_tree(node, h)
|
10
|
+
h.each do |k, v|
|
11
|
+
case v
|
12
|
+
when Hash
|
13
|
+
child = Node.new(name: [node.name, k].compact.join('.'))
|
14
|
+
node.children << child
|
15
|
+
build_tree(child, v)
|
16
|
+
else
|
17
|
+
node.attributes[k] = v
|
18
|
+
end
|
19
|
+
end
|
20
|
+
node
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Node
|
25
|
+
include Format
|
26
|
+
|
27
|
+
attr_accessor :name, :attributes, :children
|
28
|
+
|
29
|
+
def initialize(name: nil, attributes: {}, children: [])
|
30
|
+
@name = name
|
31
|
+
@attributes = attributes
|
32
|
+
@children = children
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_ini(io = StringIO.new)
|
36
|
+
if name
|
37
|
+
io << '['
|
38
|
+
io << name
|
39
|
+
io << ']'
|
40
|
+
io << "\n"
|
41
|
+
end
|
42
|
+
attributes.each do |k, v|
|
43
|
+
next unless k && v
|
44
|
+
io << k.to_s
|
45
|
+
io << '='
|
46
|
+
|
47
|
+
v = case v
|
48
|
+
when Float
|
49
|
+
io << fmt_amount(v)
|
50
|
+
when String
|
51
|
+
io << '"'
|
52
|
+
io << v.tr("\n", '')
|
53
|
+
io << '"'
|
54
|
+
else
|
55
|
+
io << v
|
56
|
+
end
|
57
|
+
io << "\n"
|
58
|
+
end
|
59
|
+
children.each do |c|
|
60
|
+
io << "\n"
|
61
|
+
c.to_ini(io)
|
62
|
+
end
|
63
|
+
io.string.encode('windows-1252')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module MediServ::API
|
2
|
+
class MissingError < StandardError
|
3
|
+
end
|
4
|
+
class BadRequestError < StandardError
|
5
|
+
end
|
6
|
+
class PermissionError < StandardError
|
7
|
+
end
|
8
|
+
class UnauthenticatedError < StandardError
|
9
|
+
end
|
10
|
+
class ConflictError < StandardError
|
11
|
+
# TODO: Add resource
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module MediServ::API
|
2
|
+
module Format
|
3
|
+
def fmt_date(d)
|
4
|
+
d ? d.strftime('%d.%m.%Y') : ''
|
5
|
+
end
|
6
|
+
|
7
|
+
def fmt_time(t)
|
8
|
+
t ? t.strftime('%H:%M') : ''
|
9
|
+
end
|
10
|
+
|
11
|
+
def fmt_amount(n)
|
12
|
+
n ? sprintf('%0.2f', n) : '0.00'
|
13
|
+
end
|
14
|
+
|
15
|
+
def fmt_string(s, max: nil)
|
16
|
+
max ? s[0..max] : s
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,378 @@
|
|
1
|
+
module MediServ::API
|
2
|
+
require 'dry-types'
|
3
|
+
require 'dry-struct'
|
4
|
+
|
5
|
+
require_relative "format"
|
6
|
+
|
7
|
+
module Types
|
8
|
+
include Dry.Types()
|
9
|
+
end
|
10
|
+
|
11
|
+
class Struct < Dry::Struct
|
12
|
+
include Format
|
13
|
+
end
|
14
|
+
|
15
|
+
class Recipient < Struct
|
16
|
+
# Nummer des Empfängers
|
17
|
+
attribute :nummer, Types::Strict::Integer
|
18
|
+
# Art des Empfängers (Garant oder Gesetz_Vertreter)
|
19
|
+
attribute :art, Types::Strict::String
|
20
|
+
# Anrede in der Sprache der Rechnung
|
21
|
+
attribute :anrede, Types::Strict::String
|
22
|
+
# Titel in der Sprache der Rechnung
|
23
|
+
attribute :titel, Types::Strict::String
|
24
|
+
# Name
|
25
|
+
attribute :name, Types::Strict::String
|
26
|
+
# Vorname
|
27
|
+
attribute :vorname, Types::Strict::String
|
28
|
+
# Strasse mit Nummer
|
29
|
+
attribute :strasse, Types::Strict::String.optional.default(nil)
|
30
|
+
# Land (CH / D / F / ...)
|
31
|
+
attribute :land, Types::Strict::String
|
32
|
+
# Postleitzahl
|
33
|
+
attribute :plz, Types::Strict::String
|
34
|
+
# Ort
|
35
|
+
attribute :ort, Types::Strict::String
|
36
|
+
# Geburtsdatum
|
37
|
+
attribute :geburtsdatum, Types::Strict::Date
|
38
|
+
end
|
39
|
+
|
40
|
+
class Patient < Struct
|
41
|
+
# Patientennummer
|
42
|
+
attribute :nummer, Types::Strict::Integer
|
43
|
+
# Anrede in der Sprache der Rechnung
|
44
|
+
attribute :anrede, Types::Strict::String
|
45
|
+
# Titel in der Sprache der Rechnung
|
46
|
+
attribute :titel, Types::Strict::String
|
47
|
+
# Name
|
48
|
+
attribute :name, Types::Strict::String
|
49
|
+
# Vorname
|
50
|
+
attribute :vorname, Types::Strict::String
|
51
|
+
# Strasse mit Nummer
|
52
|
+
attribute :strasse, Types::Strict::String.optional.default(nil)
|
53
|
+
# Zusatzadresse
|
54
|
+
attribute :zusatz, Types::Strict::String.optional.default(nil)
|
55
|
+
# Land (CH / D / F / ...)
|
56
|
+
attribute :land, Types::Strict::String
|
57
|
+
# Postleitzahl
|
58
|
+
attribute :plz, Types::Strict::String
|
59
|
+
# Ort
|
60
|
+
attribute :ort, Types::Strict::String
|
61
|
+
# Geburtsdatum
|
62
|
+
attribute :geburtsdatum, Types::Strict::Date
|
63
|
+
end
|
64
|
+
|
65
|
+
class InvoiceItem < Struct
|
66
|
+
Art = Types::Integer.enum(
|
67
|
+
0 => 'leistung',
|
68
|
+
1 => 'medikament',
|
69
|
+
2 => 'labo',
|
70
|
+
3 => 'diverse',
|
71
|
+
)
|
72
|
+
|
73
|
+
# Datum der Leistung
|
74
|
+
attribute :datum, Types::Strict::Date
|
75
|
+
# Anzahl der Leistung
|
76
|
+
attribute :anzahl, Types::Strict::Integer
|
77
|
+
# Zahnnummer der Leistung, Freie Eingabe des Zahnarztes.
|
78
|
+
attribute :zahnnummer, Types::Strict::String.optional.default(nil)
|
79
|
+
# Art der Leistung (0=Leistung, 1=Medikament, 2=Labo, 3=Diverse)
|
80
|
+
attribute :art, Art
|
81
|
+
# Nummer der Leistung
|
82
|
+
attribute :nummer, Types::Strict::String.optional.default(nil)
|
83
|
+
# Bezeichnung in der Sprache der Rechnung
|
84
|
+
attribute :bezeichnung, Types::Strict::String
|
85
|
+
# Ansatz der Leistung
|
86
|
+
attribute :ansatz, Types::Strict::Float.optional.default(nil)
|
87
|
+
# Punkte der Leistung
|
88
|
+
attribute :punkte, Types::Strict::Float.optional.default(nil)
|
89
|
+
# Auf der Leistung ist ein Rabatt gewährt (0 = ohne Rabatt; 1 = mit Rabatt)
|
90
|
+
attribute :rabatt, Types::Strict::Bool.default(false)
|
91
|
+
# Betrag
|
92
|
+
attribute :betrag, Types::Strict::Float
|
93
|
+
|
94
|
+
# Bruttobetrag (Anzahl * Betrag)
|
95
|
+
def total
|
96
|
+
anzahl * betrag
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class Invoice < Struct
|
101
|
+
BehandlungStatus = Types::Integer.enum(
|
102
|
+
0 => 'laufend',
|
103
|
+
1 => 'abgeschlossen',
|
104
|
+
)
|
105
|
+
BehandlungTyp = Types::String.enum(
|
106
|
+
'PP',
|
107
|
+
'VS',
|
108
|
+
'IV',
|
109
|
+
'KK',
|
110
|
+
)
|
111
|
+
Sprache = Types::Integer.enum(
|
112
|
+
1 => 'DE',
|
113
|
+
2 => 'FR',
|
114
|
+
3 => 'IT',
|
115
|
+
4 => 'EN',
|
116
|
+
)
|
117
|
+
|
118
|
+
# Rechnungsnummer aus dem Programm
|
119
|
+
attribute :nummer, Types::Strict::Integer
|
120
|
+
# Datum der Rechnung (kann auch vordatiert sein)
|
121
|
+
attribute :datum, Types::Strict::Date
|
122
|
+
# Behandlungsbeginn
|
123
|
+
attribute :behandlungsbeginn, Types::Strict::Date
|
124
|
+
# Behandlungsende
|
125
|
+
attribute :behandlungsende, Types::Strict::Date
|
126
|
+
# 0=Behandlung laufend, 1=Behandlung abgeschlossen
|
127
|
+
attribute :behandlungstatus, BehandlungStatus
|
128
|
+
# Typ der Behandlung (PP / VS / IV / KK)
|
129
|
+
attribute :behandlungstyp, BehandlungTyp
|
130
|
+
# Sprache der Rechnung (1=deu, 2=franz. 3=ital. 4=engl.)
|
131
|
+
attribute :sprache, Sprache
|
132
|
+
# Rechnungsüberschrift
|
133
|
+
attribute :rech_titel, Types::Strict::String.optional.default(nil)
|
134
|
+
# Rechnungstext pro Zeile ein Eintrag
|
135
|
+
attribute :rech_text, Types::Strict::String.optional.default(nil)
|
136
|
+
# Versicherungsnummer
|
137
|
+
attribute :versicherungsnummer, Types::Strict::String.optional.default(nil)
|
138
|
+
# Rabatt in Prozent auf den markierten Leistungen
|
139
|
+
attribute :rabatt, Types::Strict::Integer.optional.default(nil)
|
140
|
+
# Datum der Verfügung
|
141
|
+
attribute :verfugungs_datum, Types::Strict::Date.optional.default(nil)
|
142
|
+
# Nummer der Verfügung
|
143
|
+
attribute :verfugungs_nummer, Types::Strict::Integer.optional.default(nil)
|
144
|
+
# Anhang
|
145
|
+
attribute :anhange, Types::Strict::Array.of(Types::Strict::String).default([].freeze)
|
146
|
+
|
147
|
+
# Rechnungsbetrag (ohne Vorauszahlungen)
|
148
|
+
attribute :total_rabatt, Types::Strict::Float
|
149
|
+
# Total aller Vorauszahlungen dieser Rechnung
|
150
|
+
attribute :total_vz, Types::Strict::Float
|
151
|
+
|
152
|
+
attribute :empfanger, Recipient.optional.default(nil)
|
153
|
+
attribute :patient, Patient
|
154
|
+
attribute :leistungen, Types::Strict::Array.of(InvoiceItem)
|
155
|
+
|
156
|
+
def total_punkte
|
157
|
+
leistungen.select{|l| l.punkte != nil }.map(&:punkte).reduce(0.0, :+)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Total von allen Leistungen
|
161
|
+
def total_leis
|
162
|
+
leistungen.select{|l| l.art == 0 }.map(&:total).reduce(0.0, :+)
|
163
|
+
end
|
164
|
+
|
165
|
+
# Rechnungsbetrag (ohne Vorauszahlungen)
|
166
|
+
def total_med
|
167
|
+
leistungen.select{|l| l.art == 1 }.map(&:total).reduce(0.0, :+)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Rechnungsbetrag (ohne Vorauszahlungen)
|
171
|
+
def total_labor
|
172
|
+
leistungen.select{|l| l.art == 2 }.map(&:total).reduce(0.0, :+)
|
173
|
+
end
|
174
|
+
|
175
|
+
# Rechnungsbetrag (ohne Vorauszahlungen)
|
176
|
+
def total_diverse
|
177
|
+
leistungen.select{|l| l.art == 3 }.map(&:total).reduce(0.0, :+)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Total minus Vorauszahlungen dieser Rechnung
|
181
|
+
def total_netto
|
182
|
+
total_leis + total_med + total_labor + total_diverse + total_rabatt
|
183
|
+
end
|
184
|
+
|
185
|
+
# Rechnungsbetrag (ohne Vorauszahlungen)
|
186
|
+
def rechnungsbetrag
|
187
|
+
total_netto + total_vz
|
188
|
+
end
|
189
|
+
|
190
|
+
def to_h
|
191
|
+
h = {
|
192
|
+
RechNr: nummer,
|
193
|
+
RechDat: datum.strftime('%d.%m.%Y'),
|
194
|
+
BehBeginn: behandlungsbeginn.strftime('%d.%m.%Y'),
|
195
|
+
BehEnde: behandlungsende.strftime('%d.%m.%Y'),
|
196
|
+
BehStatus: behandlungstatus,
|
197
|
+
BehTyp: behandlungstyp,
|
198
|
+
RechBetrag: rechnungsbetrag,
|
199
|
+
TotalLeis: total_leis,
|
200
|
+
TotalMed: total_med,
|
201
|
+
TotalLabor: total_labor,
|
202
|
+
TotalDiverse: total_diverse,
|
203
|
+
TotalRabatt: total_rabatt,
|
204
|
+
TotalVZ: total_vz,
|
205
|
+
TotalNetto: total_netto,
|
206
|
+
Sprache: sprache,
|
207
|
+
PatNr: patient.nummer,
|
208
|
+
PatAnrede: fmt_string(patient.anrede, max: 4),
|
209
|
+
PatTitel: fmt_string(patient.titel, max: 20),
|
210
|
+
PatName: fmt_string(patient.name, max: 40),
|
211
|
+
PatVorname: fmt_string(patient.vorname, max: 40),
|
212
|
+
PatStrasse: fmt_string(patient.strasse, max: 30),
|
213
|
+
PatZusatz: fmt_string(patient.zusatz, max: 20),
|
214
|
+
PatLand: fmt_string(patient.land, max: 3),
|
215
|
+
PatPLZ: fmt_string(patient.plz, max: 10),
|
216
|
+
PatOrt: fmt_string(patient.ort, max: 40),
|
217
|
+
PatGebDatum: fmt_date(patient.geburtsdatum),
|
218
|
+
}
|
219
|
+
h[:RechTitel] = rech_titel[0..180] unless rech_titel.nil?
|
220
|
+
h[:VersNr] = versicherungsnummer unless versicherungsnummer.nil?
|
221
|
+
h[:Rabatt] = rabatt unless rabatt.nil?
|
222
|
+
h[:VerfügungsDat] = verfugungs_datum unless verfugungs_datum.nil?
|
223
|
+
h[:VerfügungsNr] = verfugungs_nummer unless verfugungs_nummer.nil?
|
224
|
+
if empfanger
|
225
|
+
h[:EmpfNr] = empfanger.nummer
|
226
|
+
h[:EmpfArt] = fmt_string(empfanger.art, max: 20)
|
227
|
+
h[:EmpfAnrede] = fmt_string(empfanger.anrede, max: 4)
|
228
|
+
h[:EmpfTitel] = fmt_string(empfanger.titel, max: 20)
|
229
|
+
h[:EmpfName] = fmt_string(empfanger.name, max: 40)
|
230
|
+
h[:EmpfVorname] = fmt_string(empfanger.vorname, max: 40)
|
231
|
+
h[:EmpfStrasse] = fmt_string(empfanger.strasse, max: 20)
|
232
|
+
h[:EmpfLand] = fmt_string(empfanger.land, max: 3)
|
233
|
+
h[:EmpfPLZ] = fmt_string(empfanger.plz, max: 10)
|
234
|
+
h[:EmpfOrt] = fmt_string(empfanger.ort, max: 40)
|
235
|
+
h[:EmpfGebDatum] = fmt_date(empfanger.geburtsdatum)
|
236
|
+
end
|
237
|
+
anhange.each.with_index(1) do |a, i|
|
238
|
+
# Path to attachment file
|
239
|
+
h["Anhang#{i}"] = a
|
240
|
+
end
|
241
|
+
rech_text.scan(/.{1,180}/).each.with_index(1) do |s, i|
|
242
|
+
# A line will go up to 180 characters, but could be shorter in case of a
|
243
|
+
# new line or simply a short line.
|
244
|
+
h["RechText[#{i}]"] = s
|
245
|
+
end unless rech_text.nil?
|
246
|
+
leistungen.each.with_index(1) do |l, i|
|
247
|
+
# Total der Punkt von Ansatz
|
248
|
+
# h["TotalPkt[#{i}]"] = l.punkte || 0.0
|
249
|
+
# Ansatz für Punkte
|
250
|
+
# h["TotalAnsatz[#{i}]"] = l.ansatz || 0.0
|
251
|
+
|
252
|
+
h["LeisDatum[#{i}]"] = fmt_date(l.datum)
|
253
|
+
h["LeisAnz[#{i}]"] = fmt_amount(l.anzahl)
|
254
|
+
h["LeisZahnNr[#{i}]"] = l.zahnnummer
|
255
|
+
h["LeisArt[#{i}]"] = l.art
|
256
|
+
h["LeisPosNr[#{i}]"] = l.nummer
|
257
|
+
h["LeisBez[#{i}]"] = l.bezeichnung
|
258
|
+
h["LeisAnsatz[#{i}]"] = l.ansatz
|
259
|
+
h["LeisPkt[#{i}]"] = l.punkte
|
260
|
+
h["LeisRabatt[#{i}]"] = l.rabatt ? 1 : 0
|
261
|
+
h["LeisBetrag[#{i}]"] = l.betrag
|
262
|
+
h["LeisTotal[#{i}]"] = l.total
|
263
|
+
end
|
264
|
+
h
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
# Folgende Einträge sind 1x pro Datei vorhanden
|
269
|
+
class Header < Struct
|
270
|
+
# Programmname
|
271
|
+
attribute :programm, Types::Strict::String
|
272
|
+
# Programm Version
|
273
|
+
attribute :programm_version, Types::Strict::String
|
274
|
+
# Schnittstellenversion
|
275
|
+
attribute :version, Types::Strict::String
|
276
|
+
# Eindeutige Kundennummer bei Mediserv
|
277
|
+
attribute :kundennummer, Types::Strict::Integer
|
278
|
+
# Die Stapelnummer ist eine fortlaufende Nummer. Für jede Datei eine neue Nummer
|
279
|
+
attribute :stapelnummer, Types::Strict::Integer
|
280
|
+
|
281
|
+
def to_h
|
282
|
+
{
|
283
|
+
Programm: programm,
|
284
|
+
ProgrammVersion: programm_version,
|
285
|
+
Version: version,
|
286
|
+
KuNr: kundennummer,
|
287
|
+
StapelNr: stapelnummer,
|
288
|
+
}
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
class Batch < Struct
|
293
|
+
attribute :allgemein, MediServ::API::Header
|
294
|
+
attribute :rechnungen, Types::Strict::Array.of(MediServ::API::Invoice)
|
295
|
+
attribute :created_at, Types::Strict::DateTime
|
296
|
+
|
297
|
+
# Anzahl Rechnungen
|
298
|
+
def anzahl_rechnungen
|
299
|
+
rechnungen.length
|
300
|
+
end
|
301
|
+
|
302
|
+
# Gesamtsumme Taxpunkte
|
303
|
+
def total_pkt
|
304
|
+
rechnungen.map(&:total_punkte).reduce(0.0, :+)
|
305
|
+
end
|
306
|
+
|
307
|
+
# Gesamtsumme aller Leistungen
|
308
|
+
def total_leis
|
309
|
+
rechnungen.map(&:total_leis).reduce(0.0, :+)
|
310
|
+
end
|
311
|
+
|
312
|
+
# Gesamtsumme aller Medikamente
|
313
|
+
def total_med
|
314
|
+
rechnungen.map(&:total_med).reduce(0.0, :+)
|
315
|
+
end
|
316
|
+
|
317
|
+
# Gesamtsumme aller Laborkosten
|
318
|
+
def total_labor
|
319
|
+
rechnungen.map(&:total_labor).reduce(0.0, :+)
|
320
|
+
end
|
321
|
+
|
322
|
+
# Gesamtsumme Diverse Positionen
|
323
|
+
def total_diverse
|
324
|
+
rechnungen.map(&:total_diverse).reduce(0.0, :+)
|
325
|
+
end
|
326
|
+
|
327
|
+
# Gesamtsumme Rabatte
|
328
|
+
def total_rabatt
|
329
|
+
rechnungen.map(&:total_rabatt).reduce(0.0, :+)
|
330
|
+
end
|
331
|
+
|
332
|
+
# Gesamtsumme der abgezogenen Vorauszahlungen
|
333
|
+
def total_vz
|
334
|
+
rechnungen.map(&:total_vz).reduce(0.0, :+)
|
335
|
+
end
|
336
|
+
|
337
|
+
# Gesamtsumme Total (ist auch die Summe von TotalLeis + TotalMed + TotalLabor + TotalDiverse + TotalRabatt)
|
338
|
+
def total
|
339
|
+
total_leis + total_med + total_labor + total_diverse + total_rabatt
|
340
|
+
end
|
341
|
+
|
342
|
+
# Nettosumme (Total – Vorauszahlung)
|
343
|
+
def total_netto
|
344
|
+
total - total_vz
|
345
|
+
end
|
346
|
+
|
347
|
+
def to_h
|
348
|
+
h = {
|
349
|
+
Allgemein: allgemein.to_h.merge({
|
350
|
+
Total: total,
|
351
|
+
TotalPkt: total_pkt,
|
352
|
+
TotalLeis: total_leis,
|
353
|
+
TotalMed: total_med,
|
354
|
+
TotalLabor: total_labor,
|
355
|
+
TotalDiverse: total_diverse,
|
356
|
+
TotalRabatt: total_rabatt,
|
357
|
+
TotalVz: total_vz,
|
358
|
+
TotalNetto: total_netto,
|
359
|
+
Datum: fmt_date(created_at),
|
360
|
+
Zeit: fmt_time(created_at),
|
361
|
+
AnzRech: anzahl_rechnungen,
|
362
|
+
}),
|
363
|
+
}
|
364
|
+
rechnungen.each.with_index(1) do |r,i|
|
365
|
+
h["R#{i}"] = r.to_h
|
366
|
+
end
|
367
|
+
stringify_keys h
|
368
|
+
end
|
369
|
+
|
370
|
+
def stringify_keys(h)
|
371
|
+
h.reduce({}) do |h, (k,v)|
|
372
|
+
v = stringify_keys(v) if v.kind_of?(Hash)
|
373
|
+
h.merge({k.to_s => v})
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
end
|
data/lib/mediserv/api.rb
ADDED
data/lib/mediserv.rb
ADDED
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mediserv
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Denteo AG
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-10-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dry-types
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.5.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.5.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dry-struct
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.4.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.4.0
|
41
|
+
description: Ruby client interacting with MediServ
|
42
|
+
email: simon@denteo.ch
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- lib/mediserv.rb
|
48
|
+
- lib/mediserv/api.rb
|
49
|
+
- lib/mediserv/api/client.rb
|
50
|
+
- lib/mediserv/api/encoder.rb
|
51
|
+
- lib/mediserv/api/error.rb
|
52
|
+
- lib/mediserv/api/format.rb
|
53
|
+
- lib/mediserv/api/storage.rb
|
54
|
+
- lib/mediserv/api/types.rb
|
55
|
+
homepage: https://rubygems.org/gems/mediserv
|
56
|
+
licenses:
|
57
|
+
- MIT
|
58
|
+
metadata: {}
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubygems_version: 3.1.2
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: Ruby client interacting with MediServ
|
78
|
+
test_files: []
|