通常の請求書を想像してみてください。そこにはいくつかの項目があります。各アイテムには、とりわけ、数量と単位あたりの価格 (単位と説明) があります。
各アイテムの合計金額は、数量 * 単位あたりの価格のように計算されます。これはアイテムごとに行われます。次に、請求書全体の正味金額は、すべての合計の合計です。VAT を追加すると、請求書の総額が得られます。
これは、Rails アプリでやろうとしていることです。請求書には多くの項目があり、それらのネストされた属性を受け入れます。通常、これはすべて正常に機能します。
ロジックに従って、手動で入力する必要があるのは、単位あたりの価格と各アイテムの数量、および請求書の VAT だけです。合計とその結果の正味額および総額は、自動的に計算されます。before_save
フィルターを使用してこれを実現したいと思います。
これが私の請求書モデルです:
before_save :calculate_net_amount, :calculate_gross_amount
def calculate_net_amount
self.items do |item|
self.net_amount += item.total
end
end
def calculate_gross_amount
self.gross_amount = self.net_amount * (1 + self.vat_rate)
end
これはアイテムモデルです:
before_save :calculate_total
def calculate_total
self.total = self.quantity * self.price_per_unit
end
そして、これが失敗している私の仕様です:
it "calculates the net amount from all item totals" do
invoice = FactoryGirl.build(:invoice)
item = invoice.items.build(quantity: 2, unit: "Unit", description: "Desc", price_per_unit: 2)
invoice.save
invoice.net_amount.should == 4
end
この請求書ファクトリを使用します。
FactoryGirl.define do
factory :invoice do
association :client
currency "EUR"
vat_rate 0.19
net_amount 1
payment_on "2013-01-01"
status "paid"
end
end
このテストは基本的に次のことを行います: どちらも USD 2 の 2 つの請求書の正味額は USD 4 である必要があります。代わりに、テストは 1 を返します。これは工場からのものであり、明らかに上書きされていないようです。フィクスチャから削除すると、nil オブジェクトで * を使用できないため、総量を計算できないと表示されます。
フィルターとそれらが呼び出される順序に何か問題があると想定しています-合計金額は正しく計算されているため、間違っているのは calculate_net_amount メソッドに関する何かである必要があり、その結果、もはや総量。
私が間違っていることがわかりますか?