Created
February 17, 2016 16:21
-
-
Save juan-m-medina/7803acdf73c0031e2f69 to your computer and use it in GitHub Desktop.
LunchNLearn - Mixins
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// General library function to apply mixins to classes | |
function applyMixins(derivedCtor: any, baseCtors: any[]) { | |
baseCtors.forEach(baseCtor => { | |
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { | |
derivedCtor.prototype[name] = baseCtor.prototype[name]; | |
}) | |
}); | |
} | |
// An Enum to classify items for pricing | |
enum Fruits { | |
Apple, | |
Pear, | |
Grape, | |
Orange | |
} | |
// Item Definition | |
class Item { | |
constructor(options? : { type: Fruits, description : string}) { | |
this.type = options.type; | |
this.description = options.description; | |
} | |
type : Fruits; | |
description : string; | |
} | |
// Item + Quantity | |
class LineItem extends Item { | |
quantity : number; | |
constructor(options? : { type: Fruits, description : string, quantity : number}) { | |
super( { type: options.type, description : options.description}); | |
this.quantity = options.quantity; | |
} | |
} | |
// Address + static methods | |
class Address { | |
number : number; | |
street : string; | |
suffix : string; | |
city : string; | |
state : string; | |
zip : number; | |
zip4 : number | |
} | |
// Item Pricer | |
class ItemPricer { | |
getPrice(item : Item) : number { | |
if (item.type == Fruits.Apple) return 10; | |
if (item.type == Fruits.Pear) return 20; | |
if (item.type == Fruits.Grape) return 30; | |
if (item.type == Fruits.Orange) return 40; | |
} | |
} | |
// Line Item Pricer (Item Pricer * quantity) | |
class LineItemPricer implements ItemPricer { | |
getPrice : (item : Item) => number; | |
priceLineItem(item : LineItem) { | |
return this.getPrice(item) * item.quantity; | |
} | |
} | |
// Setup the Pricer mixin | |
applyMixins(LineItemPricer, [ItemPricer]); | |
// Class to determine whether to insure the invoce | |
class Insurable { | |
lowLimit : number = 10; | |
requiresInsurance(price : number) : Boolean { | |
if (price > this.lowLimit) { | |
return true; | |
} | |
return false; | |
} | |
} | |
// Invoice Builder combining all the other stuff | |
class InvoiceBuilder implements LineItemPricer, Insurable { | |
lineItems : LineItem[]; | |
lowLimit : number; | |
getPrice : (item : Item) => number; | |
priceLineItem : (item : LineItem) => number; | |
requiresInsurance : (price : number) => boolean; | |
constructor(lowLimit : number = 150, lineItems : LineItem[]) { | |
this.lowLimit = lowLimit; | |
this.lineItems = lineItems; | |
} | |
build() { | |
let lineItemNumber = 1; | |
let totalInvoicePrice = 0; | |
// Table creation | |
let table = document.createElement('table'); | |
let tableHeader = <HTMLTableElement> table.createTHead(); | |
let headerRow = <HTMLTableRowElement> tableHeader.insertRow(0); | |
let tableBody = <HTMLTableElement> table.createTBody(); | |
// Header creation | |
let lineItemNumberHeaderCell = headerRow.insertCell(); | |
lineItemNumberHeaderCell.innerText = "Item Number"; | |
let descriptionHeaderCell = headerRow.insertCell(); | |
descriptionHeaderCell.innerText = "Description"; | |
let unitPriceHeaderCell = headerRow.insertCell(); | |
unitPriceHeaderCell.innerText = "Unit Price"; | |
let quantityHeaderCell = headerRow.insertCell(); | |
quantityHeaderCell.innerText = "Quantity"; | |
let lineItemPriceHeaderCell = headerRow.insertCell(); | |
lineItemPriceHeaderCell.innerText = "Total Price"; | |
// Table content creation | |
for(let lineItem of this.lineItems) { | |
let row = <HTMLTableRowElement> tableBody.insertRow(); | |
let lineItemNumberCell = row.insertCell(); | |
lineItemNumberCell.innerText = lineItemNumber.toString(); | |
let descriptionCell = row.insertCell(); | |
descriptionCell.innerText = lineItem.description; | |
let unitPriceCell = row.insertCell(); | |
unitPriceCell.innerText = this.getPrice(lineItem).toString(); | |
let quantityCell = row.insertCell(); | |
quantityCell.innerText = lineItem.quantity.toString(); | |
let lineItemPriceCell = row.insertCell(); | |
let lineItemPrice = this.priceLineItem(lineItem); | |
lineItemPriceCell.innerText = lineItemPrice.toString(); | |
totalInvoicePrice += lineItemPrice; | |
lineItemNumber++; | |
} | |
let footerText = document.createElement('div'); | |
footerText.innerText = `The total price for the invoice is ${totalInvoicePrice.toString()}, and it ${this.requiresInsurance(totalInvoicePrice) === true ? "requires insurance" : "does not require insurance"}`; | |
document.body.appendChild(footerText); | |
document.body.appendChild(table); | |
} | |
} | |
applyMixins(InvoiceBuilder, [LineItemPricer, Insurable]); | |
var sampleLineItems = [ | |
new LineItem ({ type: Fruits.Apple, description : "Best Apples Ever", quantity : 10 }), | |
new LineItem ({ type: Fruits.Pear, description: "Best Pears Ever", quantity : 3 }), | |
new LineItem ({ type: Fruits.Grape, description: "Best Grapes Ever", quantity : 5 }), | |
new LineItem ({ type: Fruits.Orange, description : "Best Oranges Ever", quantity : 7 }) | |
]; | |
var sampleInvoice = new InvoiceBuilder(5000, sampleLineItems).build(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment