Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(#241): Fix and test for exfactory and public prices #243

Merged
merged 1 commit into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 70 additions & 24 deletions src/plugin/bsv_xml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ class PreparationsListener < Listener
:updated_sl_entries, :created_limitation_texts,
:deleted_limitation_texts, :updated_limitation_texts,
:duplicate_iksnrs
attr_accessor :test_sequences if defined?(Minitest) #something we should avoid!!

def initialize *args
super
@known_packages = {}
Expand Down Expand Up @@ -238,7 +240,7 @@ def add_bag_composition_to_sequence sequence, substances
[data[:lt], ODDB::Dose.new(data[:dose], data[:unit])]
end

composition_pointer = sequence.pointer + :bag_composition
composition_pointer = sequence.pointer + :bag_composition
comp = if (sequence.bag_compositions.nil? || sequence.bag_compositions.empty?) then @app.create composition_pointer else sequence.bag_compositions[0] end
if !sequence.bag_compositions.empty?
first_composition = sequence.bag_compositions[0]
Expand Down Expand Up @@ -266,7 +268,13 @@ def load_ikskey pcode
end
def tag_start name, attrs
case name
when 'IntegrationDate'
@parsing_prices = false
when 'Pack'
@parsing_prices = true
@price_change_code = nil
@price_amount = nil
@valid_from = nil
@ikscd = nil
@data = @pac_data.dup
@report = @report_data.dup.update(@data).update(@reg_data).update(@seq_data)
Expand All @@ -292,11 +300,23 @@ def tag_start name, attrs
@deferred_packages = []
@substances = []
@sequence = nil
when /(.+)Price/u
@price_type = $~[1].downcase.to_sym
@price = Util::Money.new(0, @price_type, 'CH')
@price.origin = @origin
@price.authority = :sl
when 'LastPriceChange' # just ignore it
when 'ExFactoryPrice'
@valid_from = nil
@price_change_code = nil
@price = nil
@price_exfactory = Util::Money.new(0, :exfactory, 'CH')
@price_exfactory.origin = @origin
@price_exfactory.authority = :sl
@price_type = :exfactory
when 'PublicPrice'
@valid_from = nil
@price_change_code = nil
@price = nil
@price_type = :public
@price_public = Util::Money.new(0, :public, 'CH')
@price_public.origin = @origin
@price_public.authority = :sl
when 'Limitation'
@in_limitation = true
when 'ItCode'
Expand All @@ -317,6 +337,8 @@ def tag_end name
already_disabled = GC.disable # to prevent method `method_missing' called on terminated object
@seq_data ||= {}
case name
when 'Prices'
@parsing_prices = false
when 'Pack'
fix_flags_with_rss_logic
if @pack.nil? && @completed_registrations[@iksnr] && !@out_of_trade
Expand All @@ -331,22 +353,38 @@ def tag_end name
elsif @pack && !@duplicate_iksnr
## don't take the Swissmedic-Category unless it's missing in the DB
@data.delete :ikscat if @pack.ikscat
if @pack.price_exfactory.nil? || !@price_exfactory.amount.to_s.eql?(@pack.price_exfactory.amount.to_s) || !@price_change_code.eql?(@pack.price_exfactory.mutation_code)
LogFile.debug "tag_end_set price_exfactory #{@price_exfactory} for @pack.price_exfactor '#{@pack.price_exfactory}' #{@pack.price_exfactory&.mutation_code} now #{@price_change_code}"
@pack.price_exfactory = @price_exfactory
@pack.price_exfactory.mutation_code = @price_exfactory.mutation_code
@pack.price_exfactory.valid_from = @price_exfactory.valid_from
@data.store :price_exfactory, @price_exfactory
end if @price_exfactory
if @pack.price_public.nil? || !@price_public.amount.to_s.eql?(@pack.price_public.amount.to_s) || !@price_change_code.eql?(@pack.price_public.mutation_code)
LogFile.debug "tag_end price_public #{@price_public} for @pack.price_exfactor '#{@pack.price_public}' #{@pack.price_public&.mutation_code} now #{@price_change_code}"
@pack.price_public = @price_public
@pack.price_public.valid_from = @price_public.valid_from
@pack.price_public.mutation_code = @price_public.mutation_code
@data.store :price_public, @price_public
end if @price_public
@app.update @pack.pointer, @data, :bag
@sl_entries.store @pack.pointer, @sl_data
@lim_texts.store @pack.pointer, @lim_data
end
if [email protected]?
@sequence = @pack.sequence
@pack.odba_store
end
@pack, @sl_data, @lim_data, @out_of_trade, @ikscd, @data, @size, @price, @price_type = nil
@pack, @sl_data, @lim_data, @out_of_trade, @ikscd, @data, @size, @price_public, @price_exfactory = nil
when 'Preparation'
seq = @sequence || identify_sequence(@registration, @name, @substances)
@test_sequences ||= []
@test_sequences << seq if defined?(Minitest) #something we should avoid!!
if !@deferred_packages.empty? && seq
@deferred_packages.each do |info|
ptr = seq.pointer + [:package, info[:ikscd]]
@app.update seq.pointer, info[:sequence]
unless seq.package(info[:ikscd])
LogFile.debug "create_package export #{seq.export_flag} ptr #{ptr}"
seq.create_package(info[:ikscd])
end
@app.update ptr.creator, info[:package]
Expand All @@ -367,7 +405,6 @@ def tag_end name
@known_packages.delete pac_ptr
next if pac.nil?
unless pac.is_a?(ODDB::Package)
LogFile.debug "Skipping pac_ptr #{pac_ptr} sl_data is_a? #{sl_data.class} pac is_a? #{pac.class}"
else
pointer = pac_ptr + :sl_entry
if sl_data.empty?
Expand All @@ -382,14 +419,12 @@ def tag_end name
@created_sl_entries += 1
end
if (lim_data = @lim_texts[pac_ptr]) && !lim_data.empty?
LogFile.debug("limitation store sl_data for #{pac_ptr} #{@iksnr} #{@name[:de]} lim: #{lim_data[:de].to_s[0..70]}")
sl_data.store :limitation, true
end
@app.update pointer.creator, sl_data, :bag
end
end
rescue ODBA::OdbaError, ODDB::Persistence::InvalidPathError, NoMethodError => error
LogFile.debug "Skipping #{error} pac_ptr #{pac_ptr} sl_data is_a? #{sl_data.class}"
# skip
end
end
Expand All @@ -398,7 +433,6 @@ def tag_end name
pac = pac_ptr.resolve @app
next if pac.nil?
unless pac.is_a?(ODDB::Package)
LogFile.debug "Skipping pac_ptr #{pac_ptr} lim_data is_a? #{lim_data.class} pac is_a? #{pac.class}"
else
sl_entry = pac.sl_entry
next if sl_entry.nil?
Expand All @@ -408,7 +442,6 @@ def tag_end name
# 2021.03.16 Niklaus has no idea, why I have to freeze it here
# but without a freeze the @app.update fails miserably
if lim_data.nil? || lim_data.empty?
LogFile.debug("limitation delete txt_ptr for #{txt_ptr} limitation_text #{sl_entry.limitation_text.class}")
if sl_entry.limitation_text
@deleted_limitation_texts += 1
@app.delete txt_ptr
Expand All @@ -429,18 +462,15 @@ def tag_end name
end
rescue ODDB::Persistence::UninitializedPathError,
ODDB::Persistence::InvalidPathError => error
LogFile.debug "Skipping delete txt_ptr '#{error}' txt_ptr #{txt_ptr}"
# skip
end
txt_ptr = sl_ptr + :limitation_text
# 2021.03.16 Niklaus has no idea, why I have to redefine it here
# but without redefining the @app.update fails miserably
LogFile.debug("limitation update txt_ptr for #{txt_ptr} lim_data #{lim_data.class}")
@app.update txt_ptr.creator, lim_data, :bag
end
end
rescue TypeError, ODBA::OdbaError, ODDB::Persistence::InvalidPathError, NoMethodError => error
LogFile.debug "Skipping '#{error}' pac_ptr #{pac_ptr}"
# skip
end
end
Expand Down Expand Up @@ -513,16 +543,32 @@ def tag_end name
@data.store :narcotic, @text == 'Y'
when 'BagDossierNo'
@sl_data.store :bsv_dossier, @text if @sl_data
when /(.+)Price/u
if @price > 0
@data.store :"price_#{@price_type}", @price
when 'LastPriceChange' # just ignore
when 'Prices'
@parsing_prices = true
when 'ExFactoryPrice'
@price_exfactory = Util::Money.new(@price_amount, @price_type, 'CH')
@price_exfactory.origin = @origin
@price_exfactory.authority = :sl
@price_exfactory.mutation_code = @price_change_code
@price_exfactory.valid_from = @valid_from
if @price_exfactory > 0
@data.store :"price_#{@price_type}", @price_exfactory
end
when 'PublicPrice'
@price_public = Util::Money.new(@price_amount, @price_type, 'CH')
@price_public.origin = @origin
@price_public.authority = :sl
@price_public.mutation_code = @price_change_code
@price_public.valid_from = @valid_from
if @price_public > 0
@data.store :"price_#{@price_type}", @price_public
end
when 'Price'
@price.amount = @text.to_f if @price
@price_amount = @text
when 'ValidFromDate'
if @price
@price.valid_from = time(@text)
elsif @sl_entries
@valid_from = time(@text) # for prices
if @sl_entries
@sl_entries.each_value do |sl_data|
sl_data.store :valid_from, date(@text)
end
Expand Down Expand Up @@ -572,7 +618,7 @@ def tag_end name
when 'IntegrationDate'
@sl_data.store :introduction_date, date(@text) if @sl_data
when 'PriceChangeTypeCode'
@price.mutation_code = @text
@price_change_code = @text
when 'Limitation'
@in_limitation = false
when 'LimitationType'
Expand Down
144 changes: 144 additions & 0 deletions test/data/xml/Amlodipin_MwSt.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Preparations ReleaseDate="01.02.2024">
<Preparation ProductCommercial="28739">
<NameDe>Amlodipin Valsartan Sandoz</NameDe>
<NameFr>Amlodipine Valsartan Sandoz</NameFr>
<NameIt>Amlodipin Valsartan Sandoz</NameIt>
<DescriptionDe>Filmtabl 5/80</DescriptionDe>
<DescriptionFr>cpr pell 5/80 </DescriptionFr>
<DescriptionIt>Filmtabl 5/80</DescriptionIt>
<AtcCode>C09DB01</AtcCode>
<SwissmedicNo5>66015</SwissmedicNo5>
<FlagItLimitation>Y</FlagItLimitation>
<OrgGenCode>G</OrgGenCode>
<FlagSB20>N</FlagSB20>
<FlagGGSL>N</FlagGGSL>
<CommentDe />
<CommentFr />
<CommentIt />
<VatInEXF>N</VatInEXF>
<GammeNumber>4201</GammeNumber>
<GammeName>Amlodipin Valsartan Sandoz Oral</GammeName>
<Preismodell />
<Packs>
<Pack ProductKey="28739" PackId="41466">
<DescriptionDe>Blist 98 Stk</DescriptionDe>
<DescriptionFr>blist 98 pce</DescriptionFr>
<DescriptionIt>Blist 98 Stk</DescriptionIt>
<SwissmedicCategory>B</SwissmedicCategory>
<SwissmedicNo8>66015011</SwissmedicNo8>
<SwissmedicNo8ParallelImp />
<FlagNarcosis>N</FlagNarcosis>
<FlagModal>Y</FlagModal>
<FlagGGSL>N</FlagGGSL>
<BagDossierNo>21116</BagDossierNo>
<GTIN>7680660150111</GTIN>
<SizePack />
<PrevGTINcode />
<Limitations />
<PointLimitations />
<Prices>
<PublicPrice>
<Price>58.6</Price>
<ValidFromDate>01.01.2024</ValidFromDate>
<DivisionDescription />
<PriceTypeCode>PPUB</PriceTypeCode>
<PriceTypeDescriptionDe>Publikumspreis</PriceTypeDescriptionDe>
<PriceTypeDescriptionFr>Prix public</PriceTypeDescriptionFr>
<PriceTypeDescriptionIt>Prix public</PriceTypeDescriptionIt>
<PriceChangeTypeCode>MWSTAENDERUNG</PriceChangeTypeCode>
<PriceChangeTypeDescriptionDe>MwSt-Änderung</PriceChangeTypeDescriptionDe>
<PriceChangeTypeDescriptionFr>MwSt-Änderung</PriceChangeTypeDescriptionFr>
<PriceChangeTypeDescriptionIt>MwSt-Änderung</PriceChangeTypeDescriptionIt>
</PublicPrice>
<ExFactoryPrice>
<Price>36.71</Price>
<ValidFromDate>01.12.2020</ValidFromDate>
<DivisionDescription />
<PriceTypeCode>PEXF</PriceTypeCode>
<PriceTypeDescriptionDe>Ex-Factory Preis</PriceTypeDescriptionDe>
<PriceTypeDescriptionFr>Prix ex-factory</PriceTypeDescriptionFr>
<PriceTypeDescriptionIt>Prix ex-factory</PriceTypeDescriptionIt>
<PriceChangeTypeCode>SLAUFNAHME</PriceChangeTypeCode>
<PriceChangeTypeDescriptionDe>Preismutation bei Erstaufnahme</PriceChangeTypeDescriptionDe>
<PriceChangeTypeDescriptionFr>Preismutation bei Erstaufnahme</PriceChangeTypeDescriptionFr>
<PriceChangeTypeDescriptionIt>Preismutation bei Erstaufnahme</PriceChangeTypeDescriptionIt>
<LastPriceChange>01.12.2020</LastPriceChange>
</ExFactoryPrice>
</Prices>
<Partners>
<Partner>
<PartnerType>V</PartnerType>
<Description>Sandoz Pharmaceuticals AG</Description>
<Street>Suurstoffi 14</Street>
<ZipCode>6343</ZipCode>
<Place>Rotkreuz</Place>
<Phone>+41417637411</Phone>
</Partner>
</Partners>
<Status>
<IntegrationDate>01.12.2020</IntegrationDate>
<ValidFromDate>01.12.2020</ValidFromDate>
<ValidThruDate>31.12.9999</ValidThruDate>
<StatusTypeCodeSl>2</StatusTypeCodeSl>
<StatusTypeDescriptionSl>Neuaufnahme</StatusTypeDescriptionSl>
<FlagApd>N</FlagApd>
</Status>
</Pack>
</Packs>
<Substances>
<Substance>
<DescriptionLa>Amlodipinum</DescriptionLa>
<Quantity>5</Quantity>
<QuantityUnit>mg</QuantityUnit>
</Substance>
<Substance>
<DescriptionLa>Valsartanum</DescriptionLa>
<Quantity>80</Quantity>
<QuantityUnit>mg</QuantityUnit>
</Substance>
</Substances>
<Limitations>
<Limitation>
<LimitationCode>AMLOVALSANDO</LimitationCode>
<LimitationType>DIA</LimitationType>
<LimitationNiveau>P</LimitationNiveau>
<IndicationsCodes />
<DescriptionDe>Die gleichzeitige Therapie mit AMLODIPIN VALSARTAN SANDOZ und einem Calciumantagonisten des I.T. 02.06 und/oder einem Angiotensin-II-Antagonisten und/oder einem ACE-Hemmer wird von der Grundversicherung nicht vergütet.
</DescriptionDe>
<DescriptionFr>Le traitement combiné d'AMLODIPINE VALSARTAN SANDOZ et d'un antagoniste du calcium I.T. 02.06 et/ou d'un inhibiteur de l'enzyme de conversion de l'angiotensine II et/ou d'un inhibiteur de l'ECA ne sera pas remboursé par l'assurance de base.</DescriptionFr>
<DescriptionIt>La terapia combinata di AMLODIPIN VALSARTAN SANDOZ e di un calcio antagonista I.T. 02.06 e/o di un cosiddetti antagonisti del recettore dell'angiotensina II e/o un inibitore ACE non sarà rimborsata dall'assicurazione di base.</DescriptionIt>
<ValidFromDate>01.12.2020</ValidFromDate>
<ValidThruDate>31.12.9999</ValidThruDate>
</Limitation>
</Limitations>
<ItCodes>
<ItCode Code="02.">
<DescriptionDe>HERZ UND KREISLAUF</DescriptionDe>
<DescriptionFr>COEUR ET CIRCULATION</DescriptionFr>
<DescriptionIt>SISTEMA CARDIOVASCOLARE </DescriptionIt>
<Limitations />
</ItCode>
<ItCode Code="02.07.">
<DescriptionDe>Blutdrucksenkende Mittel</DescriptionDe>
<DescriptionFr>Antihypertenseurs</DescriptionFr>
<DescriptionIt>Antipertensivi</DescriptionIt>
<Limitations />
</ItCode>
<ItCode Code="02.07.20.">
<DescriptionDe>Kombinierte blutdrucksenkende Mittel</DescriptionDe>
<DescriptionFr>Antihypertenseurs composés</DescriptionFr>
<DescriptionIt>Antipertensivi combinati </DescriptionIt>
<Limitations />
</ItCode>
</ItCodes>
<Status>
<IntegrationDate>01.12.2020</IntegrationDate>
<ValidFromDate>01.12.2020</ValidFromDate>
<ValidThruDate>31.12.9999</ValidThruDate>
<StatusTypeCodeSl>2</StatusTypeCodeSl>
<StatusTypeDescriptionSl>Neuaufnahme</StatusTypeDescriptionSl>
<FlagApd>N</FlagApd>
</Status>
</Preparation>
</Preparations>
Loading
Loading