【问题标题】:Filter order needing changes for invoice calculation?筛选需要更改发票计算的订单?
【发布时间】:2013-01-06 00:24:18
【问题描述】:

想象一张普通的发票:上面有几件物品。每件商品都有数量和每单位价格,除其他外(单位和描述)。

每件商品的总金额计算如下:数量 * 每件价格。 这是为每个项目完成的。那么,整个发票的净额就是所有总额的总和。添加增值税,您就有了发票的总金额。

这就是我试图用我的 Rails 应用程序做的事情。发票有许多项目并接受它们的嵌套属性。一般来说,这一切都很好。

按照逻辑,我只需要手动输入每件商品的价格、每件商品的数量以及发票的增值税。应自动计算总数以及由此产生的净额和总金额。我想使用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

测试基本上做了以下事情: 一张包含 2 件东西的发票,两者都花费 2 美元,其净额应该是 4 美元。相反,测试返回 1,这似乎来自工厂并且显然没有被覆盖。如果我将它从夹具中移除,它会说它不能再计算总金额,因为它不能在任何 nil 对象上使用 *。

我假设我在过滤器和调用它们的顺序上做错了 - 总金额计算正确,所以它必须是有关 calculate_net_amount 方法出错的东西,因此它可以'不再计算总金额。

你能看出我做错了什么吗?

【问题讨论】:

    标签: ruby-on-rails unit-testing rspec tdd


    【解决方案1】:
    self.items do |item|
    

    应该是

    self.items.each do |item|
    

    由于items 是一个访问器,它是一种方法,它在技术上可以占用一个块,但该块没有被调用,因此不会发生求和。这很容易打错。

    顺便说一句,最好用inject求和:

    self.net_amount = self.items.inject(0){|sum, item| sum + item.total}
    

    【讨论】:

    • 谢谢!取得进展......现在它在同一行给我nil can't be coerced into Fixnum - 为什么?难道item.total是nil?
    • 我好像找到了原因。由于我需要物品的总金额,并且这些仅在保存物品时计算,所以我需要先保存物品,然后才保存发票。将来,我不会总是执行这两个步骤的过程 - 有没有办法告诉在发票模型中的保存方法之前是否应该计算项目总数?
    • 通过在calculate_net_amount 方法的循环中执行item.calculate_total 解决了这个问题:) 出于好奇,尽管我说@987654329,是否可以先救孩子,然后再救父母@?
    • 嗯,肯定要分两步,因为物品需要发票的FK,也就是说发票需要一个ID,也就是说最好先保存发票再保存物品,或者它必须保存项目然后更新它们。所以简短的回答是,我不知道,但我猜你在一个地方总结所有的东西是正确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-19
    • 2011-02-10
    • 1970-01-01
    相关资源
    最近更新 更多