elibri_onix_mocks 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -0
- data/Gemfile +1 -1
- data/elibri_onix_mocks.gemspec +1 -0
- data/lib/elibri_onix_mocks.rb +1 -0
- data/lib/elibri_onix_mocks/generators/xml_generator.rb +1 -989
- data/lib/elibri_onix_mocks/version.rb +2 -2
- metadata +24 -13
- data/lib/elibri_onix_mocks/generators/xml_tags.yml +0 -388
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/elibri_onix_mocks.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
s.add_development_dependency 'rake'
|
25
25
|
|
26
26
|
# s.add_runtime_dependency "rest-client"
|
27
|
+
s.add_runtime_dependency "elibri_onix_generator"
|
27
28
|
s.add_runtime_dependency "elibri_onix_dict"
|
28
29
|
s.add_runtime_dependency 'elibri_api_client'
|
29
30
|
s.add_runtime_dependency "mocha"
|
data/lib/elibri_onix_mocks.rb
CHANGED
@@ -2,6 +2,7 @@ require 'active_support'
|
|
2
2
|
require 'ostruct'
|
3
3
|
require 'elibri_onix_dict'
|
4
4
|
require 'elibri_api_client'
|
5
|
+
require 'elibri_onix_generator'
|
5
6
|
require 'elibri_onix_mocks/onix_helpers'
|
6
7
|
require "elibri_onix_mocks/version"
|
7
8
|
require 'elibri_onix_mocks/mocks/mock_method_missing'
|
@@ -1,995 +1,7 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require 'builder'
|
4
|
-
|
5
1
|
module Elibri
|
6
2
|
module ONIX
|
7
|
-
|
8
3
|
class XMLGenerator
|
9
|
-
|
10
|
-
|
11
|
-
SHORT_TAGS = YAML::load_file(File.dirname(__FILE__) + "/xml_tags.yml")
|
12
|
-
DOC_ORDER = ["record_identifiers", "publishing_status", "product_form", "contributors", "titles", "series_memberships", "measurement",
|
13
|
-
"sale_restrictions", "audience_range", "publisher_info", "extent", "edition", "languages", "epub_details",
|
14
|
-
"texts", "supporting_resources", "elibri_extensions"]
|
15
|
-
#"subjects", "related_products", "supply_details"
|
16
|
-
attr_reader :builder, :tags_type
|
17
|
-
|
18
|
-
|
19
|
-
def self.tag(builder, short_tags, tag_id, *args, &block)
|
20
|
-
if short_tags
|
21
|
-
if SHORT_TAGS[tag_id]
|
22
|
-
tag_id = SHORT_TAGS[tag_id]
|
23
|
-
elsif tag_id.starts_with?("elibri")
|
24
|
-
tag_id
|
25
|
-
else
|
26
|
-
raise "Unknow short tag for: #{tag_id}"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
builder.__send__(tag_id, *args, &block)
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.render_header(builder, options = {}, &block)
|
33
|
-
options.reverse_merge!({:short_tags => false, :elibri_onix_dialect => '3.0.1'})
|
34
|
-
short_tags = options[:short_tags]
|
35
|
-
|
36
|
-
builder.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
|
37
|
-
message_attributes = {:release => "3.0", :xmlns => "http://www.editeur.org/onix/3.0/reference", "xmlns:elibri" => "http://elibri.com.pl/ns/extensions"}
|
38
|
-
message_attributes.delete('xmlns:elibri') if options[:pure_onix]
|
39
|
-
|
40
|
-
builder.ONIXMessage message_attributes do
|
41
|
-
unless options[:pure_onix]
|
42
|
-
builder.elibri :Dialect, options[:elibri_onix_dialect] # potrzebne, aby parser wiedział jak interpretować niektóre tagi
|
43
|
-
end
|
44
|
-
tag(builder, short_tags, :Header) do
|
45
|
-
tag(builder, short_tags, :Sender) do
|
46
|
-
tag(builder, short_tags, :SenderName, "Elibri.com.pl")
|
47
|
-
tag(builder, short_tags, :ContactName, "Tomasz Meka")
|
48
|
-
tag(builder, short_tags, :EmailAddress, "kontakt@elibri.com.pl")
|
49
|
-
end
|
50
|
-
tag(builder, short_tags, :SentDateTime, Date.today.strftime("%Y%m%d"))
|
51
|
-
end
|
52
|
-
yield(builder) if block_given?
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
|
57
|
-
def initialize(products, options = {})
|
58
|
-
options.reverse_merge!({
|
59
|
-
:tags_type => :full,
|
60
|
-
:export_headers => true,
|
61
|
-
:elibri_onix_dialect => '3.0.1',
|
62
|
-
:comments => false,
|
63
|
-
:xml_variant => Elibri::XmlVariant::FULL_VARIANT
|
64
|
-
})
|
65
|
-
|
66
|
-
@xml_variant = options[:xml_variant]
|
67
|
-
raise ":xml_variant unspecified" if @xml_variant.blank? or !@xml_variant.kind_of?(::Elibri::XmlVariant)
|
68
|
-
|
69
|
-
@products = Array(products)
|
70
|
-
@tags_type = ActiveSupport::StringInquirer.new(options[:tags_type].to_s)
|
71
|
-
@comments = options[:comments]
|
72
|
-
@comment_kinds = options[:comment_kinds]
|
73
|
-
@out = []
|
74
|
-
@builder = Builder::XmlMarkup.new(:indent => 2, :target => @out)
|
75
|
-
@elibri_onix_dialect = options[:elibri_onix_dialect]
|
76
|
-
# Gdy true, ignorujemy rozszerzenia eLibri
|
77
|
-
@pure_onix = options[:pure_onix]
|
78
|
-
|
79
|
-
# W testach często nie chcę żadnych nagłówków - interesuje mnie tylko tag <Product>
|
80
|
-
if options[:export_headers]
|
81
|
-
ONIX::XMLGenerator.render_header(builder, :short_tags => tags_type.short?, :elibri_onix_dialect => @elibri_onix_dialect, :pure_onix => @pure_onix) do
|
82
|
-
render_products!
|
83
|
-
end
|
84
|
-
else
|
85
|
-
render_products!
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
|
90
|
-
def to_s
|
91
|
-
@out.join
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
# Zwróć dokumentację dla metod sekcji ONIX z bieżącego pliku. Dzięki temu dokumentacja ONIX jest generowana w locie
|
96
|
-
# i nie rozjedzie się z kodem. Dokumentacje można wygenerować tylko dla metod 'def export_XXX!'.
|
97
|
-
#
|
98
|
-
# Przykład dokumentowania:
|
99
|
-
# # @hidden_tags RecordReference NotificationType
|
100
|
-
# # @title Wymiary produktu
|
101
|
-
# # eLibri zachowuje tylko <strong>wysokość, szerokość, grubość oraz masę produktu.</strong> Dla produktów typu mapa, eksportujemy również jej skalę
|
102
|
-
# # w tagu <MapScale>
|
103
|
-
# def export_measurement!(product)
|
104
|
-
# [...]
|
105
|
-
# end
|
106
|
-
#
|
107
|
-
# @hidden_tags określa tagi ONIX, które należy zwinąć w celu zachowania czytelności XML`a.
|
108
|
-
# @title to tytuł sekcji a reszta to wieloliniowy opis.
|
109
|
-
#
|
110
|
-
# Dla każdej sekcji trzeba utworzyć odpowiednią metodę w Product::Examples, która zwróci stub produktu.
|
111
|
-
# Np. dla metody 'export_measurement!' w Product::Examples należy utworzyć metodę 'onix_measurement_example'.
|
112
|
-
def self.onix_sections_docs
|
113
|
-
# Wczytaj bieżący plik
|
114
|
-
code_lines = File.readlines(__FILE__)
|
115
|
-
|
116
|
-
section_docs = Array.new
|
117
|
-
# Dla każdej metody o sygnaturze 'def export_NAZWA_SEKCJI!' czytaj otaczające linie komentarzy:
|
118
|
-
ONIX::XMLGenerator.instance_methods.grep(/export_/).each_with_index do |method_name, section_idx|
|
119
|
-
section_docs[section_idx] ||= Hash.new
|
120
|
-
section_docs[section_idx][:section_name] = method_name[/export_(.*)!/, 1] # "export_supplier_identifier!" => "supplier_identifier"
|
121
|
-
section_docs[section_idx][:hidden_tags] = Array.new
|
122
|
-
section_docs[section_idx][:auto_render] = true
|
123
|
-
|
124
|
-
# Znajdź numer linii z definicją metody:
|
125
|
-
method_definition_line_idx = code_lines.find_index {|line| line.match(/^\s*def #{method_name}/)}
|
126
|
-
|
127
|
-
# Cofamy się w gorę kodu, aż do początku pliku w poszukiwaniu linii zawierającej tag @title w komentarzu.
|
128
|
-
(method_definition_line_idx-1).downto(0).each do |line_idx|
|
129
|
-
# Oczyść linię kodu ze znaku komentarza i zbędnych spacji:
|
130
|
-
line = code_lines[line_idx].strip.sub(/^\s*#\s*/, '#')
|
131
|
-
raise "Nieprawidłowy format dokumentacji dla metody #{method_name}" if line.match(/^end$/)
|
132
|
-
if md = line.match(/^\s*$/)
|
133
|
-
break
|
134
|
-
elsif md = line.match(/@render (.*)$/)
|
135
|
-
section_docs[section_idx][:auto_render] = false
|
136
|
-
render_call = "\n= render :partial => 'example', :locals => { :method => '#{md[1].strip}' }\n"
|
137
|
-
section_docs[section_idx][:description] = [render_call, section_docs[section_idx][:description]].join("\n")
|
138
|
-
elsif md = line.match(/@title (.*)$/)
|
139
|
-
section_docs[section_idx][:section_title] = md[1].gsub(/^#/, '')
|
140
|
-
elsif md = line.match(/@hidden_tags (.*)$/)
|
141
|
-
section_docs[section_idx][:hidden_tags] = md[1].gsub(/^#/, '').scan(/\w+/)
|
142
|
-
elsif line == '#'
|
143
|
-
section_docs[section_idx][:description] = ["\n%br/\n", section_docs[section_idx][:description]].join("\n")
|
144
|
-
else
|
145
|
-
section_docs[section_idx][:description] = [line.gsub(/^#/, ''), section_docs[section_idx][:description]].join("\n")
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
# Zwróć posortowane według kolejności sekcji:
|
150
|
-
section_docs.find_all { |section_hash| DOC_ORDER.index(section_hash[:section_name]) }.sort_by {|section_hash| DOC_ORDER.index(section_hash[:section_name]) }
|
151
|
-
end
|
152
|
-
|
153
|
-
|
154
|
-
protected
|
155
|
-
|
156
|
-
# Wstaw do XML`a komentarz
|
157
|
-
def comment(text, options = {})
|
158
|
-
if options[:kind] && @comment_kinds
|
159
|
-
Array(options[:kind]).each do |kind|
|
160
|
-
builder.comment!("$#{kind}$ #{text}")
|
161
|
-
end
|
162
|
-
elsif @comments
|
163
|
-
builder.comment!(text)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
|
168
|
-
def comment_dictionary(description, dict, options = {})
|
169
|
-
indent = options[:indent] || 4
|
170
|
-
pretty_string = lambda {|dict_item| "\n" + " " * indent + "#{dict_item.onix_code} - #{dict_item.name}" }
|
171
|
-
case dict
|
172
|
-
when Symbol
|
173
|
-
dictionary_items = Elibri::ONIX::Dict::Release_3_0.const_get(dict)::ALL.map(&pretty_string)
|
174
|
-
when Array
|
175
|
-
dictionary_items = dict.map {|dict_item| "\n" + " " * indent + dict_item }
|
176
|
-
end
|
177
|
-
|
178
|
-
comment(description + dictionary_items.join, options)
|
179
|
-
end
|
180
|
-
|
181
|
-
|
182
|
-
def render_products!
|
183
|
-
@products.each do |product|
|
184
|
-
next unless product.public?
|
185
|
-
|
186
|
-
tag(:Product) do
|
187
|
-
export_record_identifiers!(product) #PR.1 + PR.2
|
188
|
-
if @xml_variant.includes_basic_meta?
|
189
|
-
tag(:DescriptiveDetail) do
|
190
|
-
export_product_form!(product) #PR.3
|
191
|
-
export_epub_details!(product) #PR.3
|
192
|
-
export_measurement!(product)
|
193
|
-
#jak się dodaje tytuł, który nie jest samodzielne w sprzedaży?
|
194
|
-
#jak się dodaje tytuł, który zostanie przeceniony?
|
195
|
-
export_series_memberships!(product) #P.5
|
196
|
-
export_titles!(product) #PR.6
|
197
|
-
export_contributors!(product) #PR.7
|
198
|
-
#PR.8 - konferencje
|
199
|
-
export_edition!(product) #PR.9
|
200
|
-
export_languages!(product) #PR.10
|
201
|
-
export_extent!(product) #PR.11
|
202
|
-
export_subjects!(product) #PR.12
|
203
|
-
export_audience_range!(product) if product.audience_range_present? #PR.13
|
204
|
-
end
|
205
|
-
end
|
206
|
-
if @xml_variant.includes_other_texts? || @xml_variant.includes_media_files?
|
207
|
-
tag(:CollateralDetail) do
|
208
|
-
if @xml_variant.includes_other_texts? #TODO zmienić nazwę wariantu
|
209
|
-
export_texts!(product) #PR.14
|
210
|
-
end
|
211
|
-
#P.15 - citywany kontent - sprawdzić
|
212
|
-
if @xml_variant.includes_media_files?
|
213
|
-
export_supporting_resources!(product) #PR.16 #TODO - to jest też do przerobienia
|
214
|
-
end
|
215
|
-
#P.17 - nagrody
|
216
|
-
end
|
217
|
-
end
|
218
|
-
remove_tag_if_empty!(:CollateralDetail)
|
219
|
-
#P.18 - ContentItem
|
220
|
-
tag(:PublishingDetail) do
|
221
|
-
export_publisher_info!(product) #P.19
|
222
|
-
export_publishing_status!(product) #PR.20
|
223
|
-
export_sale_restrictions!(product) if product.sale_restricted? #PR.21
|
224
|
-
end
|
225
|
-
remove_tag_if_empty!(:PublishingDetail)
|
226
|
-
#P.23 - related products
|
227
|
-
if product.facsimiles.present? or product.similar_products.present?
|
228
|
-
export_related_products!(product)
|
229
|
-
end
|
230
|
-
#P.24 - Market
|
231
|
-
#P.25 - market representation
|
232
|
-
if @xml_variant.includes_stocks?
|
233
|
-
export_supply_details!(product) #PR.26
|
234
|
-
end
|
235
|
-
#fake dla exportu ze sklepu - w elibri ten kod nie zadziała
|
236
|
-
# if @xml_variant.respond_to?(:cover_price?) && @xml_variant.cover_price?
|
237
|
-
# export_cover_price!(product) #fake, żeby jakoś te dane wysłać
|
238
|
-
# end
|
239
|
-
export_elibri_extensions!(product) unless @pure_onix
|
240
|
-
end
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
|
245
|
-
# Renderuj tag w XML`u za pomocą Buildera. Jeśli wybrano opcję krótkich tagów,
|
246
|
-
# wstaw krótki tag z hasha SHORT_TAGS.
|
247
|
-
def tag(tag_id, *args, &block)
|
248
|
-
self.class.tag(builder, tags_type.short?, tag_id, *args, &block)
|
249
|
-
end
|
250
|
-
|
251
|
-
def remove_tag_if_empty!(tag_name)
|
252
|
-
idx = @out.rindex("<#{tag_name}")
|
253
|
-
if idx
|
254
|
-
tail = @out[idx..-1].join.strip.gsub("\n", "").gsub(" ", "")
|
255
|
-
if tail == "<#{tag_name}></#{tag_name}>" #wycinaj końcówkę
|
256
|
-
(@out.size - idx + 1).times do #zmieniaj listę in-place
|
257
|
-
@out.pop
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
# @hidden_tags NotificationType DescriptiveDetail ProductSupply PublishingDetail
|
264
|
-
# @title Identyfikatory rekordu
|
265
|
-
# Każdy rekord w ONIX-ie posiada wewnętrzny identyfikator, który jest dowolnym ciągiem znaków, i jest przekazywany
|
266
|
-
# w tagu <strong><ProductIdentifier></strong>. Gwarantowana jest jego niezmienność.
|
267
|
-
#
|
268
|
-
#
|
269
|
-
# Oprócz tego każdy produkt może posiadać numer ISBN, EAN oraz jeden lub więcej identyfikatorów dostawców (np. numer w bazie Olesiejuka)
|
270
|
-
# Tutaj już nie ma gwarancji niezmienności, choć jest to bardzo rzadka sytuacja (np. wydrukowany został jednak inny numer ISBN na okładce,
|
271
|
-
# i wydawcnictwo zmienia wpis w eLibri)
|
272
|
-
def export_record_identifiers!(product)
|
273
|
-
comment 'Unikalne ID rekordu produktu', :kind => :onix_record_identifiers
|
274
|
-
tag(:RecordReference, product.record_reference) #doc
|
275
|
-
comment_dictionary "Typ powiadomienia", :NotificationType, :kind => :onix_publishing_status
|
276
|
-
tag(:NotificationType, product.notification_type.onix_code) # Notification confirmed on publication - Lista 1
|
277
|
-
if product.respond_to?(:deletion_text) && product.deletion_text.present?
|
278
|
-
comment "Występuje tylko gdy NotificationType == #{Elibri::ONIX::Dict::Release_3_0::NotificationType::DELETE}", :kind => :onix_record_identifiers
|
279
|
-
tag(:DeletionText, product.deletion_text)
|
280
|
-
end
|
281
|
-
|
282
|
-
if product.isbn_value
|
283
|
-
comment 'ISBN', :kind => :onix_record_identifiers
|
284
|
-
tag(:ProductIdentifier) do
|
285
|
-
tag(:ProductIDType, Elibri::ONIX::Dict::Release_3_0::ProductIDType::ISBN13) #lista 5
|
286
|
-
tag(:IDValue, product.isbn_value)
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
if product.ean.present? && product.ean != product.isbn_value
|
291
|
-
comment 'EAN-13 - gdy inny niż ISBN', :kind => :onix_record_identifiers
|
292
|
-
|
293
|
-
tag(:ProductIdentifier) do
|
294
|
-
tag(:ProductIDType, Elibri::ONIX::Dict::Release_3_0::ProductIDType::EAN)
|
295
|
-
tag(:IDValue, product.ean)
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
if @xml_variant.includes_stocks?
|
300
|
-
product.product_availabilities.each do |pa|
|
301
|
-
if pa.supplier_identifier.present?
|
302
|
-
comment "Identyfikator dostawcy: #{pa.supplier.name}", :kind => :onix_record_identifiers
|
303
|
-
tag(:ProductIdentifier) do
|
304
|
-
tag(:ProductIDType, Elibri::ONIX::Dict::Release_3_0::ProductIDType::PROPRIETARY) #lista 5
|
305
|
-
tag(:IDTypeName, pa.supplier.name)
|
306
|
-
tag(:IDValue, pa.supplier_identifier)
|
307
|
-
end
|
308
|
-
end
|
309
|
-
end
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
|
314
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier TitleDetail
|
315
|
-
# @title Forma produktu
|
316
|
-
# <strong><ProductForm></strong> określa typ produktu. Np. BA to książka.<br/>
|
317
|
-
# <strong><ProductComposition></strong> przybiera aktualnie zawsze wartość 00 - czyli że przedmiotem handlu jest pojedyncza książka.
|
318
|
-
# W przyszłości ulegnie to zmianie, gdy dodamy do eLibri obsługę pakietów książek. Pakiet książek to komplet kilku książek,
|
319
|
-
# z nowym numerem ISBN, i nową ceną, na ogół niższą, niż suma cen książek zawartych w pakiecie.
|
320
|
-
def export_product_form!(product)
|
321
|
-
comment 'W tej chwili tylko 00 - pojedynczy element', :kind => :onix_product_form
|
322
|
-
tag(:ProductComposition, '00') #lista 2 - Single-item retail product
|
323
|
-
|
324
|
-
if product.product_form_onix_code
|
325
|
-
comment_dictionary "Format produktu", :ProductFormCode, :indent => 10, :kind => [:onix_product_form, :onix_epub_details]
|
326
|
-
tag(:ProductForm, product.product_form_onix_code)
|
327
|
-
end
|
328
|
-
|
329
|
-
if product.product_form_detail_onix_code
|
330
|
-
comment_dictionary "Szczegóły formatu produktu", :ProductFormDetail, :indent => 10, :kind => :onix_epub_details
|
331
|
-
tag(:ProductFormDetail, product.product_form_detail_onix_code)
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
|
336
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier TitleDetail PublishingDetail ProductComposition
|
337
|
-
# @title Zabezpieczenia e-booków
|
338
|
-
# <strong><EpubTechnicalProtection></strong> Określa typ zabezpieczenia stosowanego przy publikacji e-booka.<br/>
|
339
|
-
# <strong><ProductFormDetail></strong> zawiera format w jakim rozprowadzany jest e-book.
|
340
|
-
# Aktualnie może przyjąć wartości takie jak:
|
341
|
-
# #{Elibri::ONIX::Dict::Release_3_0::ProductFormDetail::ALL.map(&:name).to_sentence(:last_word_connector => ' lub ')}
|
342
|
-
def export_epub_details!(product)
|
343
|
-
return unless product.kind_of_ebook?
|
344
|
-
if product.epub_technical_protection
|
345
|
-
comment_dictionary "Zabezpieczenie", :EpubTechnicalProtection, :indent => 10, :kind => :onix_epub_details
|
346
|
-
tag(:EpubTechnicalProtection, product.epub_technical_protection_onix_code)
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
|
351
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier ProductComposition ProductForm TitleDetail
|
352
|
-
# @title Wymiary produktu
|
353
|
-
# Następujące atrybuty są udostępniane: wysokość, szerokość, grubość oraz masę produktu. Pierwsze trzy podajemy zawsze w milimetrach, masę w gramach.
|
354
|
-
# W przypadku map eksportujemy również jej skalę w tagu <MapScale>
|
355
|
-
def export_measurement!(product)
|
356
|
-
return unless product.kind_of_measurable?
|
357
|
-
[[product.height, Elibri::ONIX::Dict::Release_3_0::MeasureType::HEIGHT, Product::HEIGHT_UNIT, 'Wysokość'],
|
358
|
-
[product.width, Elibri::ONIX::Dict::Release_3_0::MeasureType::WIDTH, Product::WIDTH_UNIT, 'Szerokość'],
|
359
|
-
[product.thickness, Elibri::ONIX::Dict::Release_3_0::MeasureType::THICKNESS, Product::THICKNESS_UNIT, 'Grubość'],
|
360
|
-
[product.weight, Elibri::ONIX::Dict::Release_3_0::MeasureType::WEIGHT, Product::WEIGHT_UNIT, 'Masa']
|
361
|
-
].each do |value, measure_type_code, unit_code, name|
|
362
|
-
if value
|
363
|
-
tag(:Measure) do
|
364
|
-
comment "#{name}: #{value}#{unit_code}", :kind => :onix_measurement
|
365
|
-
tag(:MeasureType, measure_type_code) #lista 48
|
366
|
-
tag(:Measurement, value)
|
367
|
-
tag(:MeasureUnitCode, unit_code)
|
368
|
-
end
|
369
|
-
end
|
370
|
-
end
|
371
|
-
|
372
|
-
if product.kind_of_map? and product.map_scale
|
373
|
-
comment 'Skala mapy - tylko dla produktów typu mapa'
|
374
|
-
tag(:MapScale, product.map_scale)
|
375
|
-
end
|
376
|
-
end
|
377
|
-
|
378
|
-
|
379
|
-
# @hidden_tags ProductIdentifier DescriptiveDetail ProductSupply
|
380
|
-
# @title Cykl życia rekordu
|
381
|
-
# W ONIX-ie status rekordu jest reprezentowany za pomocą kombinacji tagów <strong><NotificationType></strong> i <strong><PublishingStatus></strong>
|
382
|
-
#
|
383
|
-
#
|
384
|
-
# Tuż po założeniu przez wydawnictwo każdy rekord ma status prywatny. Jest to wtedy widoczny tylko i wyłącznie dla pracowników wydawnictwa,
|
385
|
-
# i nie jest udostępniany na zewnątrz. Po wypełnieniu kilku podstawowych danych (autor, tytuł) pracownik wydawnictwa może zmienić status
|
386
|
-
# rekordu na <i>zapowiedź</i>. W tym przypadku wartość <strong><NotificationType></strong> to 01 - wczesne powiadomienie.
|
387
|
-
#
|
388
|
-
# @render onix_announced_product_example
|
389
|
-
#
|
390
|
-
# Po uzupełnieniu większości danych niezbędnych (okładka, cena, ISBN, okładka, dokładna data premiery) wydawnictwo może zmienić
|
391
|
-
# status rekordu na <i>przedsprzedaż</i>.
|
392
|
-
# W zależności od naszego poziomu zaufania do terminowości wydawnictwa można uruchomić dla takiego tytułu przedsprzedaż na stronie księgarni.
|
393
|
-
# Wydawnictwo może zmienić datę premiery, jeśli produkt znajduje się w przedsprzedaży, warto zaimplementować procedurę poinformowania klientów
|
394
|
-
# o zmianie.
|
395
|
-
# Rekord o takim statusie ma wartość 02 w <strong><NotificationType></strong>
|
396
|
-
#
|
397
|
-
# @render onix_preorder_product_example
|
398
|
-
#
|
399
|
-
# Po ukazaniu się książki jej status zostaje zmieniony na <i>dostępna na rynku</i>.
|
400
|
-
# Rekord o takim statusie ma wartość 03 w <strong><NotificationType></strong> i 04 w <strong><PublishingDetail></strong>
|
401
|
-
#
|
402
|
-
# @render onix_published_product_example
|
403
|
-
#
|
404
|
-
# Każde wydawnictwo oczywiście liczy na to, że nakład książki się wyprzeda. Bardzo trudno jest poprawnie zdefiniować, co oznacza wyczerpany nakład.
|
405
|
-
# Bardzo długo egzemplarze książki, której nie ma już w magazynie wydawnictwa, mogą znajdować się w księgarniach i być zwracane co jakiś czas do hurtowni,
|
406
|
-
# co powoduje, że dany tytuł będzie się stawał na jakiś czas dostępny. W związku z tym informacje o wyczerpaniu się nakładu podejmuje wydawnictwo, i oznacza
|
407
|
-
# to, że nie będzie akceptować zamówień na określony tytuł. Nie oznacza to jednak, że tytuł jest w ogóle niedostępny, w dalszym ciągu może być w ofercie
|
408
|
-
# hurtowni.
|
409
|
-
# Rekord o statusie <i>nakład wyczerpany</i> ma wartość 03 w <strong><NotificationType></strong> i 07 w <strong><PublishingDetail></strong>
|
410
|
-
#
|
411
|
-
# @render onix_out_of_print_product_example
|
412
|
-
#
|
413
|
-
# Status 08 (niedostępny) w <strong><PublishingDetail></strong> nie jest w tej chwili używany przez eLibri. W przyszłości proszę się spodziewać również
|
414
|
-
# dodania informacji o dodrukach realizowanych pod tym samym numerem ISBN.
|
415
|
-
#
|
416
|
-
def export_publishing_status!(product)
|
417
|
-
if product.publishing_status_onix_code.present?
|
418
|
-
comment_dictionary 'Status publikacji', :PublishingStatusCode, :indent => 10, :kind => :onix_publishing_status
|
419
|
-
tag(:PublishingStatus, product.publishing_status_onix_code) #lista 64 #TODO sprawdzić
|
420
|
-
end
|
421
|
-
|
422
|
-
#TODO - tu można również zawrzeć datę, przed którą produkt nie może być importowany do baz sklepów
|
423
|
-
date, format_code = product.publication_date_with_onix_format_code
|
424
|
-
if date && format_code
|
425
|
-
tag(:PublishingDate) do
|
426
|
-
comment 'Zawsze 01 - data publikacji', :kind => :onix_publishing_status
|
427
|
-
tag(:PublishingDateRole, Elibri::ONIX::Dict::Release_3_0::PublishingDateRole::PUBLICATION_DATE) #lista 163
|
428
|
-
comment_dictionary "Format daty", :DateFormat, :indent => 12, :kind => :onix_publishing_status
|
429
|
-
tag(:DateFormat, format_code) #lista 55
|
430
|
-
tag(:Date, date)
|
431
|
-
end
|
432
|
-
end
|
433
|
-
end
|
434
|
-
|
435
|
-
|
436
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier DescriptiveDetail
|
437
|
-
# @title Ograniczenia sprzedaży
|
438
|
-
# eLibri umożliwia przechowywanie informacji o ograniczaniach dotyczących sprzedaży produktu.
|
439
|
-
# Obecnie obsługuje tylko 1 typ ograniczenia: wyłączność na produkt dla określonego detalisty.
|
440
|
-
# Opcjonalnie może się też pojawić data wygaśnięcia ograniczenia - w innym przypadku oznacza to, że produkt został przeznaczony tylko
|
441
|
-
# dla jednej, określonej sieci.
|
442
|
-
# W przypadku, gdy jest podana data wyłączności na sprzedaż produktu, należy ją traktować jako faktyczną datę premiery.
|
443
|
-
def export_sale_restrictions!(product)
|
444
|
-
if product.sale_restricted?
|
445
|
-
tag(:SalesRestriction) do
|
446
|
-
#lista 71 - For sale only through designated retailer, though not under retailer's own brand/imprint.
|
447
|
-
comment "Typ restrykcji - używamy tylko #{Elibri::ONIX::Dict::Release_3_0::SalesRestrictionType::RETAILER_EXCLUSIVE} (sprzedaż tylko poprzez wybranego detalistę)", :kind => :onix_sale_restrictions
|
448
|
-
tag(:SalesRestrictionType, Elibri::ONIX::Dict::Release_3_0::SalesRestrictionType::RETAILER_EXCLUSIVE)
|
449
|
-
tag(:SalesOutlet) do
|
450
|
-
tag(:SalesOutletName, product.sale_restricted_for)
|
451
|
-
end
|
452
|
-
comment "Ograniczenie wygasa #{product.sale_restricted_to.strftime("%d.%m.%Y")}", :kind => :onix_sale_restrictions
|
453
|
-
tag(:EndDate, product.sale_restricted_to.strftime("%Y%m%d"))
|
454
|
-
end
|
455
|
-
end
|
456
|
-
end
|
457
|
-
|
458
|
-
|
459
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier ProductComposition ProductForm TitleDetail
|
460
|
-
# @title Wiek czytelnika
|
461
|
-
# Zarówno wiek 'od', jak i wiek 'do' są opcjonalne.
|
462
|
-
def export_audience_range!(product)
|
463
|
-
if product.audience_age_from.present?
|
464
|
-
tag(:AudienceRange) do
|
465
|
-
comment "Ograniczenie dotyczy wieku czytelnika - zawsze #{Elibri::ONIX::Dict::Release_3_0::AudienceRangeQualifier::READING_AGE}", :kind => :onix_audience_range
|
466
|
-
tag(:AudienceRangeQualifier, Elibri::ONIX::Dict::Release_3_0::AudienceRangeQualifier::READING_AGE)
|
467
|
-
comment "Wiek od #{product.audience_age_from} lat", :kind => :onix_audience_range
|
468
|
-
tag(:AudienceRangePrecision, Elibri::ONIX::Dict::Release_3_0::AudienceRangePrecision::FROM)
|
469
|
-
tag(:AudienceRangeValue, product.audience_age_from)
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
if product.audience_age_to.present?
|
474
|
-
tag(:AudienceRange) do
|
475
|
-
comment "Ograniczenie dotyczy wieku czytelnika - zawsze #{Elibri::ONIX::Dict::Release_3_0::AudienceRangeQualifier::READING_AGE}", :kind => :onix_audience_range
|
476
|
-
tag(:AudienceRangeQualifier, Elibri::ONIX::Dict::Release_3_0::AudienceRangeQualifier::READING_AGE)
|
477
|
-
comment "Wiek do #{product.audience_age_to} lat", :kind => :onix_audience_range
|
478
|
-
tag(:AudienceRangePrecision, Elibri::ONIX::Dict::Release_3_0::AudienceRangePrecision::TO)
|
479
|
-
tag(:AudienceRangeValue, product.audience_age_to)
|
480
|
-
end
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
|
485
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier DescriptiveDetail
|
486
|
-
# @title Informacje o wydawcy
|
487
|
-
# W rekordzie znajduje się oczywiście nazwa wydawnictwa. Wydawca może określić też imprint.
|
488
|
-
# Z imprintem mamy do czynienia wtedy, gdy książki są wydawane pod różnymi markami, pula ISBN jest jednak wspólna.
|
489
|
-
# Jeśli wydawnictwo uzupełnia nazwę imprintu, to powinna być ona traktowana jako nazwa wydawnictwa przy prezentacji
|
490
|
-
# książki klientowi końcowemu.
|
491
|
-
def export_publisher_info!(product)
|
492
|
-
if product.imprint
|
493
|
-
tag(:Imprint) do
|
494
|
-
comment "Nazwa imprintu", :kind => :onix_publisher_info
|
495
|
-
tag(:ImprintName, product.imprint.name)
|
496
|
-
end
|
497
|
-
end
|
498
|
-
|
499
|
-
if product.publisher_name
|
500
|
-
tag(:Publisher) do
|
501
|
-
comment "Wydawca - używamy tylko kodu 01 (główny wydawca)", :kind => :onix_publisher_info
|
502
|
-
tag(:PublishingRole, '01') # Publisher, lista 45 #TODO jeszcze może być współwydawca
|
503
|
-
tag(:PublisherIdentifier) do
|
504
|
-
tag(:PublisherIDType, '01') #prioprietary
|
505
|
-
tag(:IDTypeName, 'ElibriPublisherCode')
|
506
|
-
tag(:IDValue, product.publisher_id)
|
507
|
-
end
|
508
|
-
tag(:PublisherName, product.publisher_name)
|
509
|
-
end
|
510
|
-
end
|
511
|
-
end
|
512
|
-
|
513
|
-
|
514
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier ProductComposition ProductForm TitleDetail
|
515
|
-
# @title Pozostałe atrybuty
|
516
|
-
# Dodatkowo każdy produkt może mieć kilka dodatkowych atrybutów: wielkość pliku (w Mb, tylko e-book),
|
517
|
-
# czas trwania (tylko audiobook, w minutach), ilość stron, ilość ilustracji.
|
518
|
-
#
|
519
|
-
# Poniżej przykład dla e-booka (wielkość pliku, ilość stron i ilustracji)
|
520
|
-
# @render onix_ebook_extent_example
|
521
|
-
#
|
522
|
-
# I przykład dla audiobook-a, z czasem trwania nagrania:
|
523
|
-
# @render onix_audiobook_extent_example
|
524
|
-
def export_extent!(product)
|
525
|
-
if product.kind_of_ebook? and product.file_size
|
526
|
-
tag(:Extent) do
|
527
|
-
comment 'Rozmiar pliku (w MB) - tylko dla produktów typu e-book', :kind => :onix_extent
|
528
|
-
tag(:ExtentType, Elibri::ONIX::Dict::Release_3_0::ExtentType::FILE_SIZE)
|
529
|
-
tag(:ExtentValue, product.file_size)
|
530
|
-
comment 'W MB', :kind => :onix_extent
|
531
|
-
tag(:ExtentUnit, Elibri::ONIX::Dict::Release_3_0::ExtentUnit::MEGABYTES)
|
532
|
-
end
|
533
|
-
end
|
534
|
-
|
535
|
-
if product.kind_of_audio? and product.duration
|
536
|
-
tag(:Extent) do
|
537
|
-
comment 'Czas trwania (w minutach) - tylko dla produktów typu audio', :kind => :onix_extent
|
538
|
-
tag(:ExtentType, Elibri::ONIX::Dict::Release_3_0::ExtentType::DURATION)
|
539
|
-
tag(:ExtentValue, product.duration)
|
540
|
-
comment 'W minutach', :kind => :onix_extent
|
541
|
-
tag(:ExtentUnit, Elibri::ONIX::Dict::Release_3_0::ExtentUnit::MINUTES)
|
542
|
-
end
|
543
|
-
end
|
544
|
-
|
545
|
-
if (product.kind_of_book? or product.kind_of_ebook?) && product.number_of_pages #number_of_pages to int
|
546
|
-
tag(:Extent) do
|
547
|
-
comment 'Liczba stron - tylko dla produktów typu książka', :kind => :onix_extent
|
548
|
-
tag(:ExtentType, Elibri::ONIX::Dict::Release_3_0::ExtentType::PAGE_COUNT)
|
549
|
-
tag(:ExtentValue, product.number_of_pages)
|
550
|
-
tag(:ExtentUnit, Elibri::ONIX::Dict::Release_3_0::ExtentUnit::PAGES)
|
551
|
-
end
|
552
|
-
end
|
553
|
-
|
554
|
-
if (product.kind_of_book? or product.kind_of_ebook?) and product.number_of_illustrations
|
555
|
-
comment 'Liczba ilustracji - tylko dla produktów typu książka', :kind => :onix_extent
|
556
|
-
tag(:NumberOfIllustrations, product.number_of_illustrations)
|
557
|
-
end
|
558
|
-
end
|
559
|
-
|
560
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier ProductComposition ProductForm TitleDetail
|
561
|
-
# @title Kategorie
|
562
|
-
# eLibri stosuje wewnętrzną hierarchę kategorii, dostępną w formacie JSON pod adresem
|
563
|
-
# = link_to product_categories_json_url, product_categories_json_url
|
564
|
-
def export_subjects!(product)
|
565
|
-
if product.elibri_product_categories.present? or product.publisher_product_categories.present?
|
566
|
-
comment 'Stosujemy wewnętrzną kategoryzację. Lista kategorii Elibri w formacie JSON: http://www.elibri.com.pl/assets/product_categories.js'
|
567
|
-
end
|
568
|
-
|
569
|
-
# Kategorie wg. eLibri
|
570
|
-
product.elibri_product_categories.each_with_index do |product_category,i|
|
571
|
-
tag(:Subject) do
|
572
|
-
tag(:MainSubject) if i.zero?
|
573
|
-
tag(:SubjectSchemeIdentifier, Elibri::ONIX::Dict::Release_3_0::SubjectSchemeIdentifier::PROPRIETARY)
|
574
|
-
tag(:SubjectSchemeName, 'elibri.com.pl')
|
575
|
-
tag(:SubjectSchemeVersion, '1.0')
|
576
|
-
tag(:SubjectCode, product_category.id)
|
577
|
-
tag(:SubjectHeadingText, product_category.full_node_path_name)
|
578
|
-
end
|
579
|
-
end
|
580
|
-
|
581
|
-
# Kategorie wg. wydawnictwa
|
582
|
-
product.publisher_product_categories.each do |product_category|
|
583
|
-
tag(:Subject) do
|
584
|
-
tag(:SubjectSchemeIdentifier, Elibri::ONIX::Dict::Release_3_0::SubjectSchemeIdentifier::PROPRIETARY)
|
585
|
-
tag(:SubjectSchemeName, product.publisher_name)
|
586
|
-
tag(:SubjectHeadingText, product_category.name)
|
587
|
-
end
|
588
|
-
end
|
589
|
-
end
|
590
|
-
|
591
|
-
|
592
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier ProductComposition ProductForm TitleDetail
|
593
|
-
# @title Autorzy, redaktorzy ...
|
594
|
-
# Każdy produkt może mieć wymienionych autorów, może być informacja, że jest to praca zbiorowa, produkt może nie mieć też żadnego autora (np. mapa)
|
595
|
-
#
|
596
|
-
#
|
597
|
-
# Każdy twórca ma przypisaną jedną z wielu ról (<ContributorRole>). W przypadku tłumacza dodawana jest informacja, z jakiego języka
|
598
|
-
# nastąpiło tłumaczenie (<FromLanguage>)
|
599
|
-
#
|
600
|
-
#
|
601
|
-
# W przypadku właściwego uzupełnienia danych w eLibri, system potrafi podzielić fragmenty personaliów
|
602
|
-
# autora i wyeksportować je w oddzielnych tagach ONIX. Rozróżniane są następujące fragmenty: tytuł naukowy (<TitlesBeforeNames>),
|
603
|
-
# imię (<NamesBeforeKey>), prefix nazwiska (von, van - <PrefixToKey>), nazwisko (<KeyNames>),
|
604
|
-
# postfix nazwiska (najczęściej określenie zakonu, np. OP - <NamesAfterKey>).
|
605
|
-
# Zawsze jest jednak exportowane pełne brzemienie imienia i nazwiska (<PersonName>)
|
606
|
-
#
|
607
|
-
#
|
608
|
-
# Zdarzają się również przypadki, gdzie wyżej podany podział nie jest albo znany, albo możliwy (np. św. Tomasz z Akwinu), wtedy
|
609
|
-
# exportowany jest tylko tag <PersonName>
|
610
|
-
#
|
611
|
-
# Jeśli wydawnictwo uzupełniło biogram autora, to jest on dostępny w tagu <BiographicalNote>
|
612
|
-
#
|
613
|
-
# @render onix_contributors_example
|
614
|
-
#
|
615
|
-
# W przypadku pracy zbiorowej rekord wygląda następująco:
|
616
|
-
#
|
617
|
-
# @render onix_collective_work_example
|
618
|
-
#
|
619
|
-
# Jeśli produkt nie ma żadnego autora, użyty zostaje tag <NoContributor>
|
620
|
-
#
|
621
|
-
# @render onix_no_contributors_example
|
622
|
-
#
|
623
|
-
#
|
624
|
-
def export_contributors!(product)
|
625
|
-
if product.authorship_kind.user_given?
|
626
|
-
comment 'Gdy wyszczególniono autorów', :kind => :onix_contributors if product.contributors.present?
|
627
|
-
product.contributors.each_with_index do |contributor, idx|
|
628
|
-
tag(:Contributor, :sourcename => "contributorid:#{contributor.id}", :datestamp => contributor.updated_at.to_s(:onix)) do
|
629
|
-
tag(:SequenceNumber, idx + 1)
|
630
|
-
comment_dictionary 'Rola autora', :ContributorRole, :indent => 10, :kind => :onix_contributors
|
631
|
-
tag(:ContributorRole, contributor.role_onix_code) #lista 17
|
632
|
-
comment 'Tylko w przypadku tłumaczy:', :kind => :onix_contributors
|
633
|
-
tag(:FromLanguage, contributor.language_onix_code) if contributor.language_onix_code
|
634
|
-
tag(:PersonName, contributor.generated_full_name) #zawsze jest TODO - dodać takie pole do bazy danych
|
635
|
-
|
636
|
-
tag(:TitlesBeforeNames, contributor.title) if contributor.title.present? #tytuł
|
637
|
-
tag(:NamesBeforeKey, contributor.name) if contributor.name.present? #imię
|
638
|
-
tag(:PrefixToKey, contributor.last_name_prefix) if contributor.last_name_prefix.present? #van, von
|
639
|
-
tag(:KeyNames, contributor.last_name) if contributor.last_name.present?
|
640
|
-
tag(:NamesAfterKey, contributor.last_name_postfix) if contributor.last_name_postfix.present?
|
641
|
-
tag(:BiographicalNote, contributor.biography.text) if contributor.biography
|
642
|
-
end
|
643
|
-
end
|
644
|
-
end
|
645
|
-
|
646
|
-
if product.authorship_kind.collective?
|
647
|
-
comment 'Gdy jest to praca zbiorowa', :kind => :onix_contributors
|
648
|
-
tag(:Contributor) do
|
649
|
-
comment "Autor - #{Elibri::ONIX::Dict::Release_3_0::ContributorRole::AUTHOR}", :kind => :onix_contributors
|
650
|
-
tag(:ContributorRole, Elibri::ONIX::Dict::Release_3_0::ContributorRole::AUTHOR)
|
651
|
-
comment "Różne osoby - #{Elibri::ONIX::Dict::Release_3_0::UnnamedPersons::VARIOUS_AUTHORS}", :kind => :onix_contributors
|
652
|
-
tag(:UnnamedPersons, Elibri::ONIX::Dict::Release_3_0::UnnamedPersons::VARIOUS_AUTHORS)
|
653
|
-
end
|
654
|
-
end
|
655
|
-
|
656
|
-
if product.authorship_kind.no_contributor?
|
657
|
-
comment 'Gdy brak autorów', :kind => :onix_contributors
|
658
|
-
tag(:NoContributor)
|
659
|
-
end
|
660
|
-
end
|
661
|
-
|
662
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier ProductComposition ProductForm
|
663
|
-
# @title Tytuły
|
664
|
-
# W dokumencie XML mogą pojawić się 3 typy tytułu: pełen tytuł produktu, tytuł w języku oryginału (jeśli jest tłumaczeniem)
|
665
|
-
# oraz roboczy tytuł nadany przez wydawcę.
|
666
|
-
# @render onix_titles_example
|
667
|
-
#
|
668
|
-
# Tytuł może być też kaskadowy. Dobrym przykładem jest na przykład Thorgal, komiks, który ma wiele tomów, każdy tom ma swój numer, jak i tytuł.
|
669
|
-
# W kategoriach ONIX-a Thorgal jest kolekcją. Od serii odróżnia go to, że jest częścią tytułu. Innym dobrym przykładem jest książka "Gra o Tron",
|
670
|
-
# która należy do kolekcji "Pieśń Lodu i Ognia" - ponieważ jest to częścią tytułu.
|
671
|
-
# @render onix_title_with_collection_example
|
672
|
-
#
|
673
|
-
#
|
674
|
-
def export_titles!(product)
|
675
|
-
if product.title_parts.present? or product.or_title.present? or product.trade_title.present?
|
676
|
-
#comment_dictionary 'Rozróżniane typy tytułów', :TitleType, :indent => 10, :kind => :onix_titles
|
677
|
-
end
|
678
|
-
|
679
|
-
if product.title_parts.present?
|
680
|
-
tag(:TitleDetail) do
|
681
|
-
comment "Pełen tytuł produktu - #{Elibri::ONIX::Dict::Release_3_0::TitleType::DISTINCTIVE_TITLE}", :kind => :onix_titles
|
682
|
-
tag(:TitleType, Elibri::ONIX::Dict::Release_3_0::TitleType::DISTINCTIVE_TITLE)
|
683
|
-
product.title_parts.each do |title_part|
|
684
|
-
tag(:TitleElement) do
|
685
|
-
if title_part.level == Elibri::ONIX::Dict::Release_3_0::TitleElementLevel::PRODUCT
|
686
|
-
comment "Tytuł na poziomie produktu - #{Elibri::ONIX::Dict::Release_3_0::TitleElementLevel::PRODUCT}", :kind => :onix_titles
|
687
|
-
elsif title_part.level == Elibri::ONIX::Dict::Release_3_0::TitleElementLevel::COLLECTION
|
688
|
-
comment "Tytuł na poziomie kolekcji - #{Elibri::ONIX::Dict::Release_3_0::TitleElementLevel::COLLECTION}", :kind => :onix_titles
|
689
|
-
end
|
690
|
-
tag(:TitleElementLevel, title_part.level) #odnosi się do tego produktu tylko
|
691
|
-
tag(:PartNumber, title_part.part) if title_part.part.present?
|
692
|
-
tag(:TitleText, title_part.title) if title_part.title.present?
|
693
|
-
tag(:Subtitle, title_part.subtitle) if title_part.subtitle.present?
|
694
|
-
end
|
695
|
-
end
|
696
|
-
end
|
697
|
-
end
|
698
|
-
if product.or_title.present?
|
699
|
-
tag(:TitleDetail) do
|
700
|
-
comment "Tytuł w języku oryginału - #{Elibri::ONIX::Dict::Release_3_0::TitleType::DISTINCTIVE_TITLE}", :kind => :onix_titles
|
701
|
-
tag(:TitleType, Elibri::ONIX::Dict::Release_3_0::TitleType::ORIGINAL_TITLE)
|
702
|
-
tag(:TitleElement) do
|
703
|
-
comment "Tytuł na poziomie produktu - #{Elibri::ONIX::Dict::Release_3_0::TitleElementLevel::PRODUCT}", :kind => :onix_titles
|
704
|
-
tag(:TitleElementLevel, Elibri::ONIX::Dict::Release_3_0::TitleElementLevel::PRODUCT)
|
705
|
-
tag(:TitleText, product.or_title)
|
706
|
-
end
|
707
|
-
end
|
708
|
-
end
|
709
|
-
if product.trade_title.present?
|
710
|
-
tag(:TitleDetail) do
|
711
|
-
comment "Tytuł handlowy używany przez wydawnictwo - #{Elibri::ONIX::Dict::Release_3_0::TitleType::DISTRIBUTORS_TITLE}", :kind => :onix_titles
|
712
|
-
tag(:TitleType, Elibri::ONIX::Dict::Release_3_0::TitleType::DISTRIBUTORS_TITLE) #tytuł produktu
|
713
|
-
tag(:TitleElement) do
|
714
|
-
comment "Tytuł na poziomie produktu - #{Elibri::ONIX::Dict::Release_3_0::TitleElementLevel::PRODUCT}", :kind => :onix_titles
|
715
|
-
tag(:TitleElementLevel, Elibri::ONIX::Dict::Release_3_0::TitleElementLevel::PRODUCT)
|
716
|
-
tag(:TitleText, product.trade_title)
|
717
|
-
end
|
718
|
-
end
|
719
|
-
end
|
720
|
-
end
|
721
|
-
|
722
|
-
|
723
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier ProductComposition ProductForm TitleDetail
|
724
|
-
# @title Opis wydania
|
725
|
-
def export_edition!(product)
|
726
|
-
if product.edition_statement.present?
|
727
|
-
comment 'Opis wydania', :kind => :onix_edition
|
728
|
-
tag(:EditionStatement, product.edition_statement)
|
729
|
-
end
|
730
|
-
end
|
731
|
-
|
732
|
-
|
733
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier ProductComposition ProductForm TitleDetail
|
734
|
-
# @title Języki
|
735
|
-
# Języki, w których dostępny jest produkt.
|
736
|
-
def export_languages!(product)
|
737
|
-
comment_dictionary 'Rola języka', :LanguageRole, :indent => 10, :kind => :onix_languages if product.languages.present?
|
738
|
-
product.languages.each do |language|
|
739
|
-
tag(:Language) do
|
740
|
-
tag(:LanguageRole, language.role_onix_code) #lista 22
|
741
|
-
tag(:LanguageCode, language.language_onix_code) #lista 74
|
742
|
-
end
|
743
|
-
end
|
744
|
-
end
|
745
|
-
|
746
|
-
|
747
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier DescriptiveDetail
|
748
|
-
# @title Teksty
|
749
|
-
# Wydawca może wprowadzić do eLibri różne informacje tekstowe - opis produktu, spis treści, recenzję (jeśli ma prawa ją udostępnić), jak i fragment książki.
|
750
|
-
# Biogramy autorów są udostępniane wraz z informacjami o
|
751
|
-
# = link_to "autorach", doc_api_path("onix_contributors")
|
752
|
-
def export_texts!(product)
|
753
|
-
comment_dictionary 'Typy tekstów', :OtherTextType, :indent => 10, :kind => :onix_texts if product.other_texts.present?
|
754
|
-
product.other_texts.each do |other_text|
|
755
|
-
#jeśli jest pusty tekst, nie nadaje się do umieszczania w ONIX albo tekst dotyczy autora (type_onix_code.blank?) -> nie exportuj
|
756
|
-
next if other_text.text.blank? || other_text.type_onix_code.blank? || !other_text.exportable?
|
757
|
-
|
758
|
-
tag(:TextContent, :sourcename => "textid:#{other_text.id}", :datestamp => other_text.updated_at.to_s(:onix)) do
|
759
|
-
tag(:TextType, other_text.type_onix_code) #lista 153
|
760
|
-
comment "Zawsze #{Elibri::ONIX::Dict::Release_3_0::ContentAudience::UNRESTRICTED} - Unrestricted", :kind => :onix_texts
|
761
|
-
tag(:ContentAudience, Elibri::ONIX::Dict::Release_3_0::ContentAudience::UNRESTRICTED)
|
762
|
-
|
763
|
-
if other_text.is_a_review? && other_text.resource_link.present?
|
764
|
-
text_source = {:sourcename => other_text.resource_link}
|
765
|
-
else
|
766
|
-
text_source = {}
|
767
|
-
end
|
768
|
-
|
769
|
-
tag(:Text, text_source) do |builder|
|
770
|
-
builder.cdata!(other_text.text)
|
771
|
-
end
|
772
|
-
|
773
|
-
tag(:TextAuthor, other_text.text_author) if other_text.text_author.present?
|
774
|
-
tag(:SourceTitle, other_text.source_title) if other_text.source_title.present?
|
775
|
-
end
|
776
|
-
end
|
777
|
-
end
|
778
|
-
|
779
|
-
|
780
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier DescriptiveDetail
|
781
|
-
# @title Załączniki
|
782
|
-
# Wydawca może załączyć do każdego produktu dowolną liczbę plików - a przynajmniej jeden, okładkę. Proszę za każdym razem
|
783
|
-
# tworzyć kopię pliku na swoim serwerze, hotlinking jest niedozwolony.
|
784
|
-
def export_supporting_resources!(product)
|
785
|
-
product.attachments.each do |attachment|
|
786
|
-
if attachment.onix_resource_mode #jeśli klient coś dzikiego wgrał, to ignoruj to
|
787
|
-
tag(:SupportingResource, :sourcename => "resourceid:#{attachment.id}", :datestamp => attachment.updated_at.to_s(:onix)) do
|
788
|
-
comment_dictionary 'Typ załącznika', :ResourceContentType, :indent => 12, :kind => :onix_supporting_resources
|
789
|
-
tag(:ResourceContentType, attachment.attachment_type_code) #lista 158
|
790
|
-
comment 'Zawsze 00 - Unrestricted', :kind => :onix_supporting_resources
|
791
|
-
tag(:ContentAudience, Elibri::ONIX::Dict::Release_3_0::ContentAudience::UNRESTRICTED)
|
792
|
-
comment_dictionary 'Rodzaj załącznika', :ResourceMode, :indent => 12, :kind => :onix_supporting_resources
|
793
|
-
tag(:ResourceMode, attachment.onix_resource_mode) #lista 159
|
794
|
-
tag(:ResourceVersion) do
|
795
|
-
comment 'Zawsze 02 - Downloadable file', :kind => :onix_supporting_resources
|
796
|
-
tag(:ResourceForm, Elibri::ONIX::Dict::Release_3_0::ResourceForm::DOWNLOADABLE_FILE)
|
797
|
-
url = attachment.file.url
|
798
|
-
if url.index("http://") #w sklepie zwraca mi całego linka, wygodniej mi jest to tutaj wychwycić
|
799
|
-
tag(:ResourceLink, URI.escape(url))
|
800
|
-
else
|
801
|
-
tag(:ResourceLink, URI.escape('http://' + HOST_NAME + url))
|
802
|
-
end
|
803
|
-
end
|
804
|
-
end
|
805
|
-
end
|
806
|
-
end
|
807
|
-
end
|
808
|
-
|
809
|
-
|
810
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier ProductComposition ProductForm
|
811
|
-
# @title Serie wydawnicze
|
812
|
-
# Serie wydawnicze są opisywane w podobny sposób co tytuł, zawarte są jednak w tagu <strong><Collection></strong>
|
813
|
-
# Struktura jest dosyć zawiła, ale wszystkie wartości są sztywne, więc nie powinno być problemu z odczytaniem informacji.
|
814
|
-
# Oprócz nazwy serii może zostać również podany numer wewnątrz serii, jeśli seria jest numerowana.
|
815
|
-
# Książka może należeć do kilku serii, wtedy tag <strong><Collection></strong> występuje kilkukrotnie.
|
816
|
-
def export_series_memberships!(product)
|
817
|
-
if product.series_membership_kind.user_given?
|
818
|
-
product.series_memberships.each_with_index do |series_membership, idx|
|
819
|
-
tag(:Collection) do
|
820
|
-
comment "Używamy tylko #{Elibri::ONIX::Dict::Release_3_0::CollectionType::PUBLISHER_COLLECTION} - seria wydawnictwa", :kind => :onix_series_memberships
|
821
|
-
tag(:CollectionType, Elibri::ONIX::Dict::Release_3_0::CollectionType::PUBLISHER_COLLECTION) #lista 148
|
822
|
-
comment "Teraz następuje podobna struktura, jak w przypadku tytułu", :kind => :onix_series_memberships
|
823
|
-
tag(:TitleDetail) do
|
824
|
-
comment "Używamy tylko #{Elibri::ONIX::Dict::Release_3_0::TitleType::DISTINCTIVE_TITLE}", :kind => :onix_series_memberships
|
825
|
-
tag(:TitleType, Elibri::ONIX::Dict::Release_3_0::TitleType::DISTINCTIVE_TITLE)
|
826
|
-
tag(:TitleElement) do
|
827
|
-
comment "Używamy tylko #{Elibri::ONIX::Dict::Release_3_0::TitleElementLevel::COLLECTION}", :kind => :onix_series_memberships
|
828
|
-
tag(:TitleElementLevel, Elibri::ONIX::Dict::Release_3_0::TitleElementLevel::COLLECTION)
|
829
|
-
tag(:PartNumber, series_membership.number_within_series) if series_membership.number_within_series.present?
|
830
|
-
tag(:TitleText, series_membership.series_name)
|
831
|
-
end
|
832
|
-
end
|
833
|
-
end
|
834
|
-
end
|
835
|
-
end
|
836
|
-
end
|
837
|
-
|
838
|
-
|
839
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier DescriptiveDetail
|
840
|
-
# @title Powiązane produkty
|
841
|
-
def export_related_products!(product)
|
842
|
-
tag(:RelatedMaterial) do
|
843
|
-
|
844
|
-
comment_dictionary "Typy relacji", :ProductRelationType, :indent => 10, :kind => :onix_related_products
|
845
|
-
product.facsimiles.each do |facsimile|
|
846
|
-
tag(:RelatedProduct) do
|
847
|
-
tag(:ProductRelationCode, Elibri::ONIX::Dict::Release_3_0::ProductRelationType::FACSIMILES)
|
848
|
-
tag(:ProductIdentifier) do
|
849
|
-
comment "Zawsze #{Elibri::ONIX::Dict::Release_3_0::ProductIDType::PROPRIETARY} - symbol wydawcy", :kind => :onix_related_products
|
850
|
-
tag(:ProductIDType, Elibri::ONIX::Dict::Release_3_0::ProductIDType::PROPRIETARY)
|
851
|
-
tag(:IDTypeName, facsimile.publisher_name)
|
852
|
-
tag(:IDValue, facsimile.publisher_symbol)
|
853
|
-
end
|
854
|
-
|
855
|
-
if facsimile.isbn_value.present?
|
856
|
-
tag(:ProductIdentifier) do
|
857
|
-
comment 'Zawsze ISBN-13'
|
858
|
-
tag(:ProductIDType, Elibri::ONIX::Dict::Release_3_0::ProductIDType::ISBN13)
|
859
|
-
tag(:IDValue, facsimile.isbn_value)
|
860
|
-
end
|
861
|
-
end
|
862
|
-
end
|
863
|
-
end
|
864
|
-
|
865
|
-
# Nie powtarzaj w zbiorze produktów podobnych faksymili:
|
866
|
-
(product.similar_products - product.facsimiles).each do |similar_product|
|
867
|
-
tag(:RelatedProduct) do
|
868
|
-
tag(:ProductRelationCode, Elibri::ONIX::Dict::Release_3_0::ProductRelationType::SIMILAR_PRODUCTS)
|
869
|
-
tag(:ProductIdentifier) do
|
870
|
-
comment "Zawsze #{Elibri::ONIX::Dict::Release_3_0::ProductIDType::PROPRIETARY} - symbol wydawcy"
|
871
|
-
tag(:ProductIDType, Elibri::ONIX::Dict::Release_3_0::ProductIDType::PROPRIETARY)
|
872
|
-
tag(:IDTypeName, similar_product.publisher_name)
|
873
|
-
tag(:IDValue, similar_product.publisher_symbol)
|
874
|
-
end
|
875
|
-
|
876
|
-
if similar_product.isbn_value.present?
|
877
|
-
tag(:ProductIdentifier) do
|
878
|
-
tag(:ProductIDType, Elibri::ONIX::Dict::Release_3_0::ProductIDType::ISBN13)
|
879
|
-
tag(:IDValue, similar_product.isbn_value)
|
880
|
-
end
|
881
|
-
end
|
882
|
-
end
|
883
|
-
end
|
884
|
-
|
885
|
-
end
|
886
|
-
end
|
887
|
-
|
888
|
-
|
889
|
-
# @hidden_tags RecordReference NotificationType DescriptiveDetail Supplier ProductAvailability Price
|
890
|
-
# @title Stany magazynowe
|
891
|
-
# Tag <strong><Stock></strong> może zawierać konkretną ilość produktu w <strong><OnHand></strong>,
|
892
|
-
# lub słownie określoną ilość w <strong><StockQuantityCoded></strong>.<br/><br/>
|
893
|
-
# Dokument XML zawierający dane o stanach magazynowych produktu najczęściej zawiera także rozszerzoną listę
|
894
|
-
# identyfikatorów produktu. Poza podstawowym <strong><ProductIdentifier></strong>, znajdują się także identyfikatory
|
895
|
-
# poszczególnych dostawców. Tag <strong><IDTypeName></strong> zawiera nazwę dostawcy.
|
896
|
-
def export_supply_details!(product)
|
897
|
-
return if product.try(:skip_ProductSupply)
|
898
|
-
unless product.product_availabilities.empty?
|
899
|
-
tag(:ProductSupply) do
|
900
|
-
product.product_availabilities.each do |pa|
|
901
|
-
tag(:SupplyDetail) do
|
902
|
-
tag(:Supplier) do
|
903
|
-
comment_dictionary "Rola dostawcy", :SupplierRole, :indent => 12
|
904
|
-
tag(:SupplierRole, pa.supplier_role_onix_code) #lista 93
|
905
|
-
tag(:SupplierIdentifier) do
|
906
|
-
comment "Zawsze 02 - Proprietary. Identyfikujemy dostawcę po NIP"
|
907
|
-
tag(:SupplierIDType, '02') #lista 92, Proprietary
|
908
|
-
tag(:IDTypeName, 'NIP')
|
909
|
-
tag(:IDValue, pa.supplier.nip.gsub("-", ""))
|
910
|
-
end
|
911
|
-
tag(:SupplierName, pa.supplier.name)
|
912
|
-
tag(:TelephoneNumber, pa.supplier.phone) if pa.supplier.phone.present?
|
913
|
-
tag(:EmailAddress, pa.supplier.email) if pa.supplier.email.present?
|
914
|
-
if pa.supplier.website.present?
|
915
|
-
tag(:Website) do
|
916
|
-
tag(:WebsiteLink, pa.supplier.website)
|
917
|
-
end
|
918
|
-
end
|
919
|
-
end
|
920
|
-
|
921
|
-
comment_dictionary "Typ dostępności", :ProductAvailabilityType, :indent => 10
|
922
|
-
tag(:ProductAvailability, pa.product_availability_onix_code) #lista 65
|
923
|
-
if pa.stock_info
|
924
|
-
tag(:Stock) do
|
925
|
-
if pa.stock_info.exact_info?
|
926
|
-
tag(:OnHand, pa.stock_info.on_hand)
|
927
|
-
else
|
928
|
-
comment 'Nie znamy konkretnej ilości produktów na stanie'
|
929
|
-
tag(:StockQuantityCoded) do
|
930
|
-
comment 'Zawsze 01 - Proprietary'
|
931
|
-
tag(:StockQuantityCodeType, '01') #lista 70 - proprietary
|
932
|
-
tag(:StockQuantityCode, pa.stock_info.quantity_code) #low/high
|
933
|
-
end
|
934
|
-
end
|
935
|
-
end
|
936
|
-
end
|
937
|
-
if product.pack_quantity.present?
|
938
|
-
comment 'Ile produktów dostawca umieszcza w paczce'
|
939
|
-
tag(:PackQuantity, product.pack_quantity)
|
940
|
-
end
|
941
|
-
|
942
|
-
pa.price_infos.each do |price_info|
|
943
|
-
tag(:Price) do
|
944
|
-
comment_dictionary "Typ ceny", :PriceTypeCode, :indent => 12
|
945
|
-
tag(:PriceType, Elibri::ONIX::Dict::Release_3_0::PriceTypeCode::RRP_WITH_TAX) #lista 58
|
946
|
-
tag(:MinimumOrderQuantity, price_info.minimum_order_quantity) if price_info.minimum_order_quantity
|
947
|
-
tag(:PriceAmount, price_info.amount)
|
948
|
-
tag(:Tax) do
|
949
|
-
comment 'VAT'
|
950
|
-
tag(:TaxType, '01') #lista 174, VAT
|
951
|
-
tag(:TaxRatePercent, price_info.vat)
|
952
|
-
end
|
953
|
-
tag(:CurrencyCode, price_info.currency_code)
|
954
|
-
if product.price_printed_on_product_onix_code.present?
|
955
|
-
comment_dictionary "Cena na okładce?", :PricePrintedOnProduct, :indent => 12
|
956
|
-
tag(:PrintedOnProduct, product.price_printed_on_product_onix_code) #lista 174
|
957
|
-
comment 'Zawsze 00 - Unknown / unspecified'
|
958
|
-
tag(:PositionOnProduct, '00') #lista 142 - Position unknown or unspecified
|
959
|
-
end
|
960
|
-
end
|
961
|
-
end
|
962
|
-
end
|
963
|
-
end
|
964
|
-
end
|
965
|
-
end
|
966
|
-
end
|
967
|
-
|
968
|
-
|
969
|
-
# @title Rozszerzenia eLibri dla ONIX
|
970
|
-
# @hidden_tags RecordReference NotificationType ProductIdentifier DescriptiveDetail
|
971
|
-
# Standard ONIX nie przewiduje w chwili obecnej atrybutów produktów niezbędnych z punktu widzenia polskiego rynku wydawniczego.
|
972
|
-
# Są to atrybuty takie jak np. Vat czy PKWiU. eLibri rozszerza więc ONIX o kilka użytecznych tagów, wprowadzając nową przestrzeń nazw
|
973
|
-
# w generowanych XML`ach.
|
974
|
-
def export_elibri_extensions!(product)
|
975
|
-
if @elibri_onix_dialect >= '3.0.1'
|
976
|
-
|
977
|
-
if product.cover_type
|
978
|
-
comment_dictionary "Format okładki", Product::CoverType.all.map(&:name), :indent => 10
|
979
|
-
tag("elibri:CoverType", product.cover_type.name)
|
980
|
-
end
|
981
|
-
|
982
|
-
comment 'Cena na okładce'
|
983
|
-
tag("elibri:CoverPrice", product.price_amount) if product.price_amount.present?
|
984
|
-
comment 'Vat w procentach'
|
985
|
-
tag("elibri:Vat", product.vat) if product.vat.present?
|
986
|
-
tag("elibri:PKWiU", product.pkwiu) if product.pkwiu.present?
|
987
|
-
tag("elibri:preview_exists", product.preview_exists?.to_s)
|
988
|
-
end
|
989
|
-
end
|
990
|
-
|
4
|
+
include Elibri::ONIX::Generator
|
991
5
|
end
|
992
|
-
|
993
6
|
end
|
994
|
-
|
995
7
|
end
|