Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt article & group sorted order PDF (solves #49) #87

Open
wants to merge 52 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
ecf7c17
Article units squash
lentschi Mar 16, 2024
cfbe5b7
Fix typos and removed dead code
lentschi Mar 22, 2024
2a42360
Remove obsolete testing shared db along with its tasks
lentschi Mar 22, 2024
539613b
Added no-upstream for byebug
lentschi Mar 22, 2024
ba11e4b
On #47 Adapt unit ratio export/import to be interpreted as a conversi…
lentschi Mar 23, 2024
5bcea4a
On #21: stock orders: prohibit 'ordering' more than what's on stock
lentschi Mar 23, 2024
b39cb77
Started with #8
lentschi Mar 23, 2024
51c2703
Fixes #53
lentschi Mar 29, 2024
37d1b27
fix: round article quantity in order article pdf
yksflip Mar 29, 2024
d831092
Don't show articles migrate button for newly created suppliers
lentschi Mar 31, 2024
acc982d
On #8: All existing specs pass now
lentschi Apr 6, 2024
e5a2398
Rubocop fixes
lentschi Apr 6, 2024
74ac2f3
First proposal for #35
lentschi Apr 6, 2024
cb38646
On #15: Open with inset button instead of on every focus
lentschi Apr 6, 2024
8b6d01a
Fixes #56
lentschi Apr 12, 2024
90c4fcb
On #35: Adapted list of default units
lentschi Apr 12, 2024
1c9612c
Fixes #42
lentschi Apr 12, 2024
4106ee8
Fixes #42 again
lentschi Apr 12, 2024
0abb392
On #8: Implemented article version model unit tests
lentschi Apr 12, 2024
eb33fe8
On #8: Adapted article version unit tests
lentschi Apr 19, 2024
8ed4bb9
On #35 Added missing metric default unit: GRM
lentschi Apr 19, 2024
be44773
Fixes #56 again
lentschi Apr 19, 2024
6eb79bf
Fixes #59
lentschi Apr 21, 2024
a51304b
Fixes #58
lentschi Apr 21, 2024
3939556
Fixes #60
lentschi Apr 21, 2024
3941539
Fixes #65
lentschi Apr 26, 2024
6c77080
Fixes #62
lentschi Apr 26, 2024
476e322
On #8: Fixes failing tests on github
lentschi Apr 28, 2024
3ce6390
On #8: Article units integration tests
lentschi May 1, 2024
c67a465
On #8: Started with unit tests for supplier article sharing
lentschi May 5, 2024
de4792a
Fixes #68
lentschi May 20, 2024
b61b847
Fixes #67
lentschi May 20, 2024
2e19cd3
Fixes #69
lentschi May 24, 2024
2c02208
On #8: Done with sync specs
lentschi May 24, 2024
67041a1
On #15: Fixes conversion popover min-width
lentschi May 24, 2024
2ae2c6d
Fixes #61
lentschi Jun 7, 2024
0754f15
Fixes #73
lentschi Jun 7, 2024
222ada6
Better alias for #71
lentschi Jun 7, 2024
97a3f48
On #64: Add missing unit labels
lentschi Jun 22, 2024
602cff1
On #42: Fax pdf/csv: Decimals dependant on supplier_order_unit's si c…
lentschi Jun 28, 2024
366065f
feat: update seed files (#76)
yksflip Jul 5, 2024
8f87d7e
Fixes #66 (#74)
lentschi Jul 12, 2024
61a2b1a
Workaround for #78
lentschi Jul 13, 2024
681095b
Moved fork's migrations after rebase on upstream/master
lentschi Jul 26, 2024
dec2762
Fixes #85
lentschi Jul 26, 2024
9191f42
Allow price calculation for new records
lentschi Jul 26, 2024
3871c37
Fixes #83
lentschi Jul 26, 2024
756fda0
Another workaround for #78
lentschi Jul 26, 2024
b3bc712
Fixes #81
lentschi Jul 26, 2024
3be31d5
Article CSV: fix #47 and #46 (#84)
twothreenine Jul 26, 2024
3297e5e
Fix unit tests (broken since 3871c37a06f956ab897828e35e75c794d6c7bf53)
lentschi Jul 26, 2024
a8d87d7
Adapt article & group sorted order PDF (solves #49)
twothreenine Jul 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
On #42: Fax pdf/csv: Decimals dependant on supplier_order_unit's si c…
…onvertability (#70)

* On #42: Fax pdf/csv: Decimals dependant on supplier_order_unit's si convertability

* Solve #42: Improve fax PDF, CSV, text

- outsource format_units_to_order to OrderHelper
- fax text: include unit, adjust column width
- fax PDF & text: only include order number if any present

* On #42:

- Adapted order_txt to generalized creating the text table and added
  spec
- Code style fixes for order_fax

* On #42 Fixes error dad0bb9#r143648091

---------

Co-authored-by: twothreenine <leonard_ostler@yahoo.de>
lentschi and twothreenine committed Jul 26, 2024
commit 602cff13c2cee71e269472a6fdef2b2a7ccfa6df
40 changes: 29 additions & 11 deletions app/documents/order_fax.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class OrderFax < OrderPdf
include ArticlesHelper
include OrdersHelper

BATCH_SIZE = 250

@@ -74,28 +75,39 @@ def recipient_paragraph

def articles_paragraph
total = 0
data = [I18n.t('documents.order_fax.rows')]
any_order_number_present = order_articles.where.not(article_version: { order_number: nil }).any?
data = [get_header_labels(!any_order_number_present)]
each_order_article do |oa|
price = oa.article_version.price
subtotal = oa.units_to_order * price
total += subtotal
data << [oa.article_version.order_number,
number_with_precision(oa.units_to_order, precision: 3),
format_supplier_order_unit_with_ratios(oa.price),
oa.article_version.name,
number_to_currency(price),
number_to_currency(subtotal)]
oa_data = []
oa_data += [oa.article_version.order_number] if any_order_number_present
oa_data += [
format_units_to_order(oa),
format_supplier_order_unit_with_ratios(oa.price),
oa.article_version.name,
number_to_currency(price),
number_to_currency(subtotal)
]
data << oa_data
end
data << [I18n.t('documents.order_fax.total'), nil, nil, nil, nil, number_to_currency(total)]

total_row_spacing_columns = [nil] * (any_order_number_present ? 4 : 3)
total_row = [I18n.t('documents.order_fax.total')] + total_row_spacing_columns + [number_to_currency(total)]

data << total_row

table data, cell_style: { size: fontsize(8), overflow: :shrink_to_fit } do |table|
table.header = true
table.cells.border_width = 1
table.cells.border_color = '666666'

table.row(0).border_bottom_width = 2
table.columns(1).align = :right
table.columns(4..5).align = :right
table.row(data.length - 1).columns(0..4).borders = %i[top bottom]
table.columns(-5).align = :right
table.columns(-2..-1).align = :right
table.row(data.length - 1).columns(0).align = :left
table.row(data.length - 1).columns(0..-2).borders = %i[top bottom]
table.row(data.length - 1).columns(0).borders = %i[top bottom left]
table.row(data.length - 1).border_top_width = 2
end
@@ -116,4 +128,10 @@ def order_articles
def each_order_article(&block)
order_articles.find_each_with_order(batch_size: BATCH_SIZE, &block)
end

def get_header_labels(exclude_order_number)
labels = I18n.t('documents.order_fax.rows').clone
labels.delete_at(0) if exclude_order_number
labels
end
end
11 changes: 11 additions & 0 deletions app/helpers/orders_helper.rb
Original file line number Diff line number Diff line change
@@ -23,6 +23,10 @@ def options_for_suppliers_to_select
options_for_select(options)
end

def format_units_to_order(order_article, strip_insignificant_zeros: false)
format_amount(order_article.units_to_order, order_article, strip_insignificant_zeros: strip_insignificant_zeros)
end

# "1×2 ordered, 2×2 billed, 2×2 received"
def units_history_line(order_article, options = {})
if order_article.order.open?
@@ -206,4 +210,11 @@ def receive_button(order, options = {})
class: "btn#{' btn-success' unless order.received?} #{options[:class]}"
end
end

private

def format_amount(amount, order_article, strip_insignificant_zeros: false)
strip_insignificant_zeros = true unless order_article.article_version.supplier_order_unit_is_si_convertible
number_with_precision(amount, precision: 3, strip_insignificant_zeros: strip_insignificant_zeros)
end
end
3 changes: 2 additions & 1 deletion app/lib/order_csv.rb
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
class OrderCsv < RenderCsv
include ApplicationHelper
include ArticlesHelper
include OrdersHelper

def header
[
@@ -19,7 +20,7 @@ def data
@object.order_articles.ordered.includes(:article_version).all.map do |oa|
yield [
oa.article_version.order_number,
number_with_precision(oa.units_to_order, precision: 3),
format_units_to_order(oa, strip_insignificant_zeros: true),
format_supplier_order_unit_with_ratios(oa.article_version),
oa.article_version.name,
number_to_currency(oa.article_version.price),
61 changes: 56 additions & 5 deletions app/lib/order_txt.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
class OrderTxt
include ActionView::Helpers::NumberHelper
include ArticlesHelper
include OrdersHelper

def initialize(order, _options = {})
@order = order
@@ -17,12 +19,61 @@ def to_txt
text += '****** ' + I18n.t('orders.fax.to_address') + "\n\n"
text += "#{FoodsoftConfig[:name]}\n#{contact[:street]}\n#{contact[:zip_code]} #{contact[:city]}\n\n"
text += '****** ' + I18n.t('orders.fax.articles') + "\n\n"
text += format("%8s %8s %s\n", I18n.t('orders.fax.number'), I18n.t('orders.fax.amount'),
I18n.t('orders.fax.name'))
# now display all ordered articles
@order.order_articles.ordered.includes(:article_version).each do |oa|
text += format("%8s %8.3f %s\n", oa.article_version.order_number, oa.units_to_order, oa.article_version.name)

# prepare order_articles data
order_articles = @order.order_articles.ordered.includes(:article_version).order('article_versions.order_number ASC, article_versions.name ASC')
any_number_present = order_articles.where.not(article_version: { order_number: nil }).any?

order_headers = {
number: any_number_present ? { label: I18n.t('orders.fax.number') } : nil,
amount: { label: I18n.t('orders.fax.amount'), align: :right },
unit: { label: I18n.t('orders.fax.unit') },
name: { label: I18n.t('orders.fax.name') }
}.compact

order_positions = order_articles.map do |oa|
number = oa.article_version.order_number || ''
amount = format_units_to_order(oa).to_s
unit = format_supplier_order_unit_with_ratios(oa.price)
{
number: number,
amount: amount,
unit: unit,
name: oa.article_version.name
}
end

text += text_table(order_headers, order_positions)
text
end

private

def text_table(headers, rows)
table_keys = headers.keys
columns = table_keys.each_with_index.map do |key, index|
header = headers[key]
label = header[:label]
{
key: key,
label: label,
align: header[:align],
characters: index + 1 < table_keys.length ? (rows.pluck(key) + [label]).map(&:length).max : nil
}
end

header_txt = columns.map { |column| align_text_column(column[:label], column[:characters], column[:align]) }.join(' ')

rows_texts = rows.map do |row|
columns.map { |column| align_text_column(row[column[:key]], column[:characters], column[:align]) }.join(' ')
end

([header_txt] + rows_texts).join("\n")
end

def align_text_column(text, characters, align)
return text if characters.nil?

align == :right ? text.rjust(characters) : text.ljust(characters)
end
end
1 change: 1 addition & 0 deletions config/locales/de.yml
Original file line number Diff line number Diff line change
@@ -1539,6 +1539,7 @@ de:
heading: Bestellung für %{name}
name: Name
number: Nummer
unit: Einheit
to_address: Versandaddresse
finish:
notice: Die Bestellung wurde beendet.
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
@@ -1543,6 +1543,7 @@ en:
heading: Order for %{name}
name: Name
number: Number
unit: Unit
to_address: Shipping address
finish:
notice: The order has been closed.
49 changes: 49 additions & 0 deletions spec/lib/order_txt_csv_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
require_relative '../spec_helper'

describe OrderTxt do
let(:user) { create(:user, groups: [create(:ordergroup)]) }
let(:order) { create(:order, created_by: user, starts: Date.yesterday, ends: 1.hour.ago, end_action: :auto_close, article_count: 3) }
let(:supplier) { order.supplier }
let(:go) { create(:group_order, order: order, ordergroup: user.ordergroup) }
let(:articles) { order.articles }
let(:order_articles) { order.order_articles }
let(:first_article_version) { articles.first.latest_article_version }
let(:second_article_version) { articles.second.latest_article_version }
let(:third_article_version) { articles.third.latest_article_version }

it 'creates a proper csv table sorted by order_number from an order' do
first_article_version.update(name: 'Short name', supplier_order_unit: 'XPK')
second_article_version.update(name: 'Much longer complicated name', supplier_order_unit: 'KGM')
third_article_version.update(name: 'Quite short name', supplier_order_unit: 'GRM')
order_articles.where(article_version: first_article_version).update(units_to_order: 1)
order_articles.where(article_version: second_article_version).update(units_to_order: 1.421)
order_articles.where(article_version: third_article_version).update(units_to_order: 4.432643311)

result = described_class.new(order).to_txt
expected_table = %(
Number Amount Unit Name
0 1 Package Short name
1 1.421 kg Much longer complicated name
2 4.433 g Quite short name
)
expect(result.strip).to end_with(expected_table.strip)
end

it 'omits the order_number column and sort alphabetically if none of the ordered articles have an order_number' do
first_article_version.update(name: 'Short name', supplier_order_unit: 'XPK', order_number: nil)
second_article_version.update(name: 'Much longer complicated name', supplier_order_unit: 'KGM', order_number: nil)
third_article_version.update(name: 'Quite short name', supplier_order_unit: 'GRM', order_number: nil)
order_articles.where(article_version: first_article_version).update(units_to_order: 1)
order_articles.where(article_version: second_article_version).update(units_to_order: 1.421)
order_articles.where(article_version: third_article_version).update(units_to_order: 4.432643311)

result = described_class.new(order).to_txt
expected_table = %(
Amount Unit Name
1.421 kg Much longer complicated name
4.433 g Quite short name
1 Package Short name
)
expect(result.strip).to end_with(expected_table.strip)
end
end