11import { CartItem } from './cartItem' ;
2+ import { TABLE_CONSTANTS } from './constants' ;
23import { Discount } from './discount' ;
34
45export interface TablePrinter {
@@ -11,49 +12,73 @@ export interface TablePrinter {
1112 printHeaderFooter ( ) : string ;
1213}
1314
14- export class InMemoryTablePrinter implements TablePrinter {
15+ export class DefaultTablePrinter implements TablePrinter {
1516 printHeader ( ) : string {
1617 return [
17- '--------------------------------------------' ,
18- '| Product name | Price with VAT | Quantity |' ,
19- '| ------------ | -------------- | -------- |' ,
18+ this . printLineSeparator ( ) ,
19+ ` ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } Product name ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } Price with VAT ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } Quantity ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ` ,
20+ ` ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ${ '-' . repeat ( TABLE_CONSTANTS . COLUMN_WIDTHS . NAME ) } ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ${ '-' . repeat ( TABLE_CONSTANTS . COLUMN_WIDTHS . PRICE ) } ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ${ '-' . repeat ( TABLE_CONSTANTS . COLUMN_WIDTHS . QUANTITY ) } ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ` ,
2021 ] . join ( '\n' ) ;
2122 }
2223
2324 printHeaderFooter ( ) : string {
24- return '|------------------------------------------|' ;
25+ return ` ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ${ '-' . repeat ( TABLE_CONSTANTS . LINE_WIDTH - 2 ) } ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ` ;
2526 }
2627
2728 printCartItem ( item : CartItem ) : string {
28- const name = item . product . name . padEnd ( 12 ) ;
29- const priceWithVat = `${ item . product . finalPrice . toFixed ( 2 ) } €` . padEnd ( 14 ) ;
30- const quantity = item . quantity . toString ( ) . padEnd ( 8 ) ;
29+ const name = item . product . name . padEnd ( TABLE_CONSTANTS . COLUMN_WIDTHS . NAME ) ;
30+ const priceWithVat =
31+ `${ this . formatPrice ( item . product . finalPrice ) } ${ TABLE_CONSTANTS . CURRENCY } ` . padEnd (
32+ TABLE_CONSTANTS . COLUMN_WIDTHS . PRICE ,
33+ ) ;
34+ const quantity = item . quantity . toString ( ) . padEnd ( TABLE_CONSTANTS . COLUMN_WIDTHS . QUANTITY ) ;
3135
32- return `| ${ name } | ${ priceWithVat } | ${ quantity } | ` ;
36+ return `${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ${ name } ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ${ priceWithVat } ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ${ quantity } ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ` ;
3337 }
3438
3539 printLineSeparator ( ) : string {
36- return '--------------------------------------------' ;
40+ return TABLE_CONSTANTS . SEPARATORS . HORIZONTAL . repeat ( TABLE_CONSTANTS . LINE_WIDTH ) ;
3741 }
3842
3943 printPromotion ( discount : Discount | null ) : string {
40- const promotionCode = discount ?. code ?? '' ;
41- const promotionDescription =
42- discount != null
43- ? `Promotion: ${ discount ?. percentage * 100 } % off with code ${ promotionCode } `
44- : 'Promotion:' ;
45- return [ this . printHeaderFooter ( ) , `| ${ promotionDescription . padEnd ( 40 ) } |` ] . join ( '\n' ) ;
44+ const promotionDescription = this . formatPromotionDescription ( discount ) ;
45+ return [
46+ this . printHeaderFooter ( ) ,
47+ `${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ${ promotionDescription . padEnd ( TABLE_CONSTANTS . PADDING_WIDTH ) } ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ` ,
48+ ] . join ( '\n' ) ;
4649 }
4750
4851 printProductCount ( items : CartItem [ ] ) : string {
49- const totalItems = items . reduce ( ( total , item ) => total + item . quantity , 0 ) ;
50- return `| Total products: ${ totalItems . toString ( ) . padEnd ( 24 ) } | ` ;
52+ const totalItems = this . calculateTotalItems ( items ) ;
53+ return `${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } Total products: ${ totalItems . toString ( ) . padEnd ( 24 ) } ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ` ;
5154 }
5255
5356 printTotalPrice ( items : CartItem [ ] , discount : Discount | null ) : string {
54- const totalPrice = items . reduce ( ( total , item ) => total + item . LineTotal , 0 ) ;
57+ const totalPrice = this . calculateTotalPrice ( items ) ;
5558 const discountedAmount = discount ? discount . applyTo ( totalPrice ) : totalPrice ;
56- const description = `Total price: ${ discountedAmount . toFixed ( 2 ) } €` ;
57- return `| ${ description . padEnd ( 40 ) } |` ;
59+ const description = `Total price: ${ this . formatPrice ( discountedAmount ) } ${ TABLE_CONSTANTS . CURRENCY } ` ;
60+
61+ return `${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ${ description . padEnd ( TABLE_CONSTANTS . PADDING_WIDTH ) } ${ TABLE_CONSTANTS . SEPARATORS . VERTICAL } ` ;
62+ }
63+
64+ private formatPromotionDescription ( discount : Discount | null ) : string {
65+ if ( discount == null ) {
66+ return 'Promotion:' ;
67+ }
68+
69+ const percentage = Math . round ( discount . percentage * 100 ) ;
70+ return `Promotion: ${ percentage } % off with code ${ discount . code } ` ;
71+ }
72+
73+ private calculateTotalItems ( items : CartItem [ ] ) : number {
74+ return items . reduce ( ( total , item ) => total + item . quantity , 0 ) ;
75+ }
76+
77+ private calculateTotalPrice ( items : CartItem [ ] ) : number {
78+ return items . reduce ( ( total , item ) => total + item . LineTotal , 0 ) ;
79+ }
80+
81+ private formatPrice ( price : number ) : string {
82+ return price . toFixed ( 2 ) ;
5883 }
5984}
0 commit comments