Book Keeping
Tags: javascript, beginners, programming, tutorial
Published: 2023-01-01 20:50:29

The last few days before the new year I took a critical look at my past year as a buding web developer in search of a job. I have come far, from mastering HTML to Vue.js, the road was not always easy, but it was worth it. I am happy with the current amount of technologies I know, and confident that I can learn more, if need be. I was planning to start learning Node.js, MongoDB and Express, but decided against it at the last minute. After critically evaluating my skills I realized that I jumped to fast from using JavaScript to learning a framework. I could not help myself, I like using frameworks, and building websites with Vue is really enjoyable, but that leaves me with some surface knowledge when it comes to JavaScript. In web development Javascript is still the queen of languages, and it would benefit me, if I revisit old knowledge and learn some more.

That is why I decided to take upon some challenges, that will help me understand the language better. I also want to document this journey, and my thought process behind every solution.

The first challenge in this series is to develop a simple book inventory application. This application needs to keep the number of books available at any given time. Each book has a title, author, ISBN and a number of currently available copies.
<br />
```js
/*
create book class with title, author, isbn and number of copies
make a way to get each books availability
 if stock=0 -> out of stock
if stock <5 low stock
else in stock
a function for selling a book 
-> substract sold books from total books
 a restock function 
-> adds copies to restock to total number of books

use javascript classes and a getter function
*/
```
<br />
---

## Make a Book class
<br />
> Classes are a template for creating objects. They encapsulate data with code to work on that data. Classes in JS are built on prototypes but also have some syntax and semantics that are unique to classes.
<br />
Read more about classes [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)
<br />
```js
class Book {
  constructor(title, author, ISBN, currentCopies){
    this.title = title;
    this.author = author;
    this.ISBN = ISBN;
    this.currentCopies=currentCopies;
  }
}
```
<br />
After making the `Book` class I made 3 books, that will help me with testing the upcoming functions that I have to write.
<br />
```js
const firstBook = new Book("The best Book", "mrs. Author", 123456567, 0);
const secondBook = new Book("The best Book", "mrs. Author", 123456567, 4);
const thirdBook = new Book("The best Book", "mrs. Author", 123456567, 5);
```
<br />
After making the book class I need to write the functions for checking the number of available books and selling and restocking the books. 

---

## Check the availability

To get the number of available books I need to check the number of `this.currentCopies`. I do not want, nor need, to create a new instance of this function each time I make a new object/book, that is why I declared this and all of the other functions on a prototype.
Each book instance can then use the prototype's function. 

<br />
```js
Book.prototype.getAvailability = function () {
//if there is 0 books it is out of stock
//if there is less than 5 books the book is in low stock
//else the book is in stock
};
```
<br />
I roughly outlined the function above. It looks like something that a few simple if/else statements can help with.
<br />
```js
Book.prototype.getAvailability = function () {
  if (this.currentCopies === 0) {
    return `${this.title}  is out of stock.`;
  } else if (this.currentCopies < 5) {
    return `${this.title} is low in stock. There are ${this.currentCopies} left.`;
  } else {
    return `${this.title} is in stock. There are ${this.currentCopies} left.`;
  }
};
```
<br />
To see if the function works I applied it to `firstBook`, `secondBook` and `thirdBook`. The app logged out predictable results, which ment that the function works as intended.
<br />
```js
console.log(firstBook.getAvailability());
console.log(secondBook.getAvailability());
console.log(thirdBook.getAvailability());

/* Results
The best Book  is out of stock.
The best Book is low in stock. There are 4 left.
The best Book is in stock. There are 5 left.
*/
```

---

## Selling books

After knowing how many books are available I can sell them (or not, depending on current copies). I wrote a function that takes the number of sold copies and substracts it from the number of current copies. If the number of current copies is lower than the number of sold copies it does not substract anything, but instead returns a string. If no number of sold copies is specified the default number is 1.
<br />
```js
Book.prototype.sellBook = function (soldCopies = 1) {
//sell books if there is enough books to sell
//else do not sell the books
};
```
<br />
```js
Book.prototype.sellBook = function (soldCopies = 1) {
  if (this.currentCopies >= soldCopies) {
    this.currentCopies -= soldCopies;
    console.log(
      `You bought ${soldCopies}, there is still ${this.currentCopies} left`
    );
  } else {
    console.log(`We can only sell ${this.currentCopies}`);
  }
  return this.currentCopies;
};
```
<br />
I checked, if the function for selling books works, applying it to the three books defined above. I also ran the `getAvailability()`function again, to check for the new `currentCopies` values.
<br />
```js
console.log(firstBook.sellBook());
console.log(secondBook.sellBook(4));
console.log(thirdBook.sellBook(3));

console.log(firstBook.getAvailability());
console.log(secondBook.getAvailability());
console.log(thirdBook.getAvailability());

/* Results
We can only sell 0 of The best Book
0
You bought 4, there is still 0 left of The best Book
0
You bought 3, there is still 2 left of The best Book
2

The best Book  is out of stock.
The best Book  is out of stock.
The best Book is low in stock. There are 2 left.
*/
```

<br />
The `sellBook()`returns a string, depending on the condition, and the amount of books left. The results are as expected. Now the only thing left to do is to make a function to restock the books. 

---

## Restocking books

The function for restocking the books is basically inverse of the previous `sellBook()`function. Instead of removing books we are adding them. If no number of restocked books is specified the default number is 10.
<br />
```js
Book.prototype.restockBook = function (restockedCopies = 10) {
  //add number of restocked copies to current stock
};
```
<br />
```js
Book.prototype.restockBook = function (restockedCopies = 10) {
  this.currentCopies += restockedCopies;
  return `You restocked the book, there is now ${this.currentCopies} copies`;
};
```
<br />
I checked if the function for restocking books works, applying it to the three books defined above. I also ran the `getAvailability()` function again, to check for the new `currentCopies` values.
<br />
```js
console.log(firstBook.restockBook());
console.log(secondBook.restockBook(5));
console.log(thirdBook.restockBook(16));

console.log(firstBook.getAvailability());
console.log(secondBook.getAvailability());
console.log(thirdBook.getAvailability());


/* Results
You restocked The best Book, there is now 10 copies
You restocked The best Book, there is now 9 copies
You restocked The best Book, there is now 21 copies

The best Book is in stock. There are 10 left.
The best Book is in stock. There are 9 left.
The best Book is in stock. There are 21 left.
*/
```
<br />
The `restockBook()`returns a string, including the new number of books. Based on the examples it looks like it works as intended, but what happens, if I add a negative ammount of books? 
<br />
```js

console.log(thirdBook.restockBook(-16));
console.log(thirdBook.getAvailability());


/* Results
You restocked The best Book, there is now -11 copies
The best Book is low in stock. There are -11 left.
*/
```
Ofcourse you can not have a negative amount of books, so we need an if statement, that checks if the value of restockedCopies is bigger than 0.
<br />
```js
 if (restockedCopies > 0) {
    this.currentCopies += restockedCopies;
    return `You restocked ${this.title}, there is now ${this.currentCopies} copies`;
  } else {
    return "The number of restocked copies is negative.";
  }
```
<br />
After this change the function works even if the value of restocked books is negative.
<br />
```js

console.log(thirdBook.restockBook(-16));
console.log(thirdBook.getAvailability());


/* Results
The number of restocked copies is negative.
The best Book is in stock. There are 5 left.
*/
```
<br />
### Conclusion

This marks the end of this challenge. How would you solve it?