Commit 80d5c49d authored by Javier Hernández's avatar Javier Hernández 🤓

Builders, Factories, TaxesCaculator and data classes refactoring

- added calculation function to TaxesCalcultator
- create Recipe, Perfume, Candy, ChocolateBar, Chocolate and Pills classes
- Created PillsBuilder
- added buildBook and buildPills tests
- added first version of ShoppingTests for input1
- Created json test objects, may not necessaries
parent 0f11a560
package com.lm.sales.builders
import com.lm.sales.model.Taxes
import com.lm.sales.model.music.CD
import com.lm.sales.model.stationery.Book
class BookBuilder {
private lateinit var discName: String
private lateinit var artist: String
private var tracksNumber: Int? = null
private lateinit var label: String
private lateinit var name: String
private lateinit var author: String
private var pages: Int = 0
private lateinit var editorial: String
private var isImported: Boolean = false
private var basePrice: Double = 0.0
private lateinit var taxes: Taxes
fun withName(name: String): BookBuilder {
this.discName = name
this.name = name
return this
}
fun withArtist(artist: String): BookBuilder {
this.artist = artist
fun withAuthor(author: String): BookBuilder {
this.author = author
return this
}
fun withTracks(tracksNumber: Int): BookBuilder {
this.tracksNumber = tracksNumber
fun isImported(imported: Boolean): BookBuilder {
this.isImported = imported
return this
}
fun withRecordLabel(label: String): BookBuilder {
this.label = label
fun withPages(pages: Int): BookBuilder {
this.pages = pages
return this
}
fun setImported(imported: Boolean): BookBuilder {
this.isImported = imported
fun withEditorial(editorial: String): BookBuilder {
this.editorial = editorial
return this
}
......@@ -43,8 +43,8 @@ class BookBuilder {
return this
}
fun build(): CD {
return CD(discName, artist, tracksNumber, label, isImported, basePrice, taxes)
fun build(): Book {
return Book(name, author, isImported, pages, editorial, basePrice)
}
}
\ No newline at end of file
package com.lm.sales.builders
import com.lm.sales.model.Taxes
import com.lm.sales.model.music.CD
class CDBuilder {
......@@ -11,7 +10,6 @@ class CDBuilder {
private lateinit var label: String
private var isImported: Boolean = false
private var basePrice: Double = 0.0
private lateinit var taxes: Taxes
fun withName(name: String): CDBuilder {
this.discName = name
......@@ -33,7 +31,7 @@ class CDBuilder {
return this
}
fun setImported(imported: Boolean): CDBuilder {
fun isImported(imported: Boolean): CDBuilder {
this.isImported = imported
return this
}
......@@ -43,13 +41,8 @@ class CDBuilder {
return this
}
fun withTaxes(taxes: Taxes): CDBuilder {
this.taxes = taxes
return this
}
fun build(): CD {
return CD(discName, artist, tracksNumber, label, isImported, basePrice, taxes)
return CD(discName, artist, tracksNumber, label, isImported, basePrice)
}
}
\ No newline at end of file
package com.lm.sales.builders
import com.lm.sales.model.Presentation
import com.lm.sales.model.medicals.Pills
class PillsBuilder {
private lateinit var name: String
private lateinit var pharma: String
private var isImported: Boolean = false
private var basePrice: Double = 0.0
private lateinit var presentation: Presentation
fun withName(name: String): PillsBuilder {
this.name = name
return this
}
fun withPharma(pharma: String): PillsBuilder {
this.pharma = pharma
return this
}
fun isImported(imported: Boolean): PillsBuilder {
this.isImported = imported
return this
}
fun withBasePrice(price: Double): PillsBuilder {
this.basePrice = price
return this
}
fun withPresentation(presentation: Presentation): PillsBuilder {
this.presentation = presentation
return this
}
fun build(): Pills {
return Pills(name, pharma, isImported, basePrice, presentation)
}
}
\ No newline at end of file
package com.lm.sales.factories
class CandyFactory {
// fun getCandy(type: Candy.CandyType): Candy {
//
// return if (type.equals(Candy.CandyType.chocolates)) {
// Chocolates()
// } else {
// ChocolateBar()
// }
//
// }
}
\ No newline at end of file
package com.lm.sales.factories
class RecipeFactory {
}
\ No newline at end of file
......@@ -9,10 +9,14 @@ interface Product {
val name: String
val basePrice: Double
var taxes: Taxes
var taxes: Taxes?
val imported: Boolean
}
enum class Presentation {
box, bottle, packet
}
data class Taxes(var taxesAmount: Double = 0.0,
var afterTaxesAmount: Double = 0.0)
......
package com.lm.sales.model.basket
class Basket {
}
\ No newline at end of file
package com.lm.sales.model.cart
import com.lm.sales.model.Product
/**
* Data class to contain a list of bought products
*
* @j.hernandez
*/
class Cart{
var productList: MutableList<Product> = mutableListOf()
}
\ No newline at end of file
package com.lm.sales.model.drugstore
import com.lm.sales.model.Presentation
import com.lm.sales.model.Product
interface Drugstore: Product {
//val type: <DrugstoreType> //Cleaning, Perfume, PersonalCare...
val manufacturer: String
val presentation: Presentation
// ...
}
package com.lm.sales.model.drugstore
import com.lm.sales.model.Presentation
import com.lm.sales.model.Taxes
data class Perfume(override val name: String,
override val manufacturer: String,
override val imported: Boolean,
override val basePrice: Double,
override val presentation: Presentation,
override var taxes: Taxes? = null): Drugstore
\ No newline at end of file
package com.lm.sales.model.drugstore
import com.lm.sales.model.Taxes
data class Pills(val pillsName: String,
val pharma: String,
val isImported: Boolean,
val price: Double, override var taxes: Taxes): Drugstore {
override val name = pillsName
override val manufacturer = pharma
override val imported = isImported
override val basePrice = price
}
\ No newline at end of file
package com.lm.sales.model.foods
abstract class Candy(type: CandyType) : Foods {
abstract val type: CandyType
// ...
enum class CandyType {
chocolates, candyBar, bubbleGums, candies
}
}
package com.lm.sales.model.foods
import com.lm.sales.model.Presentation
import com.lm.sales.model.Taxes
/**
* Chocolate bar implementation of [Candy] [Foods] interfaces
*
*/
data class ChocolateBar (override val name: String,
override val type: Candy.CandyType,
override val manufacturer: String,
override val presentation: Presentation,
override val imported: Boolean,
override val basePrice: Double,
override var taxes: Taxes?): Candy(type)
package com.lm.sales.model.foods
import com.lm.sales.model.Presentation
import com.lm.sales.model.Taxes
/**
* Chocolates implementation of [Candy] [Foods] interfaces
*
*/
data class Chocolates (override val name: String,
override val type: Candy.CandyType,
override val manufacturer: String,
override val presentation: Presentation,
override val imported: Boolean,
override val basePrice: Double,
override var taxes: Taxes?): Candy(type)
package com.lm.sales.model.foods
import com.lm.sales.model.Presentation
import com.lm.sales.model.Product
interface Foods: Product {
//val type: <FoodType> //Fruit, Vegetable, Snack, Candy, Meat, Drink...
//val manufacturer: String
val manufacturer: String
val presentation: Presentation?
// ...
}
\ No newline at end of file
package com.lm.sales.model.medicals
import com.lm.sales.model.Presentation
import com.lm.sales.model.Product
interface Medicals: Product {
//val type: <DrugstoreType> //Cleaning, Perfume, PersonalCare...
//val manufacturer: String
val pharma: String
val presentation: Presentation
}
\ No newline at end of file
package com.lm.sales.model.medicals
import com.lm.sales.model.Presentation
import com.lm.sales.model.Taxes
data class Pills(override val name: String,
override val pharma: String,
override val imported: Boolean,
override val basePrice: Double,
override val presentation: Presentation,
override var taxes: Taxes? = null): Medicals
\ No newline at end of file
......@@ -7,17 +7,10 @@ import com.lm.sales.model.Taxes
*
* @author j.hernandez
*/
data class CD (val discName: String,
val artist: String,
val tracksNumber: Int?,
val label: String,
val isImported: Boolean,
val price: Double, override var taxes: Taxes): Music {
override val name = discName
override val mainArtist = artist
override val tracks = tracksNumber
override val recordLabel = label
override val imported = isImported
override val basePrice = price
}
\ No newline at end of file
data class CD (override val name: String,
override val mainArtist: String,
override val tracks: Int?,
override val recordLabel: String,
override val imported: Boolean,
override val basePrice: Double,
override var taxes: Taxes? = null): Music
\ No newline at end of file
......@@ -7,6 +7,5 @@ interface Music: Product {
val mainArtist: String
val tracks: Int?
val recordLabel: String
//val format: <Format> //Vinyl, CD, MP3, Tape...
// ...
}
\ No newline at end of file
package com.lm.sales.model.recipe
import com.lm.sales.model.cart.Cart
data class Recipe(val cart: Cart, val salesTaxes: Double, val totalAmount: Double)
\ No newline at end of file
......@@ -7,18 +7,10 @@ import com.lm.sales.model.Taxes
*
* @author j.hernandez
*/
data class Book (val bookName: String,
val isImported: Boolean,
val bookPages: Int?,
val bookEditorial: String?,
val bookManufacturer: String?,
val price: Double, override var taxes: Taxes) : Stationery {
override val name = bookName
override val imported = isImported
override val pages = bookPages
override val editorial = bookEditorial
override val manufacturer = bookManufacturer
override val basePrice = price
}
\ No newline at end of file
data class Book (override val name: String,
val author: String,
override val imported: Boolean,
override val pages: Int?,
override val editorial: String?,
override val basePrice: Double,
override var taxes: Taxes? = null) : Stationery
\ No newline at end of file
......@@ -7,7 +7,6 @@ interface Stationery: Product {
// parameter examples
//val type: <BookType> //Book, Notebook, Magazine, Diary...
val manufacturer: String?
val editorial: String?
val pages: Int?
// ...
......
package com.lm.sales.services
import com.lm.sales.model.Product
import com.lm.sales.model.Taxes
import com.lm.sales.model.foods.Foods
import com.lm.sales.model.medicals.Medicals
import com.lm.sales.model.stationery.Stationery
/**
* TaxesCalcultor service to calculate basic and importing taxes
*
* @j.hernandez
*/
class TaxesCalculator {
companion object {
fun calculate(product: Product, isImported: Boolean): Product {
//TODO: implement
return product
}
/**
* Returns a [Taxes] object with calculated taxes
*
* @param imported
* @param price
* @param productClass
*
* @return [Taxes] object
*/
fun calculate(product: Product): Taxes {
}
var taxes = 0.0
// Basic taxes: if product isn't a Stationery (Books), Foods or Medicals, it has a 10% more taxes
if(product !is Stationery || product !is Foods || product !is Medicals)
taxes = product.basePrice * 10 / 100
// If imported, we add a 5% more to taxes
if(product.imported)
taxes.plus(product.basePrice * 5 /100)
return Taxes().apply {
taxesAmount = taxes
afterTaxesAmount = product.basePrice.plus(taxes)
}
}
}
}
\ No newline at end of file
import com.beust.klaxon.JsonObject
import com.beust.klaxon.Parser
import org.junit.Test
......@@ -10,16 +9,12 @@ import org.junit.jupiter.api.TestInstance
class JsonParserTest {
@Test
fun convertCD() {
fun parseCD() {
val cd = "/CD.json".parse() as JsonObject
val cd = "/music/CD.json".parse() as JsonObject
Assertions.assertEquals("Purple Rain", cd.string("name"))
Assertions.assertEquals("Prince", cd.string("artist"))
Assertions.assertEquals(9, cd.int("tracksNumber"))
Assertions.assertEquals(true, cd.boolean("imported"))
Assertions.assertEquals(1984, cd.int("year"))
Assertions.assertEquals("Warner Bros", cd.string("label"))
Assertions.assertEquals("music CD", cd.string("name"))
Assertions.assertEquals(false, cd.boolean("imported"))
Assertions.assertEquals(14.99, cd.double("price"))
}
......
package builders
import com.lm.sales.builders.BookBuilder
import com.lm.sales.builders.CDBuilder
import com.lm.sales.builders.PillsBuilder
import com.lm.sales.model.Presentation
import com.lm.sales.services.TaxesCalculator
import org.junit.Test
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.TestInstance
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class BuildersTests {
@Test
fun buildCD(){
// Fictional example of a CD building
val cd = CDBuilder().withName("Purple Rain")
.withArtist("Prince")
.withTracks(9)
.isImported(false)
.withRecordLabel("Warner Bros")
.withBasePrice(14.99)
.build().apply {
taxes = TaxesCalculator.calculate(this)
}
Assertions.assertEquals("Purple Rain", cd.name)
Assertions.assertEquals("Prince", cd.mainArtist)
Assertions.assertEquals(9, cd.tracks)
Assertions.assertEquals(false, cd.imported)
Assertions.assertEquals("Warner Bros", cd.recordLabel)
Assertions.assertEquals(14.99, cd.basePrice)
}
@Test
fun buildBook(){
// Fictional example of a book building
val book = BookBuilder().withName("1Q84")
.withAuthor("Haruki Murakami")
.isImported(false)
.withPages(928)
.withEditorial("Tusquets")
.withBasePrice(12.49)
.build().apply {
taxes = TaxesCalculator.calculate(this)
}
Assertions.assertEquals("1Q84", book.name)
Assertions.assertEquals("Haruki Murakami", book.author)
Assertions.assertEquals(false, book.imported)
Assertions.assertEquals(928, book.pages)
Assertions.assertEquals("Tusquets", book.editorial)
Assertions.assertEquals(12.49, book.basePrice)
}
@Test
fun buildPills(){
// Fictional example of pills packet building
val pills = PillsBuilder().withName("Headache pills")
.withPharma("Bayern")
.isImported(false)
.withBasePrice(9.75)
.withPresentation(Presentation.packet)
.build().apply {
taxes = TaxesCalculator.calculate(this)
}
Assertions.assertEquals("Headache pills", pills.name)
Assertions.assertEquals("Bayern", pills.pharma)
Assertions.assertEquals(false, pills.imported)
Assertions.assertEquals(9.75, pills.basePrice)
Assertions.assertEquals(Presentation.packet, pills.presentation)
}
}
\ No newline at end of file
package builders
import com.lm.sales.builders.CDBuilder
import org.junit.Test
import org.junit.jupiter.api.Assertions
class CDBuilderTest {
@Test
fun build(){
val cd = CDBuilder().withName("Purple Rain")
.withArtist("Prince")
.withTracks(9)
.setImported(true)
.withRecordLabel("Warner Bros")
.withBasePrice(15.00)
.build()
Assertions.assertEquals("Purple Rain", cd.name)
Assertions.assertEquals("Prince", cd.mainArtist)
Assertions.assertEquals(9, cd.tracks)
Assertions.assertEquals(true, cd.isImported)
Assertions.assertEquals("Warner Bros", cd.label)
Assertions.assertEquals(15.00, cd.basePrice)
}
}
\ No newline at end of file
package shopping
import com.lm.sales.builders.BookBuilder
import com.lm.sales.builders.CDBuilder
import com.lm.sales.model.cart.Cart
import com.lm.sales.services.TaxesCalculator
import org.junit.Test
import org.junit.jupiter.api.TestInstance
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class ShoppingTests {
@Test
fun input1(){
val book = BookBuilder().withName("book")
.isImported(false)
.withBasePrice(12.49)
.build().apply {
taxes = TaxesCalculator.calculate(this)
}
val cd = CDBuilder().withName("music CD")
.isImported(false)
.withBasePrice(14.99)
.build().apply {
taxes = TaxesCalculator.calculate(this)
}
val cart = Cart().apply {
productList.add(book)
productList.add(cd)
}
}
}
\ No newline at end of file
{
"name": "Purple Rain",
"artist": "Prince",
"tracksNumber": 9,
"imported": true,
"year": 1984,
"label": "Warner Bros",
"price": 14.99
}
\ No newline at end of file
{
"name": "headache pills",
"imported": true,
"price": 47.50,
"package": "bottle"
}
\ No newline at end of file
{
"name": "bottle of perfume",
"imported": false,
"price": 9.75,
"package": "packet"
}
\ No newline at end of file
{
"name": "bottle of perfume",
"imported": false,
"price": 9.75,
"package": "bottle"
}
\ No newline at end of file
{
"name": "chocolate bar",
"imported": false,
"price": 0.85,
"package": "box"
}
\ No newline at end of file
{
"name": "headache pills",
"imported": false,
"price": 9.75,
"package": "packet"
}
\ No newline at end of file
{
"name": "headache pills",
"imported": false,
"price": 9.75,
"package": "packet"
}
\ No newline at end of file
{
"name": "headache pills",
"imported": false,
"price": 9.75,
"package": "packet"
}
\ No newline at end of file
{
"name": "music CD",
"imported": false,
"price": 14.99
}
\ No newline at end of file
{
"name": "book",
"imported": false,
"price": 12.49
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment