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 }
// 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 }