Skip to content

Instantly share code, notes, and snippets.

@fractalwrench
Last active October 31, 2020 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fractalwrench/ea096b33231fc3edaa56b2c786b54a40 to your computer and use it in GitHub Desktop.
Save fractalwrench/ea096b33231fc3edaa56b2c786b54a40 to your computer and use it in GitHub Desktop.
Receipt Generator Project

Receipt Generator

Make a command line tool that is capable of generation a receipt for any shop.

The product team at your company helpfully gathered requirements from the customer. But as the senior engineer at your company is on holiday and isn't answering your calls, you'll need to create the engineering design yourself! ;)

User requirements

  • Should be a command-line tool that generates a PNG image of a receipt
  • It should also be possible to configure the tool to output as JPG or PDF
  • The tool should accept order information as a JSON string
  • It should be possible to configure the file location where the receipt is output
  • The tool should log an error message if mandatory command line arguments are missing
  • The tool should have a --help option which provides concise documentation on how to use it
  • The printer has a fixed width of 568 pixels and needs a margin of at least 10% on either side
  • Should always display the company logo at the top of the receipt
  • Should display the address at the top of the receipt (if given)
  • Should display the phone number at the top of the receipt (if given)
  • Should display the website at the top of the receipt (if given)
  • Should display the email at the top of the receipt (if given)
  • Should display the VAT number at the top of the receipt (if given)
  • Should allow creating a custom message at the top and bottom of the receipt (if given)
  • Should display the Quantity, Description, Price, and Amount in a separate row for each item
  • Should display the Total amount paid
  • Should display the Total amount due (this isn't included in the input data, so will need calculating within the app)
  • Should display the number of items sold (this isn't included in the input data, so will need calculating within the app)
  • Should display whether the payment used cash or card
  • Should display change given (this isn't included in the input data, so will need calculating within the app)
  • Should display card details if using card
  • Should display the date and time of the receipt (accurate to seconds)
  • Everything should look neat and use formatting like a real receipt
  • Receipts should have a configurable currency (USD/GBP/Euro is provided as a top-level field in the order information)
  • Receipts need to support multiple different languages (English, German, Chinese)
  • Receipts need to support multiple different businesses across our business empire, and each shop lays out their receipts differently
  • Receipts should not have any ugly layout issues for expensive items or for items with very long names
  • Should be published to npmjs and documented so that our in-house devs can maintain it afterwards

Tech requirements

Hey, senior engineer here. I have to catch a flight to the Bahamas soon and will be uncontactable for the duration of this project, so good lucky. Let me give you a few pointers...

  1. Start off by creating an engineering design which describes how the tool will be used by the customer. For example, some of the options might look like: generate-receipt --order {items: []} --vat-number 509203409
  2. Play around with the required frameworks you're not familiar with first. If you're not sure how a command-line app works, create a simple one. If you need practice drawing to an image, create that.
  3. Validate your input. User data is messy - and laying out receipts is notoriously hard due to their compactness. Think about truncating long text, checking user-submitted image sizes, handling null values, etc.
  4. Don't be afraid to transform the user-submitted data into a new class. It would actually be preferable to map this data into a new object with a schema that is better suited for creating a receipt image (e.g., you could calculate the Total Amount, which is missing from the submitted info)
  5. Unit test your validation functions, create E2E tests using a shell script that create receipts & then inspect it by eyeball.
  6. Create suitable test data early on so that you can verify your receipts look good for all the use cases. It'd help to create a Testing section in your design so that you can make sure all your requirements are covered.
  7. If a piece of data is optional and isn't part of the order information, it might be a good candidate for a command line argument (e.g., company phone number)
  8. Try and organize your layout into logical components, potentially one function each. E.g., the logo should come first, and then the address, etc. If the address is omitted, then this will affect the height at which other components are laid out...
  9. Remember to verify what happens with the bare minimum and total maximum of information provided!

I would suggest using the Yargs and node-canvas frameworks.

Here are some guides on how to create a command line app, and drawing to a canvas.

Finally, when you're done, the package should be published to npm so that others can use it.

Remember to look at pictures of receipts for some inspiration!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment