示例#1
0
func valByValSub(am Amount, qs map[string]quant.Quant) Amount {
	out := am.Copy()
	for _, q := range qs {
		if old, ok := out.quants[q.ID()]; ok {
			out.quants[q.ID()] = quant.Sub(old, q)
		} else {
			out.quants[q.ID()] = quant.Quant{q.Unit, -q.Val}
		}
	}
	return out
}
示例#2
0
// Sub creates a new amount by subtracting a2 from a1
// TODO : more explanation
func Sub(a1, a2 Amount) Amount {
	out := a1.Copy()
	out = valByValSub(out, a2.quantsWithout())
	for _, q := range a2.QuantsWithByFactAsc() {
		if old, ok := out.quants[q.ID()]; !ok {
			out.quants[q.ID()] = quant.Quant{q.Unit, -q.Val}
		} else {
			if old.Val >= q.Val || q.Val > out.TotalWith() {
				out.quants[q.ID()] = quant.Sub(old, q)
				continue
			}
			current := out.QuantsWithByFactAsc()
			needed := quant.TrimSliceOnTotal(current, q.Total())
			sort.Sort(quant.ByFactDesc(needed))
			missing := q.Total()
			for i, n := range needed {
				left := quant.SliceTotal(needed[i+1:])

				if left == missing {
					continue
				}

				tosub := missing / n.Fact

				if left < missing {
					tosub = (missing - left) / n.Fact
					if tosub*n.Fact != missing-left {
						tosub++
					}
				}

				out.quants[n.ID()] = n.NewSub(tosub)
				missing -= tosub * n.Fact
			}
			if missing > 0 {
				valByValSub(out, map[string]quant.Quant{q.ID(): {q.Unit, missing}})
			}

		}
	}

	return out
}