Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Semi-automatic ordering of products from suppliers #30

Merged
merged 9 commits into from
Mar 10, 2017

Conversation

kjagiello
Copy link
Member

@kjagiello kjagiello commented Mar 6, 2017

For every product one can define base stock level (the desired quantity). Then, when placing an order from a supplier, system will aid by suggesting which products should be ordered, based on the current demand. In case of Narlivs, the "aiding" process will be that the system will prefill the cart at Narlivs with the items that should be ordered.

@kjagiello kjagiello added this to the 2.0.0 milestone Mar 6, 2017
@kjagiello kjagiello self-assigned this Mar 6, 2017
@codecov
Copy link

codecov bot commented Mar 6, 2017

Codecov Report

Merging #30 into develop will increase coverage by 0.75%.
The diff coverage is 93.82%.

@@            Coverage Diff             @@
##           develop     #30      +/-   ##
==========================================
+ Coverage    89.34%   90.1%   +0.75%     
==========================================
  Files           73      74       +1     
  Lines         2535    2739     +204     
  Branches       137     148      +11     
==========================================
+ Hits          2265    2468     +203     
  Misses         247     247              
- Partials        23      24       +1
Impacted Files Coverage Δ
src/shop/tests/factories.py 100% <100%> (ø)
src/shop/tests/test_api.py 100% <100%> (ø)
src/shop/tests/test_narlivs.py 100% <100%> (ø)
src/shop/suppliers/base.py 100% <100%> (ø)
src/shop/enums.py 100% <100%> (ø)
src/shop/tests/test_admin.py 100% <100%> (ø)
src/shop/suppliers/narlivs.py 94.64% <100%> (+16.21%)
src/shop/admin.py 63.29% <80%> (+3.6%)
src/shop/api.py 91.45% <90.56%> (-0.7%)
src/shop/models.py 84.61% <91.66%> (+0.53%)
... and 2 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7f20f80...503e311. Read the comment docs.

product.sku, supplier.internal_name)
else:
msg = 'Could not order {}.'.format(product.sku)
raise exceptions.APIException(msg)
Copy link
Member

@flaeppe flaeppe Mar 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This else clause should always run, regardless of what the iterable products will be. If I'm not missing any black magic here.
...
I just saw the test and now I'm sure there is some black magic here, as long as the test is not failing. What is the black magic?

If I try to simulate it as follows, the else clause is always executed:

for x in [1,2,3,4,5]:
  print("FOR")
else:
  print("STILL")
...
FOR
FOR
FOR
FOR
FOR
STILL

Also, do we want to localise the msg string?

UPDATE:
WOW, I completely missed the return statement, no black magic going on. I need some coffee...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else won't be executed if you do a break in your loop. https://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops

I do not know however how I feel about translating internal exceptions. I know that I'm displaying their messages in some places (exceptions from the stock taking module) in the admin panel, but it feels kind of wrong. I'll think about it and get back to you.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, ignore my first section of the comment. I completely missed the return statement

@@ -87,6 +97,15 @@ class Meta:
verbose_name_plural = _('supplier products')
unique_together = ('supplier', 'sku',)

@property
def unit_price(self):
return self.price / self.qty_multiplier
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be unlikely, but couldn't the multiplier end up as 0 here? I didn't see any barriers in the admin model.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's very true.


@abstractmethod
def order_product(self, sku, qty):
"""Places an order on product with given SKU.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is SKU? Please write the full definition at least once before using the abbreviation

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SKU is a well known abbreviation when you dealing with inventory management, but a clarification won't hurt anybody I guess!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that's a good justification, however it just saves readers trouble to write the full definition once at least.

)

def order_product(self, sku, qty):
pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a drive-by test? Or maybe just forgotten?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just something we need to do as long we keep DummySupplierAPI around. All the methods in SupplierBase are decorated with @abstractmethod and all the children classes need to implement all those methods, otherwise hell will break loose and Python won't run your code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

order_product is tested using another mocking method and we could probably do the same for retrieve_product and parse_delivery_report. Then, that dummy class could be removed entirely.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, yeah maybe a small refactor could be in order.

price=1,
units=1
)
sp5 = api.order_from_supplier(product1.id, 48)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my eyes, there is some black magic going on here, this should raise an exception.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why an exception?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of my first comment. I have soon finished my coffee and hope the embarrassment goes away soon.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

☕️

@kjagiello kjagiello merged commit f2ec78a into develop Mar 10, 2017
@kjagiello kjagiello deleted the feature/order-from-supplier branch March 12, 2017 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants