diff --git a/dcc.gemspec b/dcc.gemspec index 171f3d8..03d42e1 100644 --- a/dcc.gemspec +++ b/dcc.gemspec @@ -38,5 +38,6 @@ Gem::Specification.new do |spec| spec.add_dependency "lutaml-model", "~> 0.8" spec.add_dependency "moxml", "~> 0.1.26" spec.add_dependency "mml", "~> 2.4.0" + spec.add_dependency "liquid" spec.add_dependency "thor" end diff --git a/lib/dcc/cli/cli.rb b/lib/dcc/cli/cli.rb index 73a51bf..7544c39 100644 --- a/lib/dcc/cli/cli.rb +++ b/lib/dcc/cli/cli.rb @@ -69,6 +69,7 @@ def convert(format, file) case format when "json" then ::Dcc::Convert::Json.call(dcc) when "yaml" then ::Dcc::Convert::Yaml.call(dcc) + when "html" then ::Dcc::Convert::Html.call(dcc) else abort "Format not yet implemented: #{format}" end diff --git a/lib/dcc/convert/html.rb b/lib/dcc/convert/html.rb index 4eb9b50..bb66b7e 100644 --- a/lib/dcc/convert/html.rb +++ b/lib/dcc/convert/html.rb @@ -1,42 +1,19 @@ # frozen_string_literal: true +require "liquid" + module Dcc module Convert - # `Dcc::Convert::Html` renders a parsed DCC into a human-readable HTML - # report with collapsible sections per administrative section and - # measurement result. module Html - class << self - # @param dcc [Lutaml::Model::Serializable] - # @return [Dcc::Convert::Result] - def call(dcc) - payload = <<~HTML - - - - - DCC Report #{escape(unique_identifier_of(dcc))} - - - -

Digital Calibration Certificate

- #{summary_table(dcc)} - #{administrative_section(dcc)} - #{measurement_section(dcc)} - - - HTML + TEMPLATE_PATH = File.expand_path("templates/report.liquid", __dir__).freeze + class << self + def call(dcc, lang: nil) + hash = ::Dcc::Convert::Json.xml_to_hash(dcc.to_xml) + rendered = render_template(hash, lang: lang) ::Dcc::Convert::Result.new( format: :html, - payload: payload, + payload: rendered, source_class: dcc.class.name, schema_version: dcc.schema_version.to_s, ) @@ -44,84 +21,11 @@ def call(dcc) private - def summary_table(dcc) - <<~HTML -
-

Identity

- - - - -
Schema version#{escape(dcc.schema_version)}
Unique identifier#{escape(unique_identifier_of(dcc))}
Country#{escape(country_of(dcc))}
-
- HTML - end - - def administrative_section(dcc) - return "" unless Dcc::TypeGuards.has_attribute?(dcc, :administrative_data) && dcc.administrative_data - - admin = dcc.administrative_data - items = Dcc::TypeGuards.has_attribute?(admin, :items) && admin.items ? Array(admin.items.item) : [] - <<~HTML -
-

Items (#{items.size})

- -
- HTML - end - - def measurement_section(dcc) - return "" unless Dcc::TypeGuards.has_attribute?(dcc, :measurement_results) && dcc.measurement_results - - mrs = Array(dcc.measurement_results.measurement_result) - <<~HTML -
-

Measurement Results (#{mrs.size})

- -
- HTML - end - - def unique_identifier_of(dcc) - Dcc::TypeGuards.has_attribute?(dcc, :administrative_data) && - Dcc::TypeGuards.has_attribute?(dcc.administrative_data, :core_data) && - dcc.administrative_data.core_data && - dcc.administrative_data.core_data.unique_identifier.to_s - end - - def country_of(dcc) - Dcc::TypeGuards.has_attribute?(dcc, :administrative_data) && - Dcc::TypeGuards.has_attribute?(dcc.administrative_data, :core_data) && - dcc.administrative_data.core_data && - dcc.administrative_data.core_data.country_code_iso_3166_1.to_s - end - - def name_of(node) - return "" unless node && Dcc::TypeGuards.has_attribute?(node, :name) - return "" unless node.name - - content = Dcc::TypeGuards.has_attribute?(node.name, :content) ? node.name.content : [] - first = Array(content).first - return "" unless first - - vals = Dcc::TypeGuards.has_attribute?(first, :value) ? first.value : [] - Array(vals).first.to_s - end - - def escape(s) - return "" if s.nil? - - s.to_s - .gsub("&", "&") - .gsub("<", "<") - .gsub(">", ">") - .gsub('"', """) + def render_template(hash, lang:) + template = ::Liquid::Template.parse(File.read(TEMPLATE_PATH)) + template.render("dcc" => hash, "page_lang" => lang) end end end end -end \ No newline at end of file +end diff --git a/lib/dcc/convert/templates/report.liquid b/lib/dcc/convert/templates/report.liquid new file mode 100644 index 0000000..6cb48f2 --- /dev/null +++ b/lib/dcc/convert/templates/report.liquid @@ -0,0 +1,616 @@ + + + + + +DCC {{ dcc.administrativeData.coreData.uniqueIdentifier | default: "Certificate" }} + + + + + + +
+ + {% assign admin = dcc.adminativeData %} + {% assign core = dcc.administrativeData.coreData %} + {% assign items = dcc.administrativeData.items %} + {% assign lab = dcc.administrativeData.calibrationLaboratory %} + {% assign persons = dcc.administrativeData.respPersons %} + {% assign customer = dcc.administrativeData.customer %} + {% assign results = dcc.measurementResults %} + {% assign sv = dcc.schemaVersion %} + + +
+
+
+
+ + Digital Calibration Certificate +
+ {% assign item_name = items.item.name %} + {% if item_name %} + {% if item_name.content %} + {% if item_name.content.first.first %} +

{{ item_name.content.first.last }}

+ {% else %} +

{{ item_name.content._text | default: item_name.content }}

+ {% endif %} + {% else %} +

{{ item_name }}

+ {% endif %} + {% else %} +

Calibration Certificate

+ {% endif %} +

+ {% if lab.contact.name.content %} + {% if lab.contact.name.content.first %} + {{ lab.contact.name.content.first.last }} + {% else %} + {{ lab.contact.name.content }} + {% endif %} + {% endif %} +

+

ID: {{ core.uniqueIdentifier | default: "—" }}

+
+
+
Schema
+
v{{ sv }}
+ {% if core.countryCodeISO3166_1 %} +
+
Country
+
{{ core.countryCodeISO3166_1 }}
+
+ {% endif %} +
+
+
+ + +
+
+
⚙
+ Core Data +
+
+
+
+
Unique ID
+
{{ core.uniqueIdentifier | default: "—" }}
+
+ {% if core.receiptDate %} +
+
Receipt Date
+
{{ core.receiptDate }}
+
+ {% endif %} + {% if core.beginPerformanceDate %} +
+
Performance Begin
+
{{ core.beginPerformanceDate }}
+
+ {% endif %} + {% if core.endPerformanceDate %} +
+
Performance End
+
{{ core.endPerformanceDate }}
+
+ {% endif %} + {% if core.usedLangCodeISO639_1 %} +
+
Languages
+
{{ core.usedLangCodeISO639_1 | join: ", " }}
+
+ {% endif %} + {% if core.mandatoryLangCodeISO639_1 %} +
+
Mandatory Language
+
{{ core.mandatoryLangCodeISO639_1 }}
+
+ {% endif %} +
+
+
+ + + {% assign item_list = items.item %} + {% if item_list %} +
+
+
☰
+ Calibrated Item{{ item_list | size | times: 1 | minus: 1 | remove: "-" | prepend: "s" | remove_first: "s0s" | remove_first: "s-1s" }} +
+
+ {% for item_hash in item_list %} + {% assign item = item_hash[1] | default: item_hash %} +
+ {% if item.model %} +
+
Model
+
{{ item.model }}
+
+ {% endif %} + {% if item.manufacturer %} +
+
Manufacturer
+
+ {% if item.manufacturer.name.content._text %} + {{ item.manufacturer.name.content._text }} + {% elsif item.manufacturer.name.content.first %} + {{ item.manufacturer.name.content.first.last }} + {% else %} + {{ item.manufacturer.name.content }} + {% endif %} +
+
+ {% endif %} +
+ {% if item.identifications %} + + + + {% assign ids = item.identifications.identification %} + {% for id_hash in ids %} + {% assign id = id_hash[1] | default: id_hash %} + {% if id.issuer %} + + {% endif %} + {% endfor %} + +
Identification IssuerValue
{{ id.issuer }}{{ id.value }}
+ {% endif %} + {% endfor %} +
+
+ {% endif %} + + + {% assign lab_contact = lab.contact %} + {% if lab_contact %} +
+
+
☑
+ Calibration Laboratory +
+
+
+
+
Name
+
+ {% if lab_contact.name.content._text %} + {{ lab_contact.name.content._text }} + {% elsif lab_contact.name.content.first %} + {{ lab_contact.name.content.first.last }} + {% else %} + {{ lab_contact.name.content }} + {% endif %} +
+
+ {% if lab_contact.eMail %} +
+
Email
+
{{ lab_contact.eMail }}
+
+ {% endif %} + {% if lab_contact.phone %} +
+
Phone
+
{{ lab_contact.phone }}
+
+ {% endif %} + {% if lab_contact.location %} +
+
Address
+
+ {% if lab_contact.location.street %}{{ lab_contact.location.street }} {{ lab_contact.location.streetNo }}{% endif %} + {% if lab_contact.location.postCode %}
{{ lab_contact.location.postCode }} {{ lab_contact.location.city }}{% endif %} + {% if lab_contact.location.countryCode %}
{{ lab_contact.location.countryCode }}{% endif %} +
+
+ {% endif %} +
+
+
+ {% endif %} + + + {% assign person_list = persons.respPerson %} + {% if person_list %} +
+
+
♂
+ Responsible Persons +
+
+ {% for person_hash in person_list %} + {% assign person = person_hash[1] | default: person_hash %} + {% if person.person %} +
+
+ {% assign pname = "" %} + {% if person.person.name.content._text %} + {% assign pname = person.person.name.content._text %} + {% elsif person.person.name.content.first %} + {% assign pname = person.person.name.content.first.last %} + {% else %} + {% assign pname = person.person.name.content %} + {% endif %} + {{ pname | split: " " | last | truncate: 2, "" | upcase }} +
+
+
{{ pname }}
+ {% if person.person.eMail %}
{{ person.person.eMail }}
{% endif %} +
+ {% if person.mainSigner %}Main Signer{% endif %} +
+ {% endif %} + {% endfor %} +
+
+ {% endif %} + + + {% assign mr_list = results.measurementResult %} + {% if mr_list %} +
+
+
⚡
+ Measurement Results +
+
+ {% for mr_hash in mr_list %} + {% assign mr = mr_hash[1] | default: mr_hash %} +
+
+ {% if mr.name.content._text %} + {{ mr.name.content._text }} + {% elsif mr.name.content.first %} + {{ mr.name.content.first.last }} + {% else %} + {{ mr.name.content }} + {% endif %} +
+ {% if mr.usedMethods %} + {% assign methods = mr.usedMethods.usedMethod %} + {% for method_hash in methods %} + {% assign method = method_hash[1] | default: method_hash %} + {% if method.name %} +
+ {% if method.name.content._text %} + {{ method.name.content._text }} + {% elsif method.name.content.first %} + {{ method.name.content.first.last }} + {% else %} + {{ method.name.content }} + {% endif %} +
+ {% endif %} + {% endfor %} + {% endif %} + {% if mr.results %} + {% assign result_list = mr.results.result %} + {% if result_list %} + + + + {% for r_hash in result_list %} + {% assign r = r_hash[1] | default: r_hash %} + {% if r.name %} + + {% endif %} + {% endfor %} + +
Result
+ {% if r.name.content._text %} + {{ r.name.content._text }} + {% elsif r.name.content.first %} + {{ r.name.content.first.last }} + {% else %} + {{ r.name.content }} + {% endif %} +
+ {% endif %} + {% endif %} +
+ {% unless forloop.last %}
{% endunless %} + {% endfor %} +
+
+ {% endif %} + + + {% if customer %} +
+
+
➤
+ Customer +
+
+
+
+
Name
+
+ {% if customer.name.content._text %} + {{ customer.name.content._text }} + {% elsif customer.name.content.first %} + {{ customer.name.content.first.last }} + {% else %} + {{ customer.name.content }} + {% endif %} +
+
+ {% if customer.eMail %} +
+
Email
+
{{ customer.eMail }}
+
+ {% endif %} +
+
+
+ {% endif %} + +
+ +