Skip to content

Commit

Permalink
(#241): Fix and test for exfactory and public prices
Browse files Browse the repository at this point in the history
  • Loading branch information
ngiger committed Feb 8, 2024
1 parent a0b1a1d commit bb346a6
Show file tree
Hide file tree
Showing 6 changed files with 910 additions and 691 deletions.
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 !@pack.nil?
@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

0 comments on commit bb346a6

Please sign in to comment.