nti_receipt_builder 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +21 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +272 -0
- data/Rakefile +12 -0
- data/app/assets/javascripts/nti_receipt_builder/index.js +16 -0
- data/app/assets/javascripts/nti_receipt_builder/receipt_builder_controller.js +297 -0
- data/app/assets/javascripts/nti_receipt_builder/receipt_canvas_controller.js +279 -0
- data/app/assets/javascripts/nti_receipt_builder/receipt_draggable_controller.js +154 -0
- data/app/assets/javascripts/nti_receipt_builder/receipt_print_controller.js +24 -0
- data/app/assets/javascripts/nti_receipt_builder/receipt_properties_controller.js +297 -0
- data/app/assets/stylesheets/nti_receipt_builder.css +238 -0
- data/app/controllers/concerns/nti_receipt_builder/templates_controller.rb +170 -0
- data/app/helpers/nti_receipt_builder/render_helper.rb +21 -0
- data/app/models/nti_receipt_builder/template.rb +79 -0
- data/app/views/nti_receipt_builder/render/_order_lines_element.html.erb +36 -0
- data/app/views/nti_receipt_builder/render/_overflow_banner.html.erb +5 -0
- data/app/views/nti_receipt_builder/render/_paper.html.erb +12 -0
- data/app/views/nti_receipt_builder/render/_text_element.html.erb +1 -0
- data/app/views/nti_receipt_builder/render/_variable_element.html.erb +1 -0
- data/app/views/nti_receipt_builder/templates/_canvas.html.erb +33 -0
- data/app/views/nti_receipt_builder/templates/_elements_panel.html.erb +49 -0
- data/app/views/nti_receipt_builder/templates/_errors.html.erb +21 -0
- data/app/views/nti_receipt_builder/templates/_lock_version_field.html.erb +2 -0
- data/app/views/nti_receipt_builder/templates/_print_assets.html.erb +15 -0
- data/app/views/nti_receipt_builder/templates/_properties_panel.html.erb +8 -0
- data/app/views/nti_receipt_builder/templates/_settings_panel.html.erb +130 -0
- data/app/views/nti_receipt_builder/templates/create.turbo_stream.erb +3 -0
- data/app/views/nti_receipt_builder/templates/edit.html.erb +54 -0
- data/app/views/nti_receipt_builder/templates/new.html.erb +115 -0
- data/app/views/nti_receipt_builder/templates/preview.html.erb +24 -0
- data/app/views/nti_receipt_builder/templates/print.html.erb +31 -0
- data/app/views/nti_receipt_builder/templates/render_preview.turbo_stream.erb +26 -0
- data/app/views/nti_receipt_builder/templates/update.turbo_stream.erb +7 -0
- data/config/importmap.rb +4 -0
- data/lib/generators/nti_receipt_builder/install_generator.rb +49 -0
- data/lib/generators/nti_receipt_builder/templates/create_nti_receipt_templates.rb +28 -0
- data/lib/generators/nti_receipt_builder/templates/initializer.rb +16 -0
- data/lib/generators/nti_receipt_builder/templates/turbo_stream_tags.rb +36 -0
- data/lib/nti_receipt_builder/configuration.rb +59 -0
- data/lib/nti_receipt_builder/elements.rb +46 -0
- data/lib/nti_receipt_builder/engine.rb +32 -0
- data/lib/nti_receipt_builder/errors.rb +13 -0
- data/lib/nti_receipt_builder/layout_validator.rb +285 -0
- data/lib/nti_receipt_builder/presenters/collection.rb +126 -0
- data/lib/nti_receipt_builder/presenters/element.rb +68 -0
- data/lib/nti_receipt_builder/render_result.rb +18 -0
- data/lib/nti_receipt_builder/renderer.rb +78 -0
- data/lib/nti_receipt_builder/set_default.rb +24 -0
- data/lib/nti_receipt_builder/template_form.rb +60 -0
- data/lib/nti_receipt_builder/type_inference.rb +26 -0
- data/lib/nti_receipt_builder/variable_definition.rb +74 -0
- data/lib/nti_receipt_builder/variable_resolver.rb +55 -0
- data/lib/nti_receipt_builder/variables.rb +159 -0
- data/lib/nti_receipt_builder/version.rb +5 -0
- data/lib/nti_receipt_builder.rb +50 -0
- metadata +175 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NtiReceiptBuilder
|
|
4
|
+
# One receipt placeholder: where its value comes from, how it is labelled, how it is
|
|
5
|
+
# formatted, and what stands in for it in the designer preview.
|
|
6
|
+
#
|
|
7
|
+
# Frozen on construction — these are read on every render and must never be mutated.
|
|
8
|
+
class VariableDefinition
|
|
9
|
+
DEFAULT_SAMPLE_ROW_COUNT = 3
|
|
10
|
+
# Matches the builder's default order_lines element width, so freshly dropped tables fill it.
|
|
11
|
+
DEFAULT_COLLECTION_WIDTH_MM = 60.0
|
|
12
|
+
DEFAULT_COLUMN_ALIGN = 'left'
|
|
13
|
+
|
|
14
|
+
attr_reader :key, :method_name, :label, :type, :columns
|
|
15
|
+
|
|
16
|
+
def initialize(key:, method_name:, label:, type: nil, sample: nil, columns: nil)
|
|
17
|
+
@key = -key.to_s
|
|
18
|
+
@method_name = -method_name.to_s
|
|
19
|
+
@label = -label.to_s
|
|
20
|
+
@type = type
|
|
21
|
+
@sample = sample
|
|
22
|
+
@columns = columns
|
|
23
|
+
freeze
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# A variable that declares `columns:` IS the collection — there is no separate marker.
|
|
27
|
+
def collection? = !@columns.nil?
|
|
28
|
+
|
|
29
|
+
def column_keys = collection? ? @columns.keys : []
|
|
30
|
+
|
|
31
|
+
def column_label(column_key)
|
|
32
|
+
@columns&.dig(column_key, :label) || column_key.to_s.titleize
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def column_type(column_key)
|
|
36
|
+
@columns&.dig(column_key, :type)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# The column set the builder uses when a designer drops a fresh table onto the canvas.
|
|
40
|
+
# Without this the builder would have to hardcode column keys, and any host whose columns
|
|
41
|
+
# differ would get a layout its own validator rejects.
|
|
42
|
+
def default_columns_config
|
|
43
|
+
return [] unless collection?
|
|
44
|
+
|
|
45
|
+
even_width_mm = (DEFAULT_COLLECTION_WIDTH_MM / column_keys.size).round(2)
|
|
46
|
+
|
|
47
|
+
column_keys.map do |column_key|
|
|
48
|
+
{
|
|
49
|
+
'key' => column_key,
|
|
50
|
+
'label' => column_label(column_key),
|
|
51
|
+
'width_mm' => @columns.dig(column_key, :width_mm) || even_width_mm,
|
|
52
|
+
'align' => @columns.dig(column_key, :align) || DEFAULT_COLUMN_ALIGN
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# The declared sample, or a derived stand-in. Only ever called on the preview path, so
|
|
58
|
+
# nothing is memoised — a frozen object cannot memoise, and previews are not hot.
|
|
59
|
+
def sample
|
|
60
|
+
declared = @sample.respond_to?(:call) ? @sample.call : @sample
|
|
61
|
+
return declared unless declared.nil?
|
|
62
|
+
|
|
63
|
+
collection? ? derived_collection_sample : label
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def derived_collection_sample
|
|
69
|
+
Array.new(DEFAULT_SAMPLE_ROW_COUNT) do |index|
|
|
70
|
+
column_keys.index_with { |column_key| "#{column_label(column_key)} #{index + 1}" }
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'action_view'
|
|
4
|
+
|
|
5
|
+
module NtiReceiptBuilder
|
|
6
|
+
# Resolves every scalar variable to a formatted (not yet escaped) string. Missing keys
|
|
7
|
+
# resolve to nil so presenters can apply their own fallback.
|
|
8
|
+
#
|
|
9
|
+
# A declared type wins; otherwise the value's class decides. Collection variables are
|
|
10
|
+
# skipped — the collection presenter formats its own cells.
|
|
11
|
+
class VariableResolver
|
|
12
|
+
include ActionView::Helpers::NumberHelper
|
|
13
|
+
|
|
14
|
+
def initialize(data, definitions:)
|
|
15
|
+
@data = data || {}
|
|
16
|
+
@definitions = definitions
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def call
|
|
20
|
+
definitions.each_with_object({}) do |(key, definition), resolved|
|
|
21
|
+
next if definition.collection?
|
|
22
|
+
|
|
23
|
+
resolved[key] = format_value(definition, data[key])
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
attr_reader :data, :definitions
|
|
30
|
+
|
|
31
|
+
def format_value(definition, value)
|
|
32
|
+
return nil if value.nil?
|
|
33
|
+
|
|
34
|
+
case definition.type || TypeInference.call(value)
|
|
35
|
+
when :currency then format_currency(value)
|
|
36
|
+
when :datetime then format_datetime(value)
|
|
37
|
+
else value.to_s
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def format_currency(value)
|
|
42
|
+
number_to_currency(value, unit: NtiReceiptBuilder.config.currency_unit)
|
|
43
|
+
rescue StandardError
|
|
44
|
+
nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def format_datetime(value)
|
|
48
|
+
return value.to_s unless value.respond_to?(:strftime)
|
|
49
|
+
|
|
50
|
+
value.strftime(NtiReceiptBuilder.config.datetime_format)
|
|
51
|
+
rescue StandardError
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NtiReceiptBuilder
|
|
4
|
+
# Base class for a host application's receipt variable vocabulary.
|
|
5
|
+
#
|
|
6
|
+
# class OrderReceiptVariables < NtiReceiptBuilder::Variables
|
|
7
|
+
# MAPPINGS = {
|
|
8
|
+
# 'ORDER_REFERENCE' => 'order_reference',
|
|
9
|
+
# 'STORE_NAME' => 'store_name'
|
|
10
|
+
# }.freeze
|
|
11
|
+
#
|
|
12
|
+
# def order_reference = receipt_object.reference
|
|
13
|
+
# def store_name = receipt_object.address.name
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# MAPPINGS supplies the placeholder keys and the method producing each value. Everything
|
|
17
|
+
# else — label, formatting type, preview sample — is derived, and overridden per key with
|
|
18
|
+
# `variable`. The key that declares `columns:` is the collection.
|
|
19
|
+
#
|
|
20
|
+
# The schema is built once on first read and frozen, so render-path reads take no lock.
|
|
21
|
+
# It is memoised on the subclass itself, so a host code reload discards it along with the
|
|
22
|
+
# class it describes — there is no separate cache to invalidate and nothing that outlives
|
|
23
|
+
# what it points at.
|
|
24
|
+
class Variables
|
|
25
|
+
Schema = Struct.new(:definitions, :labels, :scalar_keys, :collection_key, keyword_init: true)
|
|
26
|
+
private_constant :Schema
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
# Override any derived aspect of a key already present in MAPPINGS.
|
|
30
|
+
#
|
|
31
|
+
# variable 'ORDER_DATETIME', label: 'Order Date/Time', sample: -> { Time.current }
|
|
32
|
+
# variable 'ORDER_LINES', columns: { 'description' => { label: 'Item' } }
|
|
33
|
+
#
|
|
34
|
+
# Column options: label:, type:, width_mm:, align: — all optional.
|
|
35
|
+
def variable(key, label: nil, type: nil, sample: nil, columns: nil)
|
|
36
|
+
overrides[key.to_s] = { label: label, type: type, sample: sample, columns: columns }
|
|
37
|
+
@schema = nil
|
|
38
|
+
self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def definitions = schema.definitions
|
|
42
|
+
def labels = schema.labels
|
|
43
|
+
def scalar_keys = schema.scalar_keys
|
|
44
|
+
def collection_key = schema.collection_key
|
|
45
|
+
def keys = definitions.keys
|
|
46
|
+
def collection_definition = collection_key && definitions[collection_key]
|
|
47
|
+
|
|
48
|
+
def sample_data
|
|
49
|
+
definitions.transform_values(&:sample)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def overrides
|
|
53
|
+
@overrides ||= {}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def schema
|
|
59
|
+
@schema ||= build_schema
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def mappings
|
|
63
|
+
unless const_defined?(:MAPPINGS, false)
|
|
64
|
+
raise InvalidVariablesError, "#{inspect} must define a MAPPINGS constant"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
const_get(:MAPPINGS, false)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def build_schema
|
|
71
|
+
raw = mappings
|
|
72
|
+
raise InvalidVariablesError, "#{inspect}: MAPPINGS must be a Hash" unless raw.is_a?(Hash)
|
|
73
|
+
|
|
74
|
+
validate_override_keys!(raw)
|
|
75
|
+
validate_mapped_methods!(raw)
|
|
76
|
+
|
|
77
|
+
definitions = build_definitions(raw)
|
|
78
|
+
validate_single_collection!(definitions)
|
|
79
|
+
|
|
80
|
+
Schema.new(
|
|
81
|
+
definitions: definitions,
|
|
82
|
+
labels: definitions.transform_values(&:label).freeze,
|
|
83
|
+
scalar_keys: definitions.reject { |_, definition| definition.collection? }.keys.freeze,
|
|
84
|
+
collection_key: definitions.each_value.find(&:collection?)&.key
|
|
85
|
+
).freeze
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def build_definitions(raw)
|
|
89
|
+
raw.each_with_object({}) do |(key, method_name), acc|
|
|
90
|
+
string_key = key.to_s
|
|
91
|
+
override = overrides.fetch(string_key, {})
|
|
92
|
+
|
|
93
|
+
acc[string_key] = VariableDefinition.new(
|
|
94
|
+
key: string_key,
|
|
95
|
+
method_name: method_name,
|
|
96
|
+
label: override[:label] || string_key.titleize,
|
|
97
|
+
type: override[:type],
|
|
98
|
+
sample: override[:sample],
|
|
99
|
+
columns: normalize_columns(override[:columns])
|
|
100
|
+
)
|
|
101
|
+
end.freeze
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def normalize_columns(columns)
|
|
105
|
+
return nil if columns.nil?
|
|
106
|
+
|
|
107
|
+
columns.each_with_object({}) do |(column_key, options), acc|
|
|
108
|
+
acc[column_key.to_s] = {
|
|
109
|
+
label: options[:label],
|
|
110
|
+
type: options[:type],
|
|
111
|
+
width_mm: options[:width_mm],
|
|
112
|
+
align: options[:align]
|
|
113
|
+
}.compact.freeze
|
|
114
|
+
end.freeze
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def validate_override_keys!(raw)
|
|
118
|
+
unknown = overrides.keys - raw.keys.map(&:to_s)
|
|
119
|
+
return if unknown.empty?
|
|
120
|
+
|
|
121
|
+
raise InvalidVariablesError,
|
|
122
|
+
"#{inspect}: `variable` called for keys not in MAPPINGS: #{unknown.join(', ')}"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def validate_mapped_methods!(raw)
|
|
126
|
+
missing = raw.values.map(&:to_s).reject do |method_name|
|
|
127
|
+
method_defined?(method_name) || private_method_defined?(method_name)
|
|
128
|
+
end
|
|
129
|
+
return if missing.empty?
|
|
130
|
+
|
|
131
|
+
raise InvalidVariablesError,
|
|
132
|
+
"#{inspect}: MAPPINGS references undefined methods: #{missing.join(', ')}"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def validate_single_collection!(definitions)
|
|
136
|
+
collections = definitions.each_value.select(&:collection?).map(&:key)
|
|
137
|
+
return if collections.size <= 1
|
|
138
|
+
|
|
139
|
+
raise InvalidVariablesError,
|
|
140
|
+
"#{inspect}: only one variable may declare `columns:` (got #{collections.join(', ')})"
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
attr_reader :receipt_object
|
|
145
|
+
|
|
146
|
+
def initialize(receipt_object)
|
|
147
|
+
@receipt_object = receipt_object
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Raw values, unformatted — VariableResolver applies formatting. An error raised by a
|
|
151
|
+
# mapping method propagates deliberately: a receipt printing silently without its total
|
|
152
|
+
# is worse than a visible failure.
|
|
153
|
+
def resolve
|
|
154
|
+
self.class.definitions.each_with_object({}) do |(key, definition), acc|
|
|
155
|
+
acc[key] = send(definition.method_name)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
require 'active_support/core_ext/string/inflections'
|
|
5
|
+
require 'active_support/core_ext/object/blank'
|
|
6
|
+
require 'active_support/core_ext/enumerable'
|
|
7
|
+
|
|
8
|
+
require_relative 'nti_receipt_builder/version'
|
|
9
|
+
require_relative 'nti_receipt_builder/errors'
|
|
10
|
+
require_relative 'nti_receipt_builder/configuration'
|
|
11
|
+
require_relative 'nti_receipt_builder/type_inference'
|
|
12
|
+
require_relative 'nti_receipt_builder/variable_definition'
|
|
13
|
+
require_relative 'nti_receipt_builder/variables'
|
|
14
|
+
require_relative 'nti_receipt_builder/elements'
|
|
15
|
+
require_relative 'nti_receipt_builder/layout_validator'
|
|
16
|
+
require_relative 'nti_receipt_builder/variable_resolver'
|
|
17
|
+
require_relative 'nti_receipt_builder/presenters/element'
|
|
18
|
+
require_relative 'nti_receipt_builder/presenters/collection'
|
|
19
|
+
require_relative 'nti_receipt_builder/render_result'
|
|
20
|
+
require_relative 'nti_receipt_builder/renderer'
|
|
21
|
+
require_relative 'nti_receipt_builder/set_default'
|
|
22
|
+
require_relative 'nti_receipt_builder/template_form'
|
|
23
|
+
require_relative 'nti_receipt_builder/engine' if defined?(Rails::Engine)
|
|
24
|
+
|
|
25
|
+
# A receipt template builder and renderer.
|
|
26
|
+
#
|
|
27
|
+
# NtiReceiptBuilder.configure { |config| config.variables_class = OrderReceiptVariables }
|
|
28
|
+
#
|
|
29
|
+
# The configured Variables subclass supplies the placeholder vocabulary, so the gem itself
|
|
30
|
+
# carries no domain terms. See NtiReceiptBuilder::Variables.
|
|
31
|
+
module NtiReceiptBuilder
|
|
32
|
+
class << self
|
|
33
|
+
def configure
|
|
34
|
+
yield(config) if block_given?
|
|
35
|
+
config
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def config
|
|
39
|
+
@config ||= Configuration.new
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Resets configuration to defaults. Intended for test suites.
|
|
43
|
+
def reset_config!
|
|
44
|
+
@config = Configuration.new
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def variables_class = config.variables_class
|
|
48
|
+
def template_class = config.template_class
|
|
49
|
+
end
|
|
50
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: nti_receipt_builder
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Den Meralpis
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: actionview
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.1'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: activemodel
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '7.1'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '7.1'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: activerecord
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '7.1'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '7.1'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: activesupport
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '7.1'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '7.1'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: railties
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '7.1'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '7.1'
|
|
82
|
+
description: NtiReceiptBuilder ships a complete receipt designer — model, layout validation,
|
|
83
|
+
millimetre-accurate renderer, Stimulus builder UI and print views — as a Rails engine.
|
|
84
|
+
Host applications declare a Variables subclass that maps receipt placeholders to
|
|
85
|
+
methods on their own receipt object, so the gem carries no domain vocabulary of
|
|
86
|
+
its own.
|
|
87
|
+
email:
|
|
88
|
+
- denmark@nueca.com.ph
|
|
89
|
+
executables: []
|
|
90
|
+
extensions: []
|
|
91
|
+
extra_rdoc_files: []
|
|
92
|
+
files:
|
|
93
|
+
- CHANGELOG.md
|
|
94
|
+
- CODE_OF_CONDUCT.md
|
|
95
|
+
- LICENSE.txt
|
|
96
|
+
- README.md
|
|
97
|
+
- Rakefile
|
|
98
|
+
- app/assets/javascripts/nti_receipt_builder/index.js
|
|
99
|
+
- app/assets/javascripts/nti_receipt_builder/receipt_builder_controller.js
|
|
100
|
+
- app/assets/javascripts/nti_receipt_builder/receipt_canvas_controller.js
|
|
101
|
+
- app/assets/javascripts/nti_receipt_builder/receipt_draggable_controller.js
|
|
102
|
+
- app/assets/javascripts/nti_receipt_builder/receipt_print_controller.js
|
|
103
|
+
- app/assets/javascripts/nti_receipt_builder/receipt_properties_controller.js
|
|
104
|
+
- app/assets/stylesheets/nti_receipt_builder.css
|
|
105
|
+
- app/controllers/concerns/nti_receipt_builder/templates_controller.rb
|
|
106
|
+
- app/helpers/nti_receipt_builder/render_helper.rb
|
|
107
|
+
- app/models/nti_receipt_builder/template.rb
|
|
108
|
+
- app/views/nti_receipt_builder/render/_order_lines_element.html.erb
|
|
109
|
+
- app/views/nti_receipt_builder/render/_overflow_banner.html.erb
|
|
110
|
+
- app/views/nti_receipt_builder/render/_paper.html.erb
|
|
111
|
+
- app/views/nti_receipt_builder/render/_text_element.html.erb
|
|
112
|
+
- app/views/nti_receipt_builder/render/_variable_element.html.erb
|
|
113
|
+
- app/views/nti_receipt_builder/templates/_canvas.html.erb
|
|
114
|
+
- app/views/nti_receipt_builder/templates/_elements_panel.html.erb
|
|
115
|
+
- app/views/nti_receipt_builder/templates/_errors.html.erb
|
|
116
|
+
- app/views/nti_receipt_builder/templates/_lock_version_field.html.erb
|
|
117
|
+
- app/views/nti_receipt_builder/templates/_print_assets.html.erb
|
|
118
|
+
- app/views/nti_receipt_builder/templates/_properties_panel.html.erb
|
|
119
|
+
- app/views/nti_receipt_builder/templates/_settings_panel.html.erb
|
|
120
|
+
- app/views/nti_receipt_builder/templates/create.turbo_stream.erb
|
|
121
|
+
- app/views/nti_receipt_builder/templates/edit.html.erb
|
|
122
|
+
- app/views/nti_receipt_builder/templates/new.html.erb
|
|
123
|
+
- app/views/nti_receipt_builder/templates/preview.html.erb
|
|
124
|
+
- app/views/nti_receipt_builder/templates/print.html.erb
|
|
125
|
+
- app/views/nti_receipt_builder/templates/render_preview.turbo_stream.erb
|
|
126
|
+
- app/views/nti_receipt_builder/templates/update.turbo_stream.erb
|
|
127
|
+
- config/importmap.rb
|
|
128
|
+
- lib/generators/nti_receipt_builder/install_generator.rb
|
|
129
|
+
- lib/generators/nti_receipt_builder/templates/create_nti_receipt_templates.rb
|
|
130
|
+
- lib/generators/nti_receipt_builder/templates/initializer.rb
|
|
131
|
+
- lib/generators/nti_receipt_builder/templates/turbo_stream_tags.rb
|
|
132
|
+
- lib/nti_receipt_builder.rb
|
|
133
|
+
- lib/nti_receipt_builder/configuration.rb
|
|
134
|
+
- lib/nti_receipt_builder/elements.rb
|
|
135
|
+
- lib/nti_receipt_builder/engine.rb
|
|
136
|
+
- lib/nti_receipt_builder/errors.rb
|
|
137
|
+
- lib/nti_receipt_builder/layout_validator.rb
|
|
138
|
+
- lib/nti_receipt_builder/presenters/collection.rb
|
|
139
|
+
- lib/nti_receipt_builder/presenters/element.rb
|
|
140
|
+
- lib/nti_receipt_builder/render_result.rb
|
|
141
|
+
- lib/nti_receipt_builder/renderer.rb
|
|
142
|
+
- lib/nti_receipt_builder/set_default.rb
|
|
143
|
+
- lib/nti_receipt_builder/template_form.rb
|
|
144
|
+
- lib/nti_receipt_builder/type_inference.rb
|
|
145
|
+
- lib/nti_receipt_builder/variable_definition.rb
|
|
146
|
+
- lib/nti_receipt_builder/variable_resolver.rb
|
|
147
|
+
- lib/nti_receipt_builder/variables.rb
|
|
148
|
+
- lib/nti_receipt_builder/version.rb
|
|
149
|
+
homepage: https://github.com/nueca-tech/nti_receipt_builder
|
|
150
|
+
licenses:
|
|
151
|
+
- MIT
|
|
152
|
+
metadata:
|
|
153
|
+
allowed_push_host: https://rubygems.org
|
|
154
|
+
homepage_uri: https://github.com/nueca-tech/nti_receipt_builder
|
|
155
|
+
source_code_uri: https://github.com/nueca-tech/nti_receipt_builder
|
|
156
|
+
changelog_uri: https://github.com/nueca-tech/nti_receipt_builder/blob/main/CHANGELOG.md
|
|
157
|
+
rubygems_mfa_required: 'true'
|
|
158
|
+
rdoc_options: []
|
|
159
|
+
require_paths:
|
|
160
|
+
- lib
|
|
161
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
162
|
+
requirements:
|
|
163
|
+
- - ">="
|
|
164
|
+
- !ruby/object:Gem::Version
|
|
165
|
+
version: 3.4.0
|
|
166
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
|
+
requirements:
|
|
168
|
+
- - ">="
|
|
169
|
+
- !ruby/object:Gem::Version
|
|
170
|
+
version: '0'
|
|
171
|
+
requirements: []
|
|
172
|
+
rubygems_version: 4.0.16
|
|
173
|
+
specification_version: 4
|
|
174
|
+
summary: A drag-and-drop receipt template builder and renderer for Rails.
|
|
175
|
+
test_files: []
|