├── .dockerignore
├── .gitattributes
├── .gitignore
├── .ruby-version
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── app
├── assets
│ ├── config
│ │ ├── initializers
│ │ │ └── assets.rb
│ │ └── manifest.js
│ ├── files
│ │ └── template.docx
│ ├── images
│ │ ├── .keep
│ │ ├── company_logo.png
│ │ └── company_logo.png:Zone.Identifier
│ └── stylesheets
│ │ ├── application.css
│ │ └── invoice.css
├── channels
│ └── application_cable
│ │ ├── channel.rb
│ │ └── connection.rb
├── controllers
│ ├── application_controller.rb
│ ├── concerns
│ │ └── .keep
│ └── invoices_controller.rb
├── helpers
│ ├── application_helper.rb
│ └── invoices_helper.rb
├── javascript
│ ├── application.js
│ └── controllers
│ │ ├── application.js
│ │ ├── hello_controller.js
│ │ └── index.js
├── jobs
│ └── application_job.rb
├── mailers
│ └── application_mailer.rb
├── models
│ ├── application_record.rb
│ ├── concerns
│ │ └── .keep
│ ├── invoice.rb
│ └── invoice_item.rb
└── views
│ ├── invoices
│ ├── index.html.erb
│ └── show.html.erb
│ └── layouts
│ ├── application.html.erb
│ ├── mailer.html.erb
│ ├── mailer.text.erb
│ └── shared
│ └── _header.html.erb
├── bin
├── bundle
├── docker-entrypoint
├── importmap
├── rails
├── rake
└── setup
├── config.ru
├── config
├── application.rb
├── boot.rb
├── cable.yml
├── credentials.yml.enc
├── database.yml
├── environment.rb
├── environments
│ ├── development.rb
│ ├── production.rb
│ └── test.rb
├── importmap.rb
├── initializers
│ ├── assets.rb
│ ├── content_security_policy.rb
│ ├── filter_parameter_logging.rb
│ ├── inflections.rb
│ └── permissions_policy.rb
├── locales
│ └── en.yml
├── puma.rb
├── routes.rb
└── storage.yml
├── db
├── migrate
│ ├── 20240410012906_create_invoices.rb
│ └── 20240410013013_create_invoice_items.rb
├── schema.rb
└── seeds.rb
├── lib
├── assets
│ └── .keep
└── tasks
│ └── .keep
├── log
└── .keep
├── public
├── 404.html
├── 422.html
├── 500.html
├── apple-touch-icon-precomposed.png
├── apple-touch-icon.png
├── favicon.ico
└── robots.txt
├── storage
└── .keep
├── test
├── application_system_test_case.rb
├── channels
│ └── application_cable
│ │ └── connection_test.rb
├── controllers
│ ├── .keep
│ └── invoices_controller_test.rb
├── fixtures
│ ├── files
│ │ └── .keep
│ ├── invoice_items.yml
│ └── invoices.yml
├── helpers
│ └── .keep
├── integration
│ └── .keep
├── mailers
│ └── .keep
├── models
│ ├── .keep
│ ├── invoice_item_test.rb
│ └── invoice_test.rb
├── system
│ └── .keep
└── test_helper.rb
├── tmp
├── .keep
├── pids
│ └── .keep
└── storage
│ └── .keep
└── vendor
├── .keep
└── javascript
└── .keep
/.dockerignore:
--------------------------------------------------------------------------------
1 | # See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.
2 |
3 | # Ignore git directory.
4 | /.git/
5 |
6 | # Ignore bundler config.
7 | /.bundle
8 |
9 | # Ignore all environment files (except templates).
10 | /.env*
11 | !/.env*.erb
12 |
13 | # Ignore all default key files.
14 | /config/master.key
15 | /config/credentials/*.key
16 |
17 | # Ignore all logfiles and tempfiles.
18 | /log/*
19 | /tmp/*
20 | !/log/.keep
21 | !/tmp/.keep
22 |
23 | # Ignore pidfiles, but keep the directory.
24 | /tmp/pids/*
25 | !/tmp/pids/.keep
26 |
27 | # Ignore storage (uploaded files in development and any SQLite databases).
28 | /storage/*
29 | !/storage/.keep
30 | /tmp/storage/*
31 | !/tmp/storage/.keep
32 |
33 | # Ignore assets.
34 | /node_modules/
35 | /app/assets/builds/*
36 | !/app/assets/builds/.keep
37 | /public/assets
38 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # See https://git-scm.com/docs/gitattributes for more about git attribute files.
2 |
3 | # Mark the database schema as having been generated.
4 | db/schema.rb linguist-generated
5 |
6 | # Mark any vendored files as having been vendored.
7 | vendor/* linguist-vendored
8 | config/credentials/*.yml.enc diff=rails_credentials
9 | config/credentials.yml.enc diff=rails_credentials
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2 | #
3 | # If you find yourself ignoring temporary files generated by your text editor
4 | # or operating system, you probably want to add a global ignore instead:
5 | # git config --global core.excludesfile '~/.gitignore_global'
6 |
7 | # Ignore bundler config.
8 | /.bundle
9 |
10 | # Ignore all environment files (except templates).
11 | /.env*
12 | !/.env*.erb
13 |
14 | # Ignore all logfiles and tempfiles.
15 | /log/*
16 | /tmp/*
17 | !/log/.keep
18 | !/tmp/.keep
19 |
20 | # Ignore pidfiles, but keep the directory.
21 | /tmp/pids/*
22 | !/tmp/pids/
23 | !/tmp/pids/.keep
24 |
25 | # Ignore storage (uploaded files in development and any SQLite databases).
26 | /storage/*
27 | !/storage/.keep
28 | /tmp/storage/*
29 | !/tmp/storage/
30 | !/tmp/storage/.keep
31 |
32 | /public/assets
33 | /lib
34 | # Ignore master key for decrypting credentials and more.
35 | /config/master.key
36 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | ruby-3.3.0
2 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax = docker/dockerfile:1
2 |
3 | # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
4 | ARG RUBY_VERSION=3.3.0
5 | FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
6 |
7 | # Rails app lives here
8 | WORKDIR /rails
9 |
10 | # Set production environment
11 | ENV RAILS_ENV="production" \
12 | BUNDLE_DEPLOYMENT="1" \
13 | BUNDLE_PATH="/usr/local/bundle" \
14 | BUNDLE_WITHOUT="development"
15 |
16 |
17 | # Throw-away build stage to reduce size of final image
18 | FROM base as build
19 |
20 | # Install packages needed to build gems
21 | RUN apt-get update -qq && \
22 | apt-get install --no-install-recommends -y build-essential git libvips pkg-config
23 |
24 | # Install application gems
25 | COPY Gemfile Gemfile.lock ./
26 | RUN bundle install && \
27 | rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
28 | bundle exec bootsnap precompile --gemfile
29 |
30 | # Copy application code
31 | COPY . .
32 |
33 | # Precompile bootsnap code for faster boot times
34 | RUN bundle exec bootsnap precompile app/ lib/
35 |
36 | # Precompiling assets for production without requiring secret RAILS_MASTER_KEY
37 | RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
38 |
39 |
40 | # Final stage for app image
41 | FROM base
42 |
43 | # Install packages needed for deployment
44 | RUN apt-get update -qq && \
45 | apt-get install --no-install-recommends -y curl libsqlite3-0 libvips && \
46 | rm -rf /var/lib/apt/lists /var/cache/apt/archives
47 |
48 | # Copy built artifacts: gems, application
49 | COPY --from=build /usr/local/bundle /usr/local/bundle
50 | COPY --from=build /rails /rails
51 |
52 | # Run and own only the runtime files as a non-root user for security
53 | RUN useradd rails --create-home --shell /bin/bash && \
54 | chown -R rails:rails db log storage tmp
55 | USER rails:rails
56 |
57 | # Entrypoint prepares the database.
58 | ENTRYPOINT ["/rails/bin/docker-entrypoint"]
59 |
60 | # Start the server by default, this can be overwritten at runtime
61 | EXPOSE 3000
62 | CMD ["./bin/rails", "server"]
63 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | ruby "3.3.0"
4 |
5 | # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
6 | gem "rails", "~> 7.1.3"
7 |
8 | # The original asset pipeline for Rails [https://github.com/rails/sprockets-rails]
9 | gem "sprockets-rails"
10 |
11 | # Use sqlite3 as the database for Active Record
12 | gem "sqlite3", "~> 1.4"
13 |
14 | # Use the Puma web server [https://github.com/puma/puma]
15 | gem "puma", ">= 5.0"
16 |
17 | # Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails]
18 | gem "importmap-rails"
19 |
20 | # Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
21 | gem "turbo-rails"
22 |
23 | # Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
24 | gem "stimulus-rails"
25 |
26 | # Build JSON APIs with ease [https://github.com/rails/jbuilder]
27 | gem "jbuilder"
28 |
29 | # Use Redis adapter to run Action Cable in production
30 | # gem "redis", ">= 4.0.1"
31 |
32 | # Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]
33 | # gem "kredis"
34 |
35 | # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
36 | # gem "bcrypt", "~> 3.1.7"
37 |
38 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
39 | gem "tzinfo-data", platforms: %i[ windows jruby ]
40 |
41 | # Reduces boot times through caching; required in config/boot.rb
42 | gem "bootsnap", require: false
43 |
44 | # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
45 | # gem "image_processing", "~> 1.2"
46 |
47 | group :development, :test do
48 | # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
49 | gem "debug", platforms: %i[ mri windows ]
50 | end
51 |
52 | group :development do
53 | # Use console on exceptions pages [https://github.com/rails/web-console]
54 | gem "web-console"
55 |
56 | # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler]
57 | # gem "rack-mini-profiler"
58 |
59 | # Speed up commands on slow machines / big apps [https://github.com/rails/spring]
60 | # gem "spring"
61 | end
62 |
63 | group :test do
64 | # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
65 | gem "capybara"
66 | gem "selenium-webdriver"
67 | end
68 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | actioncable (7.1.3.2)
5 | actionpack (= 7.1.3.2)
6 | activesupport (= 7.1.3.2)
7 | nio4r (~> 2.0)
8 | websocket-driver (>= 0.6.1)
9 | zeitwerk (~> 2.6)
10 | actionmailbox (7.1.3.2)
11 | actionpack (= 7.1.3.2)
12 | activejob (= 7.1.3.2)
13 | activerecord (= 7.1.3.2)
14 | activestorage (= 7.1.3.2)
15 | activesupport (= 7.1.3.2)
16 | mail (>= 2.7.1)
17 | net-imap
18 | net-pop
19 | net-smtp
20 | actionmailer (7.1.3.2)
21 | actionpack (= 7.1.3.2)
22 | actionview (= 7.1.3.2)
23 | activejob (= 7.1.3.2)
24 | activesupport (= 7.1.3.2)
25 | mail (~> 2.5, >= 2.5.4)
26 | net-imap
27 | net-pop
28 | net-smtp
29 | rails-dom-testing (~> 2.2)
30 | actionpack (7.1.3.2)
31 | actionview (= 7.1.3.2)
32 | activesupport (= 7.1.3.2)
33 | nokogiri (>= 1.8.5)
34 | racc
35 | rack (>= 2.2.4)
36 | rack-session (>= 1.0.1)
37 | rack-test (>= 0.6.3)
38 | rails-dom-testing (~> 2.2)
39 | rails-html-sanitizer (~> 1.6)
40 | actiontext (7.1.3.2)
41 | actionpack (= 7.1.3.2)
42 | activerecord (= 7.1.3.2)
43 | activestorage (= 7.1.3.2)
44 | activesupport (= 7.1.3.2)
45 | globalid (>= 0.6.0)
46 | nokogiri (>= 1.8.5)
47 | actionview (7.1.3.2)
48 | activesupport (= 7.1.3.2)
49 | builder (~> 3.1)
50 | erubi (~> 1.11)
51 | rails-dom-testing (~> 2.2)
52 | rails-html-sanitizer (~> 1.6)
53 | activejob (7.1.3.2)
54 | activesupport (= 7.1.3.2)
55 | globalid (>= 0.3.6)
56 | activemodel (7.1.3.2)
57 | activesupport (= 7.1.3.2)
58 | activerecord (7.1.3.2)
59 | activemodel (= 7.1.3.2)
60 | activesupport (= 7.1.3.2)
61 | timeout (>= 0.4.0)
62 | activestorage (7.1.3.2)
63 | actionpack (= 7.1.3.2)
64 | activejob (= 7.1.3.2)
65 | activerecord (= 7.1.3.2)
66 | activesupport (= 7.1.3.2)
67 | marcel (~> 1.0)
68 | activesupport (7.1.3.2)
69 | base64
70 | bigdecimal
71 | concurrent-ruby (~> 1.0, >= 1.0.2)
72 | connection_pool (>= 2.2.5)
73 | drb
74 | i18n (>= 1.6, < 2)
75 | minitest (>= 5.1)
76 | mutex_m
77 | tzinfo (~> 2.0)
78 | addressable (2.8.6)
79 | public_suffix (>= 2.0.2, < 6.0)
80 | base64 (0.2.0)
81 | bigdecimal (3.1.7)
82 | bindex (0.8.1)
83 | bootsnap (1.18.3)
84 | msgpack (~> 1.2)
85 | builder (3.2.4)
86 | capybara (3.40.0)
87 | addressable
88 | matrix
89 | mini_mime (>= 0.1.3)
90 | nokogiri (~> 1.11)
91 | rack (>= 1.6.0)
92 | rack-test (>= 0.6.3)
93 | regexp_parser (>= 1.5, < 3.0)
94 | xpath (~> 3.2)
95 | concurrent-ruby (1.2.3)
96 | connection_pool (2.4.1)
97 | crass (1.0.6)
98 | date (3.3.4)
99 | debug (1.9.2)
100 | irb (~> 1.10)
101 | reline (>= 0.3.8)
102 | drb (2.2.1)
103 | erubi (1.12.0)
104 | globalid (1.2.1)
105 | activesupport (>= 6.1)
106 | i18n (1.14.4)
107 | concurrent-ruby (~> 1.0)
108 | importmap-rails (2.0.1)
109 | actionpack (>= 6.0.0)
110 | activesupport (>= 6.0.0)
111 | railties (>= 6.0.0)
112 | io-console (0.7.2)
113 | irb (1.12.0)
114 | rdoc
115 | reline (>= 0.4.2)
116 | jbuilder (2.11.5)
117 | actionview (>= 5.0.0)
118 | activesupport (>= 5.0.0)
119 | loofah (2.22.0)
120 | crass (~> 1.0.2)
121 | nokogiri (>= 1.12.0)
122 | mail (2.8.1)
123 | mini_mime (>= 0.1.1)
124 | net-imap
125 | net-pop
126 | net-smtp
127 | marcel (1.0.4)
128 | matrix (0.4.2)
129 | mini_mime (1.1.5)
130 | minitest (5.22.3)
131 | msgpack (1.7.2)
132 | mutex_m (0.2.0)
133 | net-imap (0.4.10)
134 | date
135 | net-protocol
136 | net-pop (0.1.2)
137 | net-protocol
138 | net-protocol (0.2.2)
139 | timeout
140 | net-smtp (0.5.0)
141 | net-protocol
142 | nio4r (2.7.1)
143 | nokogiri (1.16.3-aarch64-linux)
144 | racc (~> 1.4)
145 | nokogiri (1.16.3-arm-linux)
146 | racc (~> 1.4)
147 | nokogiri (1.16.3-arm64-darwin)
148 | racc (~> 1.4)
149 | nokogiri (1.16.3-x86-linux)
150 | racc (~> 1.4)
151 | nokogiri (1.16.3-x86_64-darwin)
152 | racc (~> 1.4)
153 | nokogiri (1.16.3-x86_64-linux)
154 | racc (~> 1.4)
155 | psych (5.1.2)
156 | stringio
157 | public_suffix (5.0.5)
158 | puma (6.4.2)
159 | nio4r (~> 2.0)
160 | racc (1.7.3)
161 | rack (3.0.10)
162 | rack-session (2.0.0)
163 | rack (>= 3.0.0)
164 | rack-test (2.1.0)
165 | rack (>= 1.3)
166 | rackup (2.1.0)
167 | rack (>= 3)
168 | webrick (~> 1.8)
169 | rails (7.1.3.2)
170 | actioncable (= 7.1.3.2)
171 | actionmailbox (= 7.1.3.2)
172 | actionmailer (= 7.1.3.2)
173 | actionpack (= 7.1.3.2)
174 | actiontext (= 7.1.3.2)
175 | actionview (= 7.1.3.2)
176 | activejob (= 7.1.3.2)
177 | activemodel (= 7.1.3.2)
178 | activerecord (= 7.1.3.2)
179 | activestorage (= 7.1.3.2)
180 | activesupport (= 7.1.3.2)
181 | bundler (>= 1.15.0)
182 | railties (= 7.1.3.2)
183 | rails-dom-testing (2.2.0)
184 | activesupport (>= 5.0.0)
185 | minitest
186 | nokogiri (>= 1.6)
187 | rails-html-sanitizer (1.6.0)
188 | loofah (~> 2.21)
189 | nokogiri (~> 1.14)
190 | railties (7.1.3.2)
191 | actionpack (= 7.1.3.2)
192 | activesupport (= 7.1.3.2)
193 | irb
194 | rackup (>= 1.0.0)
195 | rake (>= 12.2)
196 | thor (~> 1.0, >= 1.2.2)
197 | zeitwerk (~> 2.6)
198 | rake (13.2.1)
199 | rdoc (6.6.3.1)
200 | psych (>= 4.0.0)
201 | regexp_parser (2.9.0)
202 | reline (0.5.1)
203 | io-console (~> 0.5)
204 | rexml (3.2.6)
205 | rubyzip (2.3.2)
206 | selenium-webdriver (4.19.0)
207 | base64 (~> 0.2)
208 | rexml (~> 3.2, >= 3.2.5)
209 | rubyzip (>= 1.2.2, < 3.0)
210 | websocket (~> 1.0)
211 | sprockets (4.2.1)
212 | concurrent-ruby (~> 1.0)
213 | rack (>= 2.2.4, < 4)
214 | sprockets-rails (3.4.2)
215 | actionpack (>= 5.2)
216 | activesupport (>= 5.2)
217 | sprockets (>= 3.0.0)
218 | sqlite3 (1.7.3-aarch64-linux)
219 | sqlite3 (1.7.3-arm-linux)
220 | sqlite3 (1.7.3-arm64-darwin)
221 | sqlite3 (1.7.3-x86-linux)
222 | sqlite3 (1.7.3-x86_64-darwin)
223 | sqlite3 (1.7.3-x86_64-linux)
224 | stimulus-rails (1.3.3)
225 | railties (>= 6.0.0)
226 | stringio (3.1.0)
227 | thor (1.3.1)
228 | timeout (0.4.1)
229 | turbo-rails (2.0.5)
230 | actionpack (>= 6.0.0)
231 | activejob (>= 6.0.0)
232 | railties (>= 6.0.0)
233 | tzinfo (2.0.6)
234 | concurrent-ruby (~> 1.0)
235 | web-console (4.2.1)
236 | actionview (>= 6.0.0)
237 | activemodel (>= 6.0.0)
238 | bindex (>= 0.4.0)
239 | railties (>= 6.0.0)
240 | webrick (1.8.1)
241 | websocket (1.2.10)
242 | websocket-driver (0.7.6)
243 | websocket-extensions (>= 0.1.0)
244 | websocket-extensions (0.1.5)
245 | xpath (3.2.0)
246 | nokogiri (~> 1.8)
247 | zeitwerk (2.6.13)
248 |
249 | PLATFORMS
250 | aarch64-linux
251 | arm-linux
252 | arm64-darwin
253 | x86-linux
254 | x86_64-darwin
255 | x86_64-linux
256 |
257 | DEPENDENCIES
258 | bootsnap
259 | capybara
260 | debug
261 | importmap-rails
262 | jbuilder
263 | puma (>= 5.0)
264 | rails (~> 7.1.3)
265 | selenium-webdriver
266 | sprockets-rails
267 | sqlite3 (~> 1.4)
268 | stimulus-rails
269 | turbo-rails
270 | tzinfo-data
271 | web-console
272 |
273 | RUBY VERSION
274 | ruby 3.3.0p0
275 |
276 | BUNDLED WITH
277 | 2.5.7
278 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | This README would normally document whatever steps are necessary to get the
4 | application up and running.
5 |
6 | Things you may want to cover:
7 |
8 | * Ruby version
9 |
10 | * System dependencies
11 |
12 | * Configuration
13 |
14 | * Database creation
15 |
16 | * Database initialization
17 |
18 | * How to run the test suite
19 |
20 | * Services (job queues, cache servers, search engines, etc.)
21 |
22 | * Deployment instructions
23 |
24 | * ...
25 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require_relative "config/application"
5 |
6 | Rails.application.load_tasks
7 |
--------------------------------------------------------------------------------
/app/assets/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | Rails.application.config.assets.precompile += %w( invoice.css )
--------------------------------------------------------------------------------
/app/assets/config/manifest.js:
--------------------------------------------------------------------------------
1 | //= link_tree ../images
2 | //= link_directory ../stylesheets .css
3 | //= link_tree ../../javascript .js
4 | //= link_tree ../../../vendor/javascript .js
5 |
--------------------------------------------------------------------------------
/app/assets/files/template.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/app/assets/files/template.docx
--------------------------------------------------------------------------------
/app/assets/images/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/app/assets/images/.keep
--------------------------------------------------------------------------------
/app/assets/images/company_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/app/assets/images/company_logo.png
--------------------------------------------------------------------------------
/app/assets/images/company_logo.png:Zone.Identifier:
--------------------------------------------------------------------------------
1 | [ZoneTransfer]
2 | ZoneId=3
3 | HostUrl=https://github.com/
4 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll be compiled into application.css, which will include all the files
3 | * listed below.
4 | *
5 | * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's
6 | * vendor/assets/stylesheets directory can be referenced here using a relative path.
7 | *
8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS
10 | * files in this directory. Styles in this file should be added after the last require_* statement.
11 | * It is generally better to create a new file per style scope.
12 | *
13 | *= require_tree .
14 | *= require_self
15 | */
16 | @import "bootstrap";
17 | @import "invoice";
18 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/invoice.css:
--------------------------------------------------------------------------------
1 | .invoice-box {
2 | max-width: 100%;
3 | max-height: 100%;
4 | margin: auto;
5 | padding: 30px;
6 | border: 1px solid #eee;
7 | box-shadow: 0 0 5px rgba(0, 0, 0, .10);
8 | font-size: 16px;
9 | line-height: 24px;
10 | font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
11 | color: #555;
12 | }
13 |
14 | .invoice-box table {
15 | width: 100%;
16 | line-height: inherit;
17 | text-align: left;
18 | }
19 |
20 | .invoice-box table td {
21 | padding: 5px;
22 | vertical-align: middle;
23 | }
24 |
25 | .invoice-box table tr td:nth-child(2) {
26 | text-align: right;
27 | }
28 |
29 | .right {
30 | text-align: right;
31 | }
32 |
33 | .invoice-box table tr.top table td {
34 | padding-bottom: 20px;
35 | }
36 |
37 | .invoice-box table tr.top table td.title {
38 | font-size: 45px;
39 | line-height: 45px;
40 | color: #333;
41 | }
42 |
43 | .invoice-box table tr.information table td {
44 | padding-bottom: 40px;
45 | }
46 |
47 | .invoice-box table tr.heading td {
48 | background: #eee;
49 | border-bottom: 1px solid #ddd;
50 | font-weight: bold;
51 | }
52 |
53 | .invoice-box table tr.details td {
54 | padding-bottom: 20px;
55 | }
56 |
57 | .invoice-box table tr.item td{
58 | border-bottom: 1px solid #eee;
59 | }
60 |
61 | .invoice-box table tr.item.last td {
62 | border-bottom: none;
63 | }
64 |
65 | .badge {
66 | display: inline-block;
67 | padding: 0.25em 0.4em;
68 | font-size: 75%;
69 | font-weight: 700;
70 | line-height: 1;
71 | text-align: center;
72 | white-space: nowrap;
73 | vertical-align: baseline;
74 | border-radius: 0.25rem;
75 | }
76 | .badge:empty {
77 | display: none;
78 | }
79 |
80 | .btn .badge {
81 | position: relative;
82 | top: -1px;
83 | }
84 |
85 | .badge-pill {
86 | padding-right: 0.6em;
87 | padding-left: 0.6em;
88 | border-radius: 10rem;
89 | }
90 |
91 | .badge-primary {
92 | color: #fff;
93 | background-color: #007bff;
94 | }
95 |
96 | .badge-primary[href]:hover, .badge-primary[href]:focus {
97 | color: #fff;
98 | text-decoration: none;
99 | background-color: #0062cc;
100 | }
101 |
102 | .badge-secondary {
103 | color: #fff;
104 | background-color: #6c757d;
105 | }
106 |
107 | .badge-secondary[href]:hover, .badge-secondary[href]:focus {
108 | color: #fff;
109 | text-decoration: none;
110 | background-color: #545b62;
111 | }
112 |
113 | .badge-success {
114 | color: #fff;
115 | background-color: #28a745;
116 | }
117 |
118 | .badge-success[href]:hover, .badge-success[href]:focus {
119 | color: #fff;
120 | text-decoration: none;
121 | background-color: #1e7e34;
122 | }
123 |
124 | .badge-info {
125 | color: #fff;
126 | background-color: #17a2b8;
127 | }
128 |
129 | .badge-info[href]:hover, .badge-info[href]:focus {
130 | color: #fff;
131 | text-decoration: none;
132 | background-color: #117a8b;
133 | }
134 |
135 | .badge-warning {
136 | color: #212529;
137 | background-color: #ffc107;
138 | }
139 |
140 | .badge-warning[href]:hover, .badge-warning[href]:focus {
141 | color: #212529;
142 | text-decoration: none;
143 | background-color: #d39e00;
144 | }
145 |
146 | .badge-danger {
147 | color: #fff;
148 | background-color: #dc3545;
149 | }
150 |
151 | .badge-danger[href]:hover, .badge-danger[href]:focus {
152 | color: #fff;
153 | text-decoration: none;
154 | background-color: #bd2130;
155 | }
156 |
157 | .badge-light {
158 | color: #212529;
159 | background-color: #f8f9fa;
160 | }
161 |
162 | .badge-light[href]:hover, .badge-light[href]:focus {
163 | color: #212529;
164 | text-decoration: none;
165 | background-color: #dae0e5;
166 | }
167 |
168 | .badge-dark {
169 | color: #fff;
170 | background-color: #343a40;
171 | }
172 |
173 | .badge-dark[href]:hover, .badge-dark[href]:focus {
174 | color: #fff;
175 | text-decoration: none;
176 | background-color: #1d2124;
177 | }
178 |
179 |
180 |
181 |
182 | .invoice-box table tr.total td:nth-child(2) {
183 | border-top: 2px solid #eee;
184 | font-weight: bold;
185 | }
186 |
187 |
188 |
189 | /** RTL **/
190 | .rtl {
191 | direction: rtl;
192 | font-family: Tahoma, 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
193 | }
194 |
195 | .rtl table {
196 | text-align: right;
197 | }
198 |
199 | .rtl table tr td:nth-child(2) {
200 | text-align: left;
201 | }
--------------------------------------------------------------------------------
/app/channels/application_cable/channel.rb:
--------------------------------------------------------------------------------
1 | module ApplicationCable
2 | class Channel < ActionCable::Channel::Base
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/app/channels/application_cable/connection.rb:
--------------------------------------------------------------------------------
1 | module ApplicationCable
2 | class Connection < ActionCable::Connection::Base
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | end
3 |
--------------------------------------------------------------------------------
/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/app/controllers/concerns/.keep
--------------------------------------------------------------------------------
/app/controllers/invoices_controller.rb:
--------------------------------------------------------------------------------
1 | require './lib/PDFNetWrappers/PDFNetC/Lib/PDFNetRuby'
2 | include PDFNetRuby
3 | require './lib/PDFNetWrappers/Samples/LicenseKey/RUBY/LicenseKey'
4 |
5 | class InvoicesController < ApplicationController
6 |
7 | def convertToCentString (f)
8 | return (((((f)*100).to_i).to_d)/100).to_s
9 | end
10 | def index
11 | @invoices = scope
12 | end
13 |
14 | def show
15 | @invoice = scope.find(params[:id])
16 | invMod = Object.new
17 | invMod.instance_variable_set(:@id, @invoice.id.to_s)
18 | invMod.instance_variable_set(:@subtotal, convertToCentString(@invoice.subtotal))
19 | invMod.instance_variable_set(:@discount_calculated, convertToCentString(@invoice.discount_calculated))
20 | invMod.instance_variable_set(:@vat_calculated, convertToCentString(@invoice.vat_calculated))
21 | invMod.instance_variable_set(:@total, convertToCentString(@invoice.total));
22 | invMod.instance_variable_set(:@from_full_name, @invoice.from_full_name);
23 | invMod.instance_variable_set(:@from_address, @invoice.from_address);
24 | invMod.instance_variable_set(:@from_email, @invoice.from_email);
25 | invMod.instance_variable_set(:@from_phone, @invoice.from_phone);
26 | invMod.instance_variable_set(:@to_full_name, @invoice.to_full_name);
27 | invMod.instance_variable_set(:@to_address, @invoice.to_address);
28 | invMod.instance_variable_set(:@to_email, @invoice.to_email);
29 | invMod.instance_variable_set(:@to_phone, @invoice.to_phone);
30 | invMod.instance_variable_set(:@created_at, (@invoice.created_at).strftime('%d/%m/%Y'));
31 | invMod.instance_variable_set(:@due_at, (@invoice.created_at + 1.month).strftime('%d/%m/%Y'));
32 | invMod.instance_variable_set(:@discount, @invoice.discount);
33 | invMod.instance_variable_set(:@vat, @invoice.vat);
34 | invMod.instance_variable_set(:@status, @invoice.status);
35 |
36 | # add the rows
37 | rows = []
38 | @invoice.invoice_items.each do |key, item|
39 | row= Object.new
40 | row.instance_variable_set(:@name, key.name);
41 | row.instance_variable_set(:@description, key.description);
42 | row.instance_variable_set(:@price, key.price);
43 | row.instance_variable_set(:@qty, key.qty.to_s);
44 | row.instance_variable_set(:@total, key.qty.to_d * key.price.to_d);
45 | rows << row
46 | end
47 |
48 | invMod.instance_variable_set(:@rows, rows)
49 | json = invMod.to_json
50 |
51 | respond_to do |format|
52 | format.html
53 | format.pdf do
54 | PDFNet.Initialize(PDFTronLicense.Key)
55 | $inputPath = "./app/assets/files/"
56 | inputFilename = "template.docx"
57 |
58 | # Create a TemplateDocument object from an input office file.
59 | inputFile = $inputPath + inputFilename
60 | templateDoc = Convert.CreateOfficeTemplate(inputFile, nil)
61 |
62 | # Fill the template with data from a JSON string, producing a PDF document.
63 | pdfdoc = templateDoc.FillTemplateJson(json)
64 | buffer = pdfdoc.Save(SDFDoc::E_linearized)
65 |
66 | send_data(buffer, filename: 'my-awesome-pdf.pdf', type: 'application/pdf', :disposition=>'inline')
67 | PDFNet.Terminate()
68 | end
69 | end
70 | end
71 |
72 | private
73 | def scope
74 | ::Invoice.all.includes(:invoice_items)
75 | end
76 | end
--------------------------------------------------------------------------------
/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/invoices_helper.rb:
--------------------------------------------------------------------------------
1 | module InvoicesHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/javascript/application.js:
--------------------------------------------------------------------------------
1 | // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
2 | import "@hotwired/turbo-rails"
3 | import "controllers"
4 |
--------------------------------------------------------------------------------
/app/javascript/controllers/application.js:
--------------------------------------------------------------------------------
1 | import { Application } from "@hotwired/stimulus"
2 |
3 | const application = Application.start()
4 |
5 | // Configure Stimulus development experience
6 | application.debug = false
7 | window.Stimulus = application
8 |
9 | export { application }
10 |
--------------------------------------------------------------------------------
/app/javascript/controllers/hello_controller.js:
--------------------------------------------------------------------------------
1 | import { Controller } from "@hotwired/stimulus"
2 |
3 | export default class extends Controller {
4 | connect() {
5 | this.element.textContent = "Hello World!"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/app/javascript/controllers/index.js:
--------------------------------------------------------------------------------
1 | // Import and register all your controllers from the importmap under controllers/*
2 |
3 | import { application } from "controllers/application"
4 |
5 | // Eager load all controllers defined in the import map under controllers/**/*_controller
6 | import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
7 | eagerLoadControllersFrom("controllers", application)
8 |
9 | // Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
10 | // import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading"
11 | // lazyLoadControllersFrom("controllers", application)
12 |
--------------------------------------------------------------------------------
/app/jobs/application_job.rb:
--------------------------------------------------------------------------------
1 | class ApplicationJob < ActiveJob::Base
2 | # Automatically retry jobs that encountered a deadlock
3 | # retry_on ActiveRecord::Deadlocked
4 |
5 | # Most jobs are safe to ignore if the underlying records are no longer available
6 | # discard_on ActiveJob::DeserializationError
7 | end
8 |
--------------------------------------------------------------------------------
/app/mailers/application_mailer.rb:
--------------------------------------------------------------------------------
1 | class ApplicationMailer < ActionMailer::Base
2 | default from: "from@example.com"
3 | layout "mailer"
4 | end
5 |
--------------------------------------------------------------------------------
/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | class ApplicationRecord < ActiveRecord::Base
2 | primary_abstract_class
3 | end
4 |
--------------------------------------------------------------------------------
/app/models/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/app/models/concerns/.keep
--------------------------------------------------------------------------------
/app/models/invoice.rb:
--------------------------------------------------------------------------------
1 | class Invoice < ApplicationRecord
2 | has_many :invoice_items, dependent: :destroy
3 |
4 | STATUS_CLASS = {
5 | :draft => "badge badge-secondary",
6 | :sent => "badge badge-primary",
7 | :paid => "badge badge-success"
8 | }
9 |
10 | def subtotal
11 | self.invoice_items.map { |item| item.qty * item.price }.sum
12 | end
13 |
14 | def discount_calculated
15 | subtotal * (self.discount / 100.0)
16 | end
17 |
18 | def vat_calculated
19 | (subtotal - discount_calculated) * (self.vat / 100.0)
20 | end
21 |
22 | def total
23 | subtotal - discount_calculated + vat_calculated
24 | end
25 |
26 | def status_class
27 | STATUS_CLASS[self.status.to_sym]
28 | end
29 |
30 | end
--------------------------------------------------------------------------------
/app/models/invoice_item.rb:
--------------------------------------------------------------------------------
1 | class InvoiceItem < ApplicationRecord
2 | belongs_to :invoice
3 | end
4 |
--------------------------------------------------------------------------------
/app/views/invoices/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Date |
5 | From |
6 | To |
7 | Status |
8 | Discount (%) |
9 | VAT (%) |
10 | TOTAL |
11 | |
12 |
13 |
14 |
15 | <% @invoices.each do |invoice| %>
16 |
17 | <%= invoice.created_at.strftime('%d/%m/%Y') %> |
18 | <%= invoice.from_full_name %> |
19 | <%= invoice.to_full_name %> |
20 | <%= invoice.status %> |
21 | <%= invoice.discount %> |
22 | <%= invoice.vat %> |
23 | <%= number_to_currency(invoice.total) %> |
24 | <%= link_to 'View', invoice_path(invoice) %> |
25 |
26 | <% end %>
27 |
28 |
--------------------------------------------------------------------------------
/app/views/invoices/show.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | <%= image_tag ('company_logo.png') %>
10 | |
11 |
12 |
13 | Invoice #: <%= @invoice.id %>
14 |
15 | Created: <%= @invoice.created_at.strftime('%d/%m/%Y') %>
16 |
17 | Due: <%= (@invoice.created_at + 1.month).strftime('%d/%m/%Y') %>
18 |
19 | Status: <%= @invoice.status %>
20 | |
21 |
22 |
23 | |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | <%= @invoice.from_full_name %>
32 | <%= @invoice.from_address %>
33 | <%= @invoice.from_email %>
34 | <%= @invoice.from_phone %>
35 | |
36 |
37 |
38 | <%= @invoice.to_full_name %>
39 | <%= @invoice.to_address %>
40 | <%= @invoice.to_email %>
41 | <%= @invoice.to_phone %>
42 | |
43 |
44 |
45 | |
46 |
47 |
48 |
49 | Payment Method |
50 | |
51 | Cache |
52 |
53 |
54 |
55 | Delivery Method |
56 | |
57 | 1000 |
58 |
59 |
60 |
61 | Item |
62 | Price |
63 | Qty |
64 | Total |
65 |
66 |
67 | <% @invoice.invoice_items.each do |invoice_item| %>
68 |
69 |
70 | <%= invoice_item.name %>
71 | <%= invoice_item.description %>
72 | |
73 |
74 |
75 | <%= number_to_currency(invoice_item.price) %>
76 | |
77 |
78 |
79 | x <%= invoice_item.qty %>
80 | |
81 |
82 |
83 | <%= number_to_currency(invoice_item.price * invoice_item.qty) %>
84 | |
85 |
86 | <% end %>
87 |
88 |
89 | |
90 |
91 |
92 |
93 | |
94 | Subtotal |
95 | <%= number_to_currency(@invoice.subtotal) %> |
96 |
97 |
98 |
99 | |
100 | Discount (<%= @invoice.discount %>%) |
101 | - <%= number_to_currency(@invoice.discount_calculated) %> |
102 |
103 |
104 |
105 | |
106 | VAT (<%= @invoice.vat %>%) |
107 | + <%= number_to_currency(@invoice.vat_calculated) %> |
108 |
109 |
110 |
111 | |
112 | TOTAL: |
113 |
114 | <%= number_to_currency(@invoice.total) %>
115 | |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PDFs - Ruby on Rails
5 |
6 | <%= csrf_meta_tags %>
7 | <%= csp_meta_tag %>
8 |
9 | <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
10 | <%= javascript_importmap_tags %>
11 |
12 |
13 |
14 | <%= render "layouts/shared/header" %>
15 |
16 | <%= yield %>
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/views/layouts/mailer.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 | <%= yield %>
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/views/layouts/mailer.text.erb:
--------------------------------------------------------------------------------
1 | <%= yield %>
2 |
--------------------------------------------------------------------------------
/app/views/layouts/shared/_header.html.erb:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/bin/bundle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'bundle' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "rubygems"
12 |
13 | m = Module.new do
14 | module_function
15 |
16 | def invoked_as_script?
17 | File.expand_path($0) == File.expand_path(__FILE__)
18 | end
19 |
20 | def env_var_version
21 | ENV["BUNDLER_VERSION"]
22 | end
23 |
24 | def cli_arg_version
25 | return unless invoked_as_script? # don't want to hijack other binstubs
26 | return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
27 | bundler_version = nil
28 | update_index = nil
29 | ARGV.each_with_index do |a, i|
30 | if update_index && update_index.succ == i && a.match?(Gem::Version::ANCHORED_VERSION_PATTERN)
31 | bundler_version = a
32 | end
33 | next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
34 | bundler_version = $1
35 | update_index = i
36 | end
37 | bundler_version
38 | end
39 |
40 | def gemfile
41 | gemfile = ENV["BUNDLE_GEMFILE"]
42 | return gemfile if gemfile && !gemfile.empty?
43 |
44 | File.expand_path("../Gemfile", __dir__)
45 | end
46 |
47 | def lockfile
48 | lockfile =
49 | case File.basename(gemfile)
50 | when "gems.rb" then gemfile.sub(/\.rb$/, ".locked")
51 | else "#{gemfile}.lock"
52 | end
53 | File.expand_path(lockfile)
54 | end
55 |
56 | def lockfile_version
57 | return unless File.file?(lockfile)
58 | lockfile_contents = File.read(lockfile)
59 | return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
60 | Regexp.last_match(1)
61 | end
62 |
63 | def bundler_requirement
64 | @bundler_requirement ||=
65 | env_var_version ||
66 | cli_arg_version ||
67 | bundler_requirement_for(lockfile_version)
68 | end
69 |
70 | def bundler_requirement_for(version)
71 | return "#{Gem::Requirement.default}.a" unless version
72 |
73 | bundler_gem_version = Gem::Version.new(version)
74 |
75 | bundler_gem_version.approximate_recommendation
76 | end
77 |
78 | def load_bundler!
79 | ENV["BUNDLE_GEMFILE"] ||= gemfile
80 |
81 | activate_bundler
82 | end
83 |
84 | def activate_bundler
85 | gem_error = activation_error_handling do
86 | gem "bundler", bundler_requirement
87 | end
88 | return if gem_error.nil?
89 | require_error = activation_error_handling do
90 | require "bundler/version"
91 | end
92 | return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
93 | warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
94 | exit 42
95 | end
96 |
97 | def activation_error_handling
98 | yield
99 | nil
100 | rescue StandardError, LoadError => e
101 | e
102 | end
103 | end
104 |
105 | m.load_bundler!
106 |
107 | if m.invoked_as_script?
108 | load Gem.bin_path("bundler", "bundle")
109 | end
110 |
--------------------------------------------------------------------------------
/bin/docker-entrypoint:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | # If running the rails server then create or migrate existing database
4 | if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then
5 | ./bin/rails db:prepare
6 | fi
7 |
8 | exec "${@}"
9 |
--------------------------------------------------------------------------------
/bin/importmap:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require_relative "../config/application"
4 | require "importmap/commands"
5 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_PATH = File.expand_path("../config/application", __dir__)
3 | require_relative "../config/boot"
4 | require "rails/commands"
5 |
--------------------------------------------------------------------------------
/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative "../config/boot"
3 | require "rake"
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require "fileutils"
3 |
4 | # path to your application root.
5 | APP_ROOT = File.expand_path("..", __dir__)
6 |
7 | def system!(*args)
8 | system(*args, exception: true)
9 | end
10 |
11 | FileUtils.chdir APP_ROOT do
12 | # This script is a way to set up or update your development environment automatically.
13 | # This script is idempotent, so that you can run it at any time and get an expectable outcome.
14 | # Add necessary setup steps to this file.
15 |
16 | puts "== Installing dependencies =="
17 | system! "gem install bundler --conservative"
18 | system("bundle check") || system!("bundle install")
19 |
20 | # puts "\n== Copying sample files =="
21 | # unless File.exist?("config/database.yml")
22 | # FileUtils.cp "config/database.yml.sample", "config/database.yml"
23 | # end
24 |
25 | puts "\n== Preparing database =="
26 | system! "bin/rails db:prepare"
27 |
28 | puts "\n== Removing old logs and tempfiles =="
29 | system! "bin/rails log:clear tmp:clear"
30 |
31 | puts "\n== Restarting application server =="
32 | system! "bin/rails restart"
33 | end
34 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require_relative "config/environment"
4 |
5 | run Rails.application
6 | Rails.application.load_server
7 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | require_relative "boot"
2 |
3 | require "rails/all"
4 |
5 | # Require the gems listed in Gemfile, including any gems
6 | # you've limited to :test, :development, or :production.
7 | Bundler.require(*Rails.groups)
8 |
9 | module RailsGeneratePdf
10 | class Application < Rails::Application
11 | # Initialize configuration defaults for originally generated Rails version.
12 | config.load_defaults 7.1
13 |
14 | # Please, add to the `ignore` list any other `lib` subdirectories that do
15 | # not contain `.rb` files, or that should not be reloaded or eager loaded.
16 | # Common ones are `templates`, `generators`, or `middleware`, for example.
17 | config.autoload_lib(ignore: %w(assets tasks))
18 |
19 | # Configuration for the application, engines, and railties goes here.
20 | #
21 | # These settings can be overridden in specific environments using the files
22 | # in config/environments, which are processed later.
23 | #
24 | # config.time_zone = "Central Time (US & Canada)"
25 | # config.eager_load_paths << Rails.root.join("extras")
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
2 |
3 | require "bundler/setup" # Set up gems listed in the Gemfile.
4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations.
5 |
--------------------------------------------------------------------------------
/config/cable.yml:
--------------------------------------------------------------------------------
1 | development:
2 | adapter: async
3 |
4 | test:
5 | adapter: test
6 |
7 | production:
8 | adapter: redis
9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
10 | channel_prefix: rails_generate_pdf_production
11 |
--------------------------------------------------------------------------------
/config/credentials.yml.enc:
--------------------------------------------------------------------------------
1 | IHM7YQaD1HLdXzIfk2ih1xFSmiwM3PWiSt4kUV+hEeO4NEah/5sLKZk/mekt3rn1/5Ada62/uFFVhEdjKnTQe2gepX/Cd3xERHfQ9CKemiz9YMWQOgq49GorFn70hyNQlWmLy5u+LMkXxgJgrAzM9XP8QpA4csRcz7fY3/iYS1Q/bqcCuAXUEdCFpn6fzlA931G3o6r6ag1Ch2LiGwMakliQyIeahpOpIeOL6RwMAW7GsUmtfd1iDKDR/yrJkL3YI4S19ncFqUMRJ7FW2t+bVgXQi/UGFXJ70Uu0PB9qafURnPCH3wunRdBzwfCBToarQoHWNMX7KaY91PuApgBiQI76S7bFrs+UAFUtM1GYxPHbboW5bbmF5SBIVziofTkZJ1T8Xs1VuIEqgHDdoKl18HHuv+ir--J61zZWAlGZErKnMm--nCgjmIEU/FwpI3QL/8wTcw==
--------------------------------------------------------------------------------
/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite. Versions 3.8.0 and up are supported.
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem "sqlite3"
6 | #
7 | default: &default
8 | adapter: sqlite3
9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
10 | timeout: 5000
11 |
12 | development:
13 | <<: *default
14 | database: storage/development.sqlite3
15 |
16 | # Warning: The database defined as "test" will be erased and
17 | # re-generated from your development database when you run "rake".
18 | # Do not set this db to the same as development or production.
19 | test:
20 | <<: *default
21 | database: storage/test.sqlite3
22 |
23 | production:
24 | <<: *default
25 | database: storage/production.sqlite3
26 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require_relative "application"
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | require "active_support/core_ext/integer/time"
2 |
3 | Rails.application.configure do
4 | # Settings specified here will take precedence over those in config/application.rb.
5 |
6 | # In the development environment your application's code is reloaded any time
7 | # it changes. This slows down response time but is perfect for development
8 | # since you don't have to restart the web server when you make code changes.
9 | config.enable_reloading = true
10 |
11 | # Do not eager load code on boot.
12 | config.eager_load = false
13 |
14 | # Show full error reports.
15 | config.consider_all_requests_local = true
16 |
17 | # Enable server timing
18 | config.server_timing = true
19 |
20 | # Enable/disable caching. By default caching is disabled.
21 | # Run rails dev:cache to toggle caching.
22 | if Rails.root.join("tmp/caching-dev.txt").exist?
23 | config.action_controller.perform_caching = true
24 | config.action_controller.enable_fragment_cache_logging = true
25 |
26 | config.cache_store = :memory_store
27 | config.public_file_server.headers = {
28 | "Cache-Control" => "public, max-age=#{2.days.to_i}"
29 | }
30 | else
31 | config.action_controller.perform_caching = false
32 |
33 | config.cache_store = :null_store
34 | end
35 |
36 | # Store uploaded files on the local file system (see config/storage.yml for options).
37 | config.active_storage.service = :local
38 |
39 | # Don't care if the mailer can't send.
40 | config.action_mailer.raise_delivery_errors = false
41 |
42 | config.action_mailer.perform_caching = false
43 |
44 | # Print deprecation notices to the Rails logger.
45 | config.active_support.deprecation = :log
46 |
47 | # Raise exceptions for disallowed deprecations.
48 | config.active_support.disallowed_deprecation = :raise
49 |
50 | # Tell Active Support which deprecation messages to disallow.
51 | config.active_support.disallowed_deprecation_warnings = []
52 |
53 | # Raise an error on page load if there are pending migrations.
54 | config.active_record.migration_error = :page_load
55 |
56 | # Highlight code that triggered database queries in logs.
57 | config.active_record.verbose_query_logs = true
58 |
59 | # Highlight code that enqueued background job in logs.
60 | config.active_job.verbose_enqueue_logs = true
61 |
62 | # Suppress logger output for asset requests.
63 | config.assets.quiet = true
64 |
65 | # Raises error for missing translations.
66 | # config.i18n.raise_on_missing_translations = true
67 |
68 | # Annotate rendered view with file names.
69 | # config.action_view.annotate_rendered_view_with_filenames = true
70 |
71 | # Uncomment if you wish to allow Action Cable access from any origin.
72 | # config.action_cable.disable_request_forgery_protection = true
73 |
74 | # Raise error when a before_action's only/except options reference missing actions
75 | config.action_controller.raise_on_missing_callback_actions = true
76 | end
77 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | require "active_support/core_ext/integer/time"
2 |
3 | Rails.application.configure do
4 | # Settings specified here will take precedence over those in config/application.rb.
5 |
6 | # Code is not reloaded between requests.
7 | config.enable_reloading = false
8 |
9 | # Eager load code on boot. This eager loads most of Rails and
10 | # your application in memory, allowing both threaded web servers
11 | # and those relying on copy on write to perform better.
12 | # Rake tasks automatically ignore this option for performance.
13 | config.eager_load = true
14 |
15 | # Full error reports are disabled and caching is turned on.
16 | config.consider_all_requests_local = false
17 | config.action_controller.perform_caching = true
18 |
19 | # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
20 | # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
21 | # config.require_master_key = true
22 |
23 | # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead.
24 | # config.public_file_server.enabled = false
25 |
26 | # Compress CSS using a preprocessor.
27 | # config.assets.css_compressor = :sass
28 |
29 | # Do not fall back to assets pipeline if a precompiled asset is missed.
30 | config.assets.compile = false
31 |
32 | # Enable serving of images, stylesheets, and JavaScripts from an asset server.
33 | # config.asset_host = "http://assets.example.com"
34 |
35 | # Specifies the header that your server uses for sending files.
36 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
37 | # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX
38 |
39 | # Store uploaded files on the local file system (see config/storage.yml for options).
40 | config.active_storage.service = :local
41 |
42 | # Mount Action Cable outside main process or domain.
43 | # config.action_cable.mount_path = nil
44 | # config.action_cable.url = "wss://example.com/cable"
45 | # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ]
46 |
47 | # Assume all access to the app is happening through a SSL-terminating reverse proxy.
48 | # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
49 | # config.assume_ssl = true
50 |
51 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
52 | config.force_ssl = true
53 |
54 | # Log to STDOUT by default
55 | config.logger = ActiveSupport::Logger.new(STDOUT)
56 | .tap { |logger| logger.formatter = ::Logger::Formatter.new }
57 | .then { |logger| ActiveSupport::TaggedLogging.new(logger) }
58 |
59 | # Prepend all log lines with the following tags.
60 | config.log_tags = [ :request_id ]
61 |
62 | # "info" includes generic and useful information about system operation, but avoids logging too much
63 | # information to avoid inadvertent exposure of personally identifiable information (PII). If you
64 | # want to log everything, set the level to "debug".
65 | config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
66 |
67 | # Use a different cache store in production.
68 | # config.cache_store = :mem_cache_store
69 |
70 | # Use a real queuing backend for Active Job (and separate queues per environment).
71 | # config.active_job.queue_adapter = :resque
72 | # config.active_job.queue_name_prefix = "rails_generate_pdf_production"
73 |
74 | config.action_mailer.perform_caching = false
75 |
76 | # Ignore bad email addresses and do not raise email delivery errors.
77 | # Set this to true and configure the email server for immediate delivery to raise delivery errors.
78 | # config.action_mailer.raise_delivery_errors = false
79 |
80 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
81 | # the I18n.default_locale when a translation cannot be found).
82 | config.i18n.fallbacks = true
83 |
84 | # Don't log any deprecations.
85 | config.active_support.report_deprecations = false
86 |
87 | # Do not dump schema after migrations.
88 | config.active_record.dump_schema_after_migration = false
89 |
90 | # Enable DNS rebinding protection and other `Host` header attacks.
91 | # config.hosts = [
92 | # "example.com", # Allow requests from example.com
93 | # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
94 | # ]
95 | # Skip DNS rebinding protection for the default health check endpoint.
96 | # config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
97 | end
98 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | require "active_support/core_ext/integer/time"
2 |
3 | # The test environment is used exclusively to run your application's
4 | # test suite. You never need to work with it otherwise. Remember that
5 | # your test database is "scratch space" for the test suite and is wiped
6 | # and recreated between test runs. Don't rely on the data there!
7 |
8 | Rails.application.configure do
9 | # Settings specified here will take precedence over those in config/application.rb.
10 |
11 | # While tests run files are not watched, reloading is not necessary.
12 | config.enable_reloading = false
13 |
14 | # Eager loading loads your entire application. When running a single test locally,
15 | # this is usually not necessary, and can slow down your test suite. However, it's
16 | # recommended that you enable it in continuous integration systems to ensure eager
17 | # loading is working properly before deploying your code.
18 | config.eager_load = ENV["CI"].present?
19 |
20 | # Configure public file server for tests with Cache-Control for performance.
21 | config.public_file_server.enabled = true
22 | config.public_file_server.headers = {
23 | "Cache-Control" => "public, max-age=#{1.hour.to_i}"
24 | }
25 |
26 | # Show full error reports and disable caching.
27 | config.consider_all_requests_local = true
28 | config.action_controller.perform_caching = false
29 | config.cache_store = :null_store
30 |
31 | # Render exception templates for rescuable exceptions and raise for other exceptions.
32 | config.action_dispatch.show_exceptions = :rescuable
33 |
34 | # Disable request forgery protection in test environment.
35 | config.action_controller.allow_forgery_protection = false
36 |
37 | # Store uploaded files on the local file system in a temporary directory.
38 | config.active_storage.service = :test
39 |
40 | config.action_mailer.perform_caching = false
41 |
42 | # Tell Action Mailer not to deliver emails to the real world.
43 | # The :test delivery method accumulates sent emails in the
44 | # ActionMailer::Base.deliveries array.
45 | config.action_mailer.delivery_method = :test
46 |
47 | # Print deprecation notices to the stderr.
48 | config.active_support.deprecation = :stderr
49 |
50 | # Raise exceptions for disallowed deprecations.
51 | config.active_support.disallowed_deprecation = :raise
52 |
53 | # Tell Active Support which deprecation messages to disallow.
54 | config.active_support.disallowed_deprecation_warnings = []
55 |
56 | # Raises error for missing translations.
57 | # config.i18n.raise_on_missing_translations = true
58 |
59 | # Annotate rendered view with file names.
60 | # config.action_view.annotate_rendered_view_with_filenames = true
61 |
62 | # Raise error when a before_action's only/except options reference missing actions
63 | config.action_controller.raise_on_missing_callback_actions = true
64 | end
65 |
--------------------------------------------------------------------------------
/config/importmap.rb:
--------------------------------------------------------------------------------
1 | # Pin npm packages by running ./bin/importmap
2 |
3 | pin "application"
4 | pin "@hotwired/turbo-rails", to: "turbo.min.js"
5 | pin "@hotwired/stimulus", to: "stimulus.min.js"
6 | pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
7 | pin_all_from "app/javascript/controllers", under: "controllers"
8 |
--------------------------------------------------------------------------------
/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Version of your assets, change this if you want to expire all your assets.
4 | Rails.application.config.assets.version = "1.0"
5 |
6 | # Add additional assets to the asset load path.
7 | # Rails.application.config.assets.paths << Emoji.images_path
8 |
9 | # Precompile additional assets.
10 | # application.js, application.css, and all non-JS/CSS in the app/assets
11 | # folder are already added.
12 | # Rails.application.config.assets.precompile += %w( admin.js admin.css )
13 |
--------------------------------------------------------------------------------
/config/initializers/content_security_policy.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Define an application-wide content security policy.
4 | # See the Securing Rails Applications Guide for more information:
5 | # https://guides.rubyonrails.org/security.html#content-security-policy-header
6 |
7 | # Rails.application.configure do
8 | # config.content_security_policy do |policy|
9 | # policy.default_src :self, :https
10 | # policy.font_src :self, :https, :data
11 | # policy.img_src :self, :https, :data
12 | # policy.object_src :none
13 | # policy.script_src :self, :https
14 | # policy.style_src :self, :https
15 | # # Specify URI for violation reports
16 | # # policy.report_uri "/csp-violation-report-endpoint"
17 | # end
18 | #
19 | # # Generate session nonces for permitted importmap, inline scripts, and inline styles.
20 | # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
21 | # config.content_security_policy_nonce_directives = %w(script-src style-src)
22 | #
23 | # # Report violations without enforcing the policy.
24 | # # config.content_security_policy_report_only = true
25 | # end
26 |
--------------------------------------------------------------------------------
/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
4 | # Use this to limit dissemination of sensitive information.
5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
6 | Rails.application.config.filter_parameters += [
7 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
8 | ]
9 |
--------------------------------------------------------------------------------
/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, "\\1en"
8 | # inflect.singular /^(ox)en/i, "\\1"
9 | # inflect.irregular "person", "people"
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym "RESTful"
16 | # end
17 |
--------------------------------------------------------------------------------
/config/initializers/permissions_policy.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Define an application-wide HTTP permissions policy. For further
4 | # information see: https://developers.google.com/web/updates/2018/06/feature-policy
5 |
6 | # Rails.application.config.permissions_policy do |policy|
7 | # policy.camera :none
8 | # policy.gyroscope :none
9 | # policy.microphone :none
10 | # policy.usb :none
11 | # policy.fullscreen :self
12 | # policy.payment :self, "https://secure.example.com"
13 | # end
14 |
--------------------------------------------------------------------------------
/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization and
2 | # are automatically loaded by Rails. If you want to use locales other than
3 | # English, add the necessary files in this directory.
4 | #
5 | # To use the locales, use `I18n.t`:
6 | #
7 | # I18n.t "hello"
8 | #
9 | # In views, this is aliased to just `t`:
10 | #
11 | # <%= t("hello") %>
12 | #
13 | # To use a different locale, set it with `I18n.locale`:
14 | #
15 | # I18n.locale = :es
16 | #
17 | # This would use the information in config/locales/es.yml.
18 | #
19 | # To learn more about the API, please read the Rails Internationalization guide
20 | # at https://guides.rubyonrails.org/i18n.html.
21 | #
22 | # Be aware that YAML interprets the following case-insensitive strings as
23 | # booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings
24 | # must be quoted to be interpreted as strings. For example:
25 | #
26 | # en:
27 | # "yes": yup
28 | # enabled: "ON"
29 |
30 | en:
31 | hello: "Hello world"
32 |
--------------------------------------------------------------------------------
/config/puma.rb:
--------------------------------------------------------------------------------
1 | # This configuration file will be evaluated by Puma. The top-level methods that
2 | # are invoked here are part of Puma's configuration DSL. For more information
3 | # about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.
4 |
5 | # Puma can serve each request in a thread from an internal thread pool.
6 | # The `threads` method setting takes two numbers: a minimum and maximum.
7 | # Any libraries that use thread pools should be configured to match
8 | # the maximum value specified for Puma. Default is set to 5 threads for minimum
9 | # and maximum; this matches the default thread size of Active Record.
10 | max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
11 | min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
12 | threads min_threads_count, max_threads_count
13 |
14 | # Specifies that the worker count should equal the number of processors in production.
15 | if ENV["RAILS_ENV"] == "production"
16 | require "concurrent-ruby"
17 | worker_count = Integer(ENV.fetch("WEB_CONCURRENCY") { Concurrent.physical_processor_count })
18 | workers worker_count if worker_count > 1
19 | end
20 |
21 | # Specifies the `worker_timeout` threshold that Puma will use to wait before
22 | # terminating a worker in development environments.
23 | worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
24 |
25 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
26 | port ENV.fetch("PORT") { 3000 }
27 |
28 | # Specifies the `environment` that Puma will run in.
29 | environment ENV.fetch("RAILS_ENV") { "development" }
30 |
31 | # Specifies the `pidfile` that Puma will use.
32 | pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
33 |
34 | # Allow puma to be restarted by `bin/rails restart` command.
35 | plugin :tmp_restart
36 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | root 'invoices#index'
3 |
4 | resources :invoices, only: [:index, :show]
5 | get 'invoices/index'
6 | get 'invoices/show'
7 | end
8 |
9 |
--------------------------------------------------------------------------------
/config/storage.yml:
--------------------------------------------------------------------------------
1 | test:
2 | service: Disk
3 | root: <%= Rails.root.join("tmp/storage") %>
4 |
5 | local:
6 | service: Disk
7 | root: <%= Rails.root.join("storage") %>
8 |
9 | # Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
10 | # amazon:
11 | # service: S3
12 | # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
13 | # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
14 | # region: us-east-1
15 | # bucket: your_own_bucket-<%= Rails.env %>
16 |
17 | # Remember not to checkin your GCS keyfile to a repository
18 | # google:
19 | # service: GCS
20 | # project: your_project
21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
22 | # bucket: your_own_bucket-<%= Rails.env %>
23 |
24 | # Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
25 | # microsoft:
26 | # service: AzureStorage
27 | # storage_account_name: your_account_name
28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
29 | # container: your_container_name-<%= Rails.env %>
30 |
31 | # mirror:
32 | # service: Mirror
33 | # primary: local
34 | # mirrors: [ amazon, google, microsoft ]
35 |
--------------------------------------------------------------------------------
/db/migrate/20240410012906_create_invoices.rb:
--------------------------------------------------------------------------------
1 | class CreateInvoices < ActiveRecord::Migration[7.1]
2 | def change
3 | create_table :invoices do |t|
4 | t.string :from_full_name
5 | t.string :from_address
6 | t.string :from_email
7 | t.string :from_phone
8 | t.string :to_full_name
9 | t.string :to_address
10 | t.string :to_email
11 | t.string :to_phone
12 | t.string :status
13 | t.decimal :discount
14 | t.decimal :vat
15 |
16 | t.timestamps
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/db/migrate/20240410013013_create_invoice_items.rb:
--------------------------------------------------------------------------------
1 | class CreateInvoiceItems < ActiveRecord::Migration[7.1]
2 | def change
3 | create_table :invoice_items do |t|
4 | t.string :name
5 | t.string :description
6 | t.decimal :price
7 | t.integer :qty
8 | t.references :invoice, null: false, foreign_key: true
9 |
10 | t.timestamps
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/db/schema.rb:
--------------------------------------------------------------------------------
1 | # This file is auto-generated from the current state of the database. Instead
2 | # of editing this file, please use the migrations feature of Active Record to
3 | # incrementally modify your database, and then regenerate this schema definition.
4 | #
5 | # This file is the source Rails uses to define your schema when running `bin/rails
6 | # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7 | # be faster and is potentially less error prone than running all of your
8 | # migrations from scratch. Old migrations may fail to apply correctly if those
9 | # migrations use external dependencies or application code.
10 | #
11 | # It's strongly recommended that you check this file into your version control system.
12 |
13 | ActiveRecord::Schema[7.1].define(version: 2024_04_10_013013) do
14 | create_table "invoice_items", force: :cascade do |t|
15 | t.string "name"
16 | t.string "description"
17 | t.decimal "price"
18 | t.integer "qty"
19 | t.integer "invoice_id", null: false
20 | t.datetime "created_at", null: false
21 | t.datetime "updated_at", null: false
22 | t.index ["invoice_id"], name: "index_invoice_items_on_invoice_id"
23 | end
24 |
25 | create_table "invoices", force: :cascade do |t|
26 | t.string "from_full_name"
27 | t.string "from_address"
28 | t.string "from_email"
29 | t.string "from_phone"
30 | t.string "to_full_name"
31 | t.string "to_address"
32 | t.string "to_email"
33 | t.string "to_phone"
34 | t.string "status"
35 | t.decimal "discount"
36 | t.decimal "vat"
37 | t.datetime "created_at", null: false
38 | t.datetime "updated_at", null: false
39 | end
40 |
41 | add_foreign_key "invoice_items", "invoices"
42 | end
43 |
--------------------------------------------------------------------------------
/db/seeds.rb:
--------------------------------------------------------------------------------
1 | STATUSES = ["draft", "sent", "paid"]
2 | USERS = [
3 | {
4 | full_name: "Earl A. Gott",
5 | address: "1923 Stiles Street, Pittsburgh, PA 15226",
6 | email: "earlagott@rhyta.com",
7 | phone: "412-571-8270"
8 | },
9 | {
10 | full_name: "Rachelle S. Vargas",
11 | address: "974 Haymond Rocks Road, Scottsburg, OR 97473",
12 | email: "rachellesvargas@dayrep.com",
13 | phone: "541-587-6332"
14 | },
15 | {
16 | full_name: "Gladys H. Sheffield",
17 | address: "1626 Hidden Meadow Drive, Des Lacs, ND 58733",
18 | email: "gladyshsheffield@rhyta.com",
19 | phone: "701-725-9343"
20 | },
21 | {
22 | full_name: "Effie L. Goode",
23 | address: "3889 Dogwood Lane, Tucson, AZ 85710",
24 | email: "effielgoode@rhyta.com",
25 | phone: "520-731-5031"
26 | },
27 | {
28 | full_name: "Monique D. Estep",
29 | address: "957 Hamill Avenue, San Diego, CA 92103",
30 | email: "moniquedestep@dayrep.com",
31 | phone: "858-360-1802"
32 | },
33 | {
34 | full_name: "Timothy I. Atwood",
35 | address: "3402 Raver Croft Drive, Chattanooga, TN 37421",
36 | email: "timothyiatwood@teleworm.us",
37 | phone: "423-645-9346"
38 | },
39 | {
40 | full_name: "Sherry F. Maldonado",
41 | address: "3058 Freedom Lane, Stockton, CA 95202",
42 | email: "sherryfmaldonado@armyspy.com",
43 | phone: "209-461-8106"
44 | },
45 | {
46 | full_name: "Wendy A. Collins",
47 | address: "2824 Broadway Street, Charleston, SC 29405",
48 | email: "wendyacollins@teleworm.us",
49 | phone: "843-744-5410"
50 | },
51 | {
52 | full_name: "Michelle J. Horton",
53 | address: "2125 Green Hill Road, Springdale, AR 72764",
54 | email: "michellejhorton@rhyta.com",
55 | phone: "479-361-1375"
56 | },
57 | {
58 | full_name: "Marc S. Irizarry",
59 | address: "4514 Big Elm, Richmond, MO 64085",
60 | email: "marcsirizarry@jourrapide.com",
61 | phone: "816-776-0200"
62 | }
63 | ]
64 |
65 | PRODUCTS = [
66 | {
67 | name: "Nestea - Ice Tea, Diet",
68 | price: 50.7,
69 | qty: 8,
70 | description: "Team-oriented logistical policy"
71 | },
72 | {
73 | name: "Pork - Hock And Feet Attached",
74 | price: 39.17,
75 | qty: 10,
76 | description: "Programmable contextually-based local area network"
77 | },
78 | {
79 | name: "Squash - Acorn",
80 | price: 35.54,
81 | qty: 1,
82 | description: "Down-sized zero administration productivity"
83 | },
84 | {
85 | name: "Carbonated Water - Cherry",
86 | price: 34.83,
87 | qty: 10,
88 | description: "Seamless transitional installation"
89 | },
90 | {
91 | name: "Tea - Lemon Green Tea",
92 | price: 22.13,
93 | qty: 7,
94 | description: "Advanced background emulation"
95 | },
96 | {
97 | name: "Bread - Pita",
98 | price: 34.94,
99 | qty: 2,
100 | description: "Automated tangible system engine"
101 | },
102 | {
103 | name: "Soup - Knorr, Classic Can. Chili",
104 | price: 9.9,
105 | qty: 9,
106 | description: "Enhanced scalable conglomeration"
107 | },
108 | {
109 | name: "Pork - Ham, Virginia",
110 | price: 74.52,
111 | qty: 7,
112 | description: "Automated optimizing policy"
113 | },
114 | {
115 | name: "Capers - Ox Eye Daisy",
116 | price: 8.79,
117 | qty: 2,
118 | description: "Integrated asynchronous local area network"
119 | },
120 | {
121 | name: "Tomatoes",
122 | price: 88.7,
123 | qty: 5,
124 | description: "Expanded upward-trending paradigm"
125 | },
126 | {
127 | name: "Sword Pick Asst",
128 | price: 21.87,
129 | qty: 5,
130 | description: "Switchable logistical protocol"
131 | },
132 | {
133 | name: "Beans - Black Bean, Canned",
134 | price: 71.19,
135 | qty: 5,
136 | description: "Cross-group static challenge"
137 | },
138 | {
139 | name: "Oil - Truffle, Black",
140 | price: 75.6,
141 | qty: 1,
142 | description: "Robust contextually-based Graphical User Interface"
143 | },
144 | {
145 | name: "Breadfruit",
146 | price: 66.78,
147 | qty: 8,
148 | description: "Inverse mission-critical circuit"
149 | },
150 | {
151 | name: "Soupcontfoam16oz 116con",
152 | price: 22.27,
153 | qty: 5,
154 | description: "Customer-focused bandwidth-monitored architecture"
155 | },
156 | {
157 | name: "Vodka - Smirnoff",
158 | price: 13.77,
159 | qty: 7,
160 | description: "Object-based demand-driven conglomeration"
161 | },
162 | {
163 | name: "Beans - Kidney White",
164 | price: 48.64,
165 | qty: 2,
166 | description: "Customizable background product"
167 | },
168 | {
169 | name: "Filter - Coffee",
170 | price: 33.75,
171 | qty: 2,
172 | description: "Up-sized actuating moratorium"
173 | },
174 | {
175 | name: "Ice Cream - Life Savers",
176 | price: 71.39,
177 | qty: 1,
178 | description: "Cloned optimal benchmark"
179 | },
180 | {
181 | name: "Cheese - Gorgonzola",
182 | price: 23.66,
183 | qty: 6,
184 | description: "Stand-alone reciprocal architecture"
185 | }
186 | ]
187 |
188 | Invoice.all.destroy_all
189 |
190 | 10.times do
191 | from = USERS[rand(0..9)]
192 | to = USERS[rand(0..9)]
193 |
194 | invoice = Invoice.create(
195 | status: STATUSES[rand(0..2)],
196 | from_full_name: from[:full_name],
197 | from_address: from[:address],
198 | from_email: from[:email],
199 | from_phone: from[:phone],
200 | to_full_name: to[:full_name],
201 | to_address: to[:address],
202 | to_email: to[:email],
203 | to_phone: to[:phone],
204 | discount: rand(0.0..20).round(2),
205 | vat: [5, 10, 15, 20][rand(0..3)]
206 | )
207 |
208 | (rand(1..5)).times do
209 | product = PRODUCTS[rand(0..19)]
210 | invoice_item = InvoiceItem.create(
211 | name: product[:name],
212 | description: product[:description],
213 | price: product[:price],
214 | qty: product[:qty],
215 | invoice: invoice
216 | )
217 | end
218 |
219 | end
--------------------------------------------------------------------------------
/lib/assets/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/lib/assets/.keep
--------------------------------------------------------------------------------
/lib/tasks/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/lib/tasks/.keep
--------------------------------------------------------------------------------
/log/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/log/.keep
--------------------------------------------------------------------------------
/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The page you were looking for doesn't exist (404)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
The page you were looking for doesn't exist.
62 |
You may have mistyped the address or the page may have moved.
63 |
64 |
If you are the application owner check the logs for more information.
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
The change you wanted was rejected.
62 |
Maybe you tried to change something you didn't have access to.
63 |
64 |
If you are the application owner check the logs for more information.
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/public/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | We're sorry, but something went wrong (500)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
We're sorry, but something went wrong.
62 |
63 |
If you are the application owner check the logs for more information.
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/public/apple-touch-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/public/apple-touch-icon-precomposed.png
--------------------------------------------------------------------------------
/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/public/favicon.ico
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 |
--------------------------------------------------------------------------------
/storage/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/storage/.keep
--------------------------------------------------------------------------------
/test/application_system_test_case.rb:
--------------------------------------------------------------------------------
1 | require "test_helper"
2 |
3 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
4 | driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
5 | end
6 |
--------------------------------------------------------------------------------
/test/channels/application_cable/connection_test.rb:
--------------------------------------------------------------------------------
1 | require "test_helper"
2 |
3 | module ApplicationCable
4 | class ConnectionTest < ActionCable::Connection::TestCase
5 | # test "connects with cookies" do
6 | # cookies.signed[:user_id] = 42
7 | #
8 | # connect
9 | #
10 | # assert_equal connection.user_id, "42"
11 | # end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/test/controllers/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/test/controllers/.keep
--------------------------------------------------------------------------------
/test/controllers/invoices_controller_test.rb:
--------------------------------------------------------------------------------
1 | require "test_helper"
2 |
3 | class InvoicesControllerTest < ActionDispatch::IntegrationTest
4 | test "should get index" do
5 | get invoices_index_url
6 | assert_response :success
7 | end
8 |
9 | test "should get show" do
10 | get invoices_show_url
11 | assert_response :success
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/test/fixtures/files/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/test/fixtures/files/.keep
--------------------------------------------------------------------------------
/test/fixtures/invoice_items.yml:
--------------------------------------------------------------------------------
1 | # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2 |
3 | one:
4 | name: MyString
5 | description: MyString
6 | price: 9.99
7 | qty: 1
8 | invoice: one
9 |
10 | two:
11 | name: MyString
12 | description: MyString
13 | price: 9.99
14 | qty: 1
15 | invoice: two
16 |
--------------------------------------------------------------------------------
/test/fixtures/invoices.yml:
--------------------------------------------------------------------------------
1 | # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2 |
3 | one:
4 | from_full_name: MyString
5 | from_address: MyString
6 | from_email: MyString
7 | from_phone: MyString
8 | to_full_name: MyString
9 | to_address: MyString
10 | to_email: MyString
11 | to_phone: MyString
12 | status: MyString
13 | discount: 9.99
14 | vat: 9.99
15 |
16 | two:
17 | from_full_name: MyString
18 | from_address: MyString
19 | from_email: MyString
20 | from_phone: MyString
21 | to_full_name: MyString
22 | to_address: MyString
23 | to_email: MyString
24 | to_phone: MyString
25 | status: MyString
26 | discount: 9.99
27 | vat: 9.99
28 |
--------------------------------------------------------------------------------
/test/helpers/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/test/helpers/.keep
--------------------------------------------------------------------------------
/test/integration/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/test/integration/.keep
--------------------------------------------------------------------------------
/test/mailers/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/test/mailers/.keep
--------------------------------------------------------------------------------
/test/models/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/test/models/.keep
--------------------------------------------------------------------------------
/test/models/invoice_item_test.rb:
--------------------------------------------------------------------------------
1 | require "test_helper"
2 |
3 | class InvoiceItemTest < ActiveSupport::TestCase
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/test/models/invoice_test.rb:
--------------------------------------------------------------------------------
1 | require "test_helper"
2 |
3 | class InvoiceTest < ActiveSupport::TestCase
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/test/system/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/test/system/.keep
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | ENV["RAILS_ENV"] ||= "test"
2 | require_relative "../config/environment"
3 | require "rails/test_help"
4 |
5 | module ActiveSupport
6 | class TestCase
7 | # Run tests in parallel with specified workers
8 | parallelize(workers: :number_of_processors)
9 |
10 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
11 | fixtures :all
12 |
13 | # Add more helper methods to be used by all tests here...
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/tmp/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/tmp/.keep
--------------------------------------------------------------------------------
/tmp/pids/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/tmp/pids/.keep
--------------------------------------------------------------------------------
/tmp/storage/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/tmp/storage/.keep
--------------------------------------------------------------------------------
/vendor/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/vendor/.keep
--------------------------------------------------------------------------------
/vendor/javascript/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ApryseSDK/rails-generate-pdf/c86ab7d6a3e9ddac1b27eec1d81ed79714ac43fc/vendor/javascript/.keep
--------------------------------------------------------------------------------