{"id":22615619,"url":"https://github.com/marcellodesales/invoice-app","last_synced_at":"2025-06-25T00:02:49.953Z","repository":{"id":142072808,"uuid":"59702049","full_name":"marcellodesales/invoice-app","owner":"marcellodesales","description":"A java example for the implementation of an invoice app","archived":false,"fork":false,"pushed_at":"2016-05-25T22:31:49.000Z","size":1214,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-03T14:42:46.280Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcellodesales.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-25T22:29:37.000Z","updated_at":"2016-05-25T22:30:40.000Z","dependencies_parsed_at":"2023-07-09T05:32:11.413Z","dependency_job_id":null,"html_url":"https://github.com/marcellodesales/invoice-app","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/marcellodesales/invoice-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcellodesales%2Finvoice-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcellodesales%2Finvoice-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcellodesales%2Finvoice-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcellodesales%2Finvoice-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcellodesales","download_url":"https://codeload.github.com/marcellodesales/invoice-app/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcellodesales%2Finvoice-app/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261777416,"owners_count":23208113,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-08T19:08:37.122Z","updated_at":"2025-06-25T00:02:49.870Z","avatar_url":"https://github.com/marcellodesales.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Invoice App\n\nApplication showing the implementation of an invoice app in Java.\n\n# Running\n\n1. Run \"ant\" in the parent directory (where this file and build.xml are located).\nThis will execute the target \"run-test-data\", which does all the test cases and run \napplication with the test input data.\n\n2. To run a specific input file, add the FULL path to the file in the property\nINVOICE_FILE. Then type \"ant run\".\n\n### Solving the invoice problem...\n\nSolving the problem involved starting bottom up using Test-Driven Development:\nwriting the invoice file reader, design and implementation of the data wrappers\nof invoice objects using Object-Oriented Analysis and Design, to a solution \ndesigned with reusable components in Model-View-Controller along with other\ndesign-patterns. Additional libraries used were JUnit 4 and Google Guava.\n\n1. Copied the input and output data from the email to the data directory to\nstart working on initial test cases (Test-Drive Development).\n\n2. Started with the implementation of the TextFileReader and its unit tests\nat TextFileReaderTests.java. Since there is no requirement on performance, I\nthought that would be useful to implement this component using NIO APIs and\nexpect files that are larger than the examples. Also added 2 options of who\nconsumes the data loaded from the text files: buffers and listeners.\n\n3. After being able to load an invoice data into containers/listeners, the\nmodel was designed taking into account extensibility: a ShoppingBasket is\na \"container\" object aggregated with BasketItems (just to make the implementation\neasier, but conceptually a shopping basket is composed of BasketItems). To\nsupposed extensibility, different types of BasketItems can be implemented by\nimplementing that interface. A BasketItems object is a representation of a\nsingle row of the invoice. In order to support Multi-Valued state of imported,\nexempt and all regular products, EnumSet was used instead of Bit Maps (usual\nway to represent that) in ProjectTaxRateType. An Abstract Factory was created\nto be responsible to create ShoppingBasket\u003cBasketIntems\u003e instances from an\ninvoice text representation. The last decision made was to model the price as\na Money.java class so that it is easier to decrease coupling of the \nNumberFormatter.currencyFormatter. The model Unit tests were created and\nrefactored several times while developing the other layers, but the basic\nrepresentation of invoice objects were verified before moving to the other\nlayers.\n\n4. After having the Model ready, the concept of Services was added to provide\nthe real implementation of requirements and allow code reuse using singleton\n(Enums as best option as Effective Java 2nd suggests). In order to speed the\nprocess of writing the solution, the controller SalesControllerTests.java was\nput in place to indirectly exercise the services created and validate the \nscenarios of viewing invoice files. In order to decouple steps, the \nInvoiceReaderService reuses the TextFileReader utility to load a \nShoppingBasket from an invoice text file with invoice objects representation. \nTo decouple the the calculations from the ShoppingBasket, the SalesCalculatorService\nimplements the methods to read the data from the wrapper objects. The strategy\nof calculating tax values is based on the ProductTaxRateTypes. Finally, in order\ndecouple the visualization of the objects, the BasketItemsDecorator is the service\nresponsible for providing the Strategies SALE_ITEM_STRATEGY (printing the same\ninput input text) or RECEIPT_ITEM_STRATEGY (to print the expected output). All\nthe scenarios are verified by the SalesControllerTests using the files in the\n\"data\" directory.\n\n5. The view was the last piece designed. As the standard output was the primary\nview, I have added an InvoiceView interface with the contracts of for the view.\nThen, different view strategies were implemented: ConsoleViewStrategy.java and\nStringBuilderViewStrategy.java, where the former prints the invoice to the\nSystem.out and the latter to a container (StringBuilder). Tests were not added\nas the SalesControllerTests exercises the needed pieces.\n\n6. The last piece added was the InvoiceApp.java, which includes the main method\nand verification of the input and potential error messages and code.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcellodesales%2Finvoice-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcellodesales%2Finvoice-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcellodesales%2Finvoice-app/lists"}