template-archive icon indicating copy to clipboard operation
template-archive copied to clipboard

Format numbers as words

Open dselman opened this issue 5 years ago • 24 comments

Many contracts included numbers, which are also spelled out in words. IANAL so I can't speak to why this is important, but it is commonplace. I have seen several contracts recently where the number and the words are actually out of sync, which created considerable confusion!

E.g.

 "within ten (15) days of the Effective Date"

Which should presumably have been:

 "within ten (10) days of the Effective Date"

Describe the solution you'd like Support a formula that can be used to spell a number out as English language words.

Describe alternatives you've considered A TemplateMark formatting instruction to format numbers as words.

Additional context

  • https://www.npmjs.com/package/to-words
  • https://www.gentrylawgroup.com/writing-out-numbers-in-contracts/
  • https://www.quora.com/Why-are-numbers-expressed-in-legal-documents-in-both-numeric-and-written-form
  • https://weagree.com/drafting-principles/6-typical-drafting-habits-and-legalese/6-3-numbers-and-formulae/a-best-practice-rules-on-drafting-numbers/

dselman avatar Oct 07 '20 09:10 dselman

Q: Would we want to support parsing of those (e.g., as an alternative to the digit-based syntax) or would this behave more like an Ergo formula?

jeromesimeon avatar Oct 07 '20 14:10 jeromesimeon

My initial instinct was that this should behave like a formula, but then I read: https://weagree.com/drafting-principles/6-typical-drafting-habits-and-legalese/6-3-numbers-and-formulae/a-best-practice-rules-on-drafting-numbers/

Which makes the case for drafting small numbers as words, and occasionally including both the number and the word form. Perhaps we can raise this question to the lawyers in the group?

dselman avatar Oct 07 '20 14:10 dselman

Some consider it unnecessary and bad form to state the same thing twice. However, imo, it is a fairly common practice and unlikely to go away soon.

Often there are mismatches like this is due to: (1) suggested changes in certain editors that are not persisted in the document, and certain changes are accepted and others are not; or (2) a value is changed multiple times and tracked changes become unwieldy, raising the same issue.

There is no reason the written value and the numerical value should differ.

My $0.02 is that it should be left up to the drafter as to when and how they want to use dual representations of a value (i.e. one form is not mandated), but that an error is raised when parenthesis are used after one representation and the values do not correlate. For example:

10 (ten) is valid. 15 (ten) is invalid. ten (10) is valid. fifteen (10) is invalid.

Perhaps this could be a specified type like DateTime?

peterhunn avatar Oct 07 '20 15:10 peterhunn

@peterhunn Thanks for the insights. Very useful.

Perhaps this could be a specified type like DateTime?

That's an interesting idea. This could be an extension to the format (e.g., WWWW or NNNN for long-worded numbers)

One more question: do you sometimes have only the words but not the corresponding number? (e.g., in the amount of ten thousands dollars.

jeromesimeon avatar Oct 07 '20 15:10 jeromesimeon

One more question: do you sometimes have only the words but not the corresponding number? (e.g., in the amount of ten thousands dollars.

Yes, some best practices are to use words for small numbers only. The link has some examples.

dselman avatar Oct 07 '20 15:10 dselman

One more question: do you sometimes have only the words but not the corresponding number? (e.g., in the amount of ten thousands dollars.

Yes, some best practices are to use words for small numbers only. The link has some examples.

That means very weird (possibly difficult) parsing. Who decides what a small number is? Do we need that feature?

jeromesimeon avatar Oct 07 '20 15:10 jeromesimeon

I think we can start with a formula that renders a number as words. I suspect that will solve 90% of the problem... We can then wait and see if additional requirements arrive.

dselman avatar Oct 07 '20 15:10 dselman

I think we can start with a formula that renders a number as words. I suspect that will solve 90% of the problem... We can then wait and see if additional requirements arrive.

Two questions:

  • Do we really need this feature? This does not feel like a priority
  • I like @peterhunn 's proposal to do it as a formatting option for the amount. This means you do not have to add this kind of functionality to the Ergo compiler (and down the road support it in WASM, etc) -- at least initially.

jeromesimeon avatar Oct 07 '20 15:10 jeromesimeon

  1. I frequently run into contracts that spell out numeric amounts in words. I'd guess that 50% of the contracts I see have it somewhere, so it's definitely something people have to manually keep in sync right now. How much it bothers people to do that manually (keeping a Double/Integer/Long variable in sync with a String variable) I am not sure.

  2. Not sure I understand this. If it becomes an as formatting option on the {{variable}} in TemplateMark then I'd expect it to parse as well as draft for consistency. Are you referring to something else?

dselman avatar Oct 07 '20 15:10 dselman

  • I frequently run into contracts that spell out numeric amounts in words. I'd guess that 50% of the contracts I see have it somewhere, so it's definitely something people have to manually keep in sync right now.
  • Not sure I understand this. If it becomes an as formatting option on the {{variable}} in TemplateMark then I'd expect it to parse as well as draft for consistency. Are you referring to something else?

I was thinking the format could make the number itself mandatory. so e.g., WWWW 0,0.00 would be valid but not WWWW so you can always parse from the number and check that it is consistent with the words.

But I could certainly add it to the new Ergo compiler after we've merged it in if we feel this is where it should be.

jeromesimeon avatar Oct 07 '20 16:10 jeromesimeon

Discussed during a Tech WG call. This reference is interesting:

https://www.delawarelitigation.com/2019/01/articles/chancery-court-updates/words-prevail-over-conflicting-numbers-in-contract/#:~:text=A%20recent%20Delaware%20Court%20of,that%20is%20inconsistent%20and%20contradictory.

jeromesimeon avatar Oct 07 '20 21:10 jeromesimeon

@jeromesimeon Is this issue still available for work.I would like to work as well share my ideas upon this issue.

Cronus1007 avatar Mar 19 '21 18:03 Cronus1007

@jeromesimeon Is this issue still available for work.I would like to work as well share my ideas upon this issue.

Sounds great @Cronus1007

Would be great if there was a library we can use for this?

jeromesimeon avatar Mar 19 '21 18:03 jeromesimeon

@jeromesimeon The plan that I intend to follow to resolve this issue :-

  • [ ] NPM package to be used this
  • [ ] Files where the desired changes need to be done (Will need a little bit of help for this step)
  • [ ] Little instance of code to be written
// Require Statement
const { ToWords } = require('to-words');
// Config for package
const toWords = new ToWords({
  localeCode: 'en-US',
  converterOptions: {
    currency: true,
    ignoreDecimal: true,
    ignoreZeroCurrency: false,
  }
let words = toWords.convert(123);
});

Cronus1007 avatar Mar 22 '21 12:03 Cronus1007

@jeromesimeon The plan that I intend to follow to resolve this issue :-

  • [ ] NPM package to be used this
  • [ ] Files where the desired changes need to be done (Will need a little bit of help for this step)
  • [ ] Little instance of code to be written
// Require Statement
const { ToWords } = require('to-words');
// Config for package
const toWords = new ToWords({
  localeCode: 'en-US',
  converterOptions: {
    currency: true,
    ignoreDecimal: true,
    ignoreZeroCurrency: false,
  }
let words = toWords.convert(123);
});

Looks good! One of the challenges we have in AP is that we also parse contract text. Not sure how to make that feature work with this. Maybe @dselman will have some thoughts.

jeromesimeon avatar Mar 22 '21 12:03 jeromesimeon

@jeromesimeon Sure lets wait for @dselman inputs and then I shall create a draft pr for maintainers to have a look.

Cronus1007 avatar Mar 22 '21 12:03 Cronus1007

@jeromesimeon Can you plzz refer me the files that parse contract text and shall I start implementing this feature?

Cronus1007 avatar Mar 24 '21 19:03 Cronus1007

@jeromesimeon Can you plzz refer me the files that parse contract text and shall I start implementing this feature?

hi @Cronus1007 The parser is actually located in the markdown-transform project. More specifically the parsing for natural numbers (Integer) is in this place https://github.com/accordproject/markdown-transform/tree/master/packages/markdown-template/lib/plugins/Integer

Yet it still feels like a pretty ambitious thing to try and parse numbers written in English format (I'd be happy to be wrong of course). I would be interested to get further feedback on this from e.g., @dselman @mttrbrts or @peterhunn who created this issue before sending you on this journey :)

[ I believe this is discussion is the reason this specific issue is labelled as "Challenging" ]

jeromesimeon avatar Mar 24 '21 19:03 jeromesimeon

@jeromesimeon Okk so first shall I give a mock of the code in here only and then will start implementing this issue.

Cronus1007 avatar Mar 24 '21 19:03 Cronus1007

Reading through a little bit, we might want to offer a "format" for numbers that lets you add an English form. Here is the corresponding part of the documentation for monetary amounts and dates https://docs.accordproject.org/docs/markup-templatemark.html#formatted-variables

Maybe something along those lines would make sense?

jeromesimeon avatar Mar 24 '21 19:03 jeromesimeon

Reading through a little bit, we might want to offer a "format" for numbers that lets you add an English form. Here is the corresponding part of the documentation for monetary amounts and dates https://docs.accordproject.org/docs/markup-templatemark.html#formatted-variables

Maybe something along those lines would make sense?

😊 This was, I think, what @peterhunn was suggesting here. I just forgot!

jeromesimeon avatar Mar 24 '21 19:03 jeromesimeon

@irmerk @jeromesimeon @dselman @mttrbrts @DianaLease @Michael-Grover @peterhunn @algomaster99 Implementation idea for this since it handles formation of integers

const { ToWords } = require('to-words');

/**
 * Creates config Options for to-words package
 */
// This config is just a mock for cuurency but can be handled for percentages,months,days
const toWords = new ToWords({
    localeCode: 'en-US',
    converterOptions: {
        currency: true,
        ignoreDecimal: false,
        ignoreZeroCurrency: false,
    }
});
function draftInteger(value) {
    return '(' + toWords.convert(value) + ') ' + value;
}

toWords.convert(value) The required changes to implement this feature. Few things that we should follow while making this change:-

  • [ ] The integer can't be bigger than 10^18.(Overflow Problem)
  • [ ] For numbers greater than 1000 like 1234 (my opinion) text displayed (One Thousand) i.e. Representing the Most Significant Digit
  • [ ] If the user updated a number the functionality will make the text updated as well.(Can be tested via writing few unit test cases for this)

@dselman Thanks for sharing this document.This could help a lot in formation of guidelines. https://weagree.com/drafting-principles/6-typical-drafting-habits-and-legalese/6-3-numbers-and-formulae/a-best-practice-rules-on-drafting-numbers/

Cronus1007 avatar Mar 25 '21 13:03 Cronus1007

15 (ten) is invalid. fifteen (10) is invalid.

Perhaps this could be a specified type like DateTime?

These cases can't arise with this implementation since if the user changes the value then draftInteger functions gets triggered and inherited use of toWords in the function will make to automatically change the written text as well.

Cronus1007 avatar Mar 25 '21 13:03 Cronus1007

@jeromesimeon The clause will look something like this.This change has only been made for integers not for double, long and Monetary Amount. oie_L4H3JqzfZ7kl oie_4il3isCL6MW8

Cronus1007 avatar Mar 30 '21 16:03 Cronus1007