A well-automatized stock control is an important value in an enterprise. Maintaining plenty of stock results in the very important continuity in production and/or sales. On the other hand, one must see to it that the stock absorbs as little of the enterprise's budget as possible.

For an efficient stock control, a correct product list and a correct registration of the articles sold is necessary. The data that must be kept up to date depends for every article on various factors. Our enterprise buys articles, and sells them for a certain profit. When the supply of an article is below the minimum boundary, its stocks must be replenished. At any given moment, an overview of stocks that need replenishing can be asked.

Assignment

In order to solve the problem above, you must first define a class Article that supports the following methods:

  1. An initializing method __init__ to which five arguments must be given: a code that consists of one letter (A,B or C - defending on the sales frequency) followed by a number, the complete name of the article, a purchaseprice, the stock and a minimum_number_in_stock and a maximum_number_in_stock. The constructor must respectively appoint these arguments to the attributes code, name, purchaseprice, stock and minimumstock and maximumstock. If no maximum stock was given, this is equated with the minimum stock. If a minimum stock is given that is larger than the maximum stock, an error message appears 'minimum stock may not be larger than maximum stock' (see example).

  2. A method __str__ with no arguments that prints a string representation of the article. Look at the example below to determine what the string representation should look like. 

  3. A method __repr__ with no arguments that prints a string representation of the article. The method __repr__ prints a syntactically correct Python expression, that — if it were to be evaluated — makes an object that is equal to the object that was originally given to __repr__.

  4. A method value, that prints the total purchase value of the stock for this article.

  5. A method shortage, that determines whether or not the stock has decrease below the minimum value. If so, the number below the minimum is printed (as a negative number), otherwise, the value 0 (zero) is printed. 

  6. A method reorder that indicates how many items must be ordered, should a shortage arise. If no items must be ordered, a 0 (zero) is printed.

Define a second class Stock that provides the following methods: 

  1. An initializing method __init__ to which a dictionary of articles is given. This dictionary contains the article code as a key and the article as a corresponding value. Standard, the empty dictionary is appointed to the attribute articles

  2. A method addArticle that takes an object of the class Article as a parameter and that adds this element to a product list.

  3. A method value that prints the purchase value of the entire stock at that moment.

  4. A method purchase, to which two arguments can be given: the code of the article involved and the number of articles purchased. The methods sees to it that, for the article involved from the list, the stock is adjusted with number pieces. If the given number is negative, the error message 'number must be positive' should appear. Furthermore, if a non-existing code is given, an error message should appear ('article does not exist').

  5. A method sales, to which two arguments should be given as well: the code of the article and the number of articles sold. If the given number is negative, or if the given code does not exist, a similar error message should appear as in purchase. The stock of the article involved must be adjusted if there are enough pieces to meet an order, if not, you will also receive an error message. Look at the example below.

  6. A method replenish that sees to it that a list that was sorted on code is printed for the articles that need replenishing. The number that the article is short is always stated. Look at the example to see how this list must be printed.

Example

>>> article1 = Article('A207', 'rug', 45, 25, 20, 30)
>>> print(article1)
article: rug
code: A207
purchaseprice: 45
stock: 25
minimumstock: 20
maximumstock: 30
>>> article1
Article('A207', 'rug', 45, 25, 20, 30)
>>> article1.value()
1125
>>> article1.shortage()
0

>>> article2 = Article('C130', 'closet', 230, 10, 3)
>>> print(article2)
article: closet
code: C130
purchaseprice: 230
stock: 10
minimumstock: 3
maximumstock: 3
>>> article2
Article('C130', 'closet', 230, 10, 3, 3)
>>> article2.value()
2300
>>> article2.shortage()
0

>>> stock = Stock()
>>> stock.addArticle(Article('A207', 'rug', 45, 25, 20, 30))
>>> stock.addArticle(Article('B734', 'sofa', 186, 12, 8, 16))
>>> stock.addArticle(Article('C130', 'closet', 230, 10, 3))
>>> stock.sales('A207', 7)
>>> stock.sales('B734', 14)
Traceback (most recent call last):
AssertionError: not enough supply of article B734 (2 pieces short)
>>> stock.sales('C130', 8)
>>> stock.value()
3502
>>> stock.replenish()
article: rug
code: A207
purchaseprice: 45
stock: 18
minimumstock: 20
maximumstock: 30
--> 12 reorders
==============================
article: closet
code: C130
purchaseprice: 230
stock: 2
minimumstock: 3
maximumstock: 3
--> 1 reorders