So here is my problem.
I have a class created that extends AdminProductsControllerCore.
What it does is if you have one product that you want to split in 3 different products but have the same stock, it will have 1 master and 2 slaves.
For example:
You have reference - N101 that has stock 100, but you want to have 3 products with different reference N100FR and N100DE.
What the new class does is that if you link the 3 products, all will have the same stock. As soon as you change the stock for one, it will also change it for the other 2.
We also have a connection to a fulfillment system that manages the warehouse stock. This means that the Fulfillment software is connected through WebService to Prestashop and every change in the Fulfillment system to the stock is being sent to Prestashop. This also works very good.
Also to be noted that in the Fulfillment software we have multiple systems linked to import orders, not just prestashop so it means that some orders are never in prestashop, but the stock drops.
Now comes the problem:
If i manually (or by new order) change the stock in Prestashop, all products change qty to the new value.
But if the qty changes in the Fulfillment system, only the master sku changes stock in Prestashop.
So this actually means that the new class that changes the stock when it's manually done in Prestashop (or by creation of new order) does not work.
My question is how can i make it that when the stock is changed, that the class that i created will run?
If there is need for more details, please let me know.
Thanks in advance.
Stock update does not trigger a full product object update.
I guess your fulfillment system is calling the stock_available resource,
so one possible solution is to override the updateWs() method
to make sure your code is executed there too.
Related
This question has been asked many times before on StackOverflow and in the Django forums, but none of the answers I've found are appropriate or complete enough for my situation.
First, the brief:
I'm creating a web application for a car rental business. In addition to helping them organize and centralize their fleet, it will also help them collect orders directly from customers. As with most rentals, the logistics of it all can be somewhat confusing.
Someone may place an order for a car today (December 12th) but actually take the car over the Christmas to New Year's period.
A renter may borrow a car for just two days, and then extend the booking at the last minute. When this happens (often very frequently), the business usually has to scramble to find another one for a different customer who was scheduled to get that car the next day.
Adding to that, an individual car can only be rented to one client at a time, so it can't have multiple bookings for the same period.
Most answers advocate for a simple approach that looks like this:
models.py
class Booking(models.Model):
car = models.ForeignKey(Car, ...)
start_date = models.dateField(...)
end_date = models.dateField(...)
is_available = models.booleanField(default=True)
forms.py
import datetime
from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from . import models
class PlaceOrderForm(forms.Form):
"""Initial order forms for customers."""
start_date = forms.DateField(help_text='When do you want the car?')
end_date = forms.DateField(help_text='When will you return the car?')
def clean_data(self, date):
data = self.cleaned_data(date)
# Check that start date is not in the past
if data < datetime.date.today():
raise ValidationError(_('Invalid date: Start in past.'))
# Ensure that start date is not today (to avoid last_minute bookings.)
if data == datetime.date.today():
raise ValidationError(_('Invalid date: Please reserve your car at least 24 hours in advance.'))
return data
cleaned_start_date = clean_data(start_date)
cleaned_end_date = clean_data(end_date)
('_' is for )
The booking has a start_date and an end_date. When a current date is within the start_date and end_date, the car is marked as unavailable. If the boolean field is_available (not represented in forms.py above) is set to "False", the car is unavailable completely.
Again, because of the unique nature of car rentals, this may be a problem. Some people book a car for six months, and others book it for two days. If someone wants a long-term rental but there's another short interlude during their expected duration, this validation would prevent them from placing the order completely!
But this is a problem: Going back to the rental model, someone may be booking a car in the future. A car that's unavailable now should still be able to be reserved for a future date.
Adding to that, an individual car can only be rented to one person at a time, so it can't have multiple bookings for the same period. Again, because of the unique nature of car rentals, this may be a problem. Some people book a car for six months, and others book it for two days. If someone wants a long-term rental but there's another short interlude during their expected duration, this validation would prevent them from placing the order completely!
So if a conflict arises, rather than blocking the booking entirely (which, again, would be a bad UX decision), it should notify the business so they can assign another car and plan ahead.
Other clients should not be able to book it for the time in which it is borrowed, but they should be able to book it for other times when it is free.
So if someone places an order now for, let's say the 24-31st of December. Those days should be blocked off. However, another person should be able to book it from today to the 23rd, and from the 31st onwards. And if the person renting it should extend, it should notify the rental business so they can assign another car to the user well in advance.
Possible idea to move forward
The core assumption in all those answers is that the booking unavailability has to be handled in Django itself, in the backend. However, I'm building this project with REST framework, and will use a Js based front-end (currently learning Javascript for this purpose).
I think that this would be better handled in a more holistic way with the in-built form validation and save functions.
The workflow would go something like this:
The User selects a car and selects the start and end dates from a drop-down calendar on the website.
The form will then check to see if the absolute basic checks (can't book a car in the past) are fine. If those work, then the order is placed and saved in the database.
If there's a scheduling conflict, the order is not blocked, but passed to the business that can assign them a different car for the period. (Generally, people don't care much for receiving particular cars--mostly the price, space and the fuel economy. Everything else is interchangeable.
Once that happens, the deposit can be collected, and the order can be set in the system.
Anyhow, that's my preliminary idea that would bring together the best of all worlds
and create a great experience for both the business and customer.
So my question is: How could this actually be set up? What would need to be on the front-end and what would go in the back-end? I'm learning programming as I go, so this may be simple, but I've been struggling with this for a week, I would appreciate any help on this!
Thanks!
Sounds like you have two processes - the customer order and the car assignment. You need to plan out your data structure and then your process flow. This will help you get things straight before you start.
Models
Using (Brackets) for foreign keys, Customer_order collects things like:
Customer(User)
desired_start_date
desired_end_date
car_type - this could be many fields
A car model
car_type
rental (many to many Rental with through table Rental)
A rental model
car (Car)
customer_order(Customer_order)
start_date
end_date
We have kept the rental model with its own start and end dates as the user may change their desired period but it shouldn't change the rental dates without checking if others exist in that time period for that car.
So the flow should go:
user passes js validation and form submitted to backend
backend checks for car availability based on type and dates
if available, creates rental
if not available, alert user and passes to staff
if a user changes a rental period (via an edit screen for existing customer_orders)
backend checks for same car availability based on existing rentals
if not available, alert user and pass to staff
You'd also create a staff only view, that lists customer_orders that can't be matched (without rental models) along with cars of the requested type that don't have rentals for that period.
Seeing as you have that view, it strikes me your backend process could use something similar to also look for and assign a different car of the same type automatically if you wanted to extend the availability check process, notifying staff it has occurred, while only referring back to staff if that type of car is unavailable.
Actually programming all this is left as an exercise for the reader.
After a basic introduction to Python thanks to an edX course and a chat with a friend who told me about Django, I thought I could implement a solution for my laboratory. My goal is to keep track of every reagent order made by everyone of us researchers to the suppliers.
After one month I have a pretty decent version of it which I'm very proud of (I also have to thank a lot of StackOverFlow questions that helped me). Nonetheless, there's one requirement of the ordering flow that I haven't been able to translate to the Django app. Let me explain:
Users have a form to anotate the reagent (one per form) they need, and then it is passed to the corresponding manufacturer for them to send us an invoice. It's convenient that each invoice has several products, but they all have to: a) be sold by the same manufacturer, b) be sent to the same location and c) be charged to the same bank account (it's actually more complicated, but this will suffice for the explanation).
According to that, administrators of the app could process different orders by different users and merge them together as long as they meet the three requirements.
How would you implement this into the app regarding tables and relationships?
What I have now is an Order Model and an Order Form which has different CharFields regarding information of the product (name, reference, etc.), and then the sending direction and the bank account (which are ForeingKeys).
When the administrators (administratives) process the orders, they asign several of them that meet the requirements to an invoice, and then the problem comes: all the data has to be filled repeatedly for each of the orders.
The inmediate solution for this would be to create a Products Model and then each Order instance could have various products as long as they meet the three requirements, but this presents two problems:
1) The products table is gonna be very difficult to populate properly. Users are not gonna be concise about references and important data.
2) We would still have different Orders that could be merged into the same invoice.
I thought maybe I could let the users add fields dynamically to the Order model (adding product 1, product 2, product 3). I read about formsets, but they repeat whole Forms as far as I understood, and I would just need to repeat fields. Anyway, that would solve the first point, but not the second.
Any suggestions?
Thanks, and sorry for the long block!
I am currently building a Django application where visitors can buy an online course. I now want to implement the possibility to provide discount codes. As these discount codes should be limited by quantity I now have the following implementation idea:
Guest visits www.page.com?discount=TEST
The model discount contains the fields discount_codes & max qty. I will check here, if the code exists. Also, I have to count all entries in my order model that used the discount code TEST. My order model contains the foreign_key field 'redeemed_discounts').
As soon the user clicks on Pay (via Stripe) I'll once again count all the orders in my order model which contain 'TEST' to make sure, the 'max_qty' is not reached meanwhile.
Now I can charge the visitor.
Would you consider this as good implemented or do you see any problems with the way I am planning to do it?
instead of using max_qty why don't you use something like use_left and max_use
so whenever someone uses that code you can reduce the count accordingly and when count hits zero you can stop using that with this approach you don't have to scan order table every time to see if the coupon code is still available.
I'm trying to figure out how companies that use nosql database solve this general nosql race condition issue:
Lucky example: User and Product. Product has quantity of 1 and there are 2 users. When the first user tries to buy this product, system first checks whether quantity is > 0 and it is indeed > 0, proceeds to create a Transaction object and decrement quantity of product. The second user tries to buy the product, system rejects as quantity isn't > 0.
Unlucky: Both users try to buy the product simultaneously. For both, system confirmed quantity is > 0 and so created a Transaction object for both users, hence destroying the company image next day...
How to generally deal with this common scenario?
From similar cases i found on the net, one suggested solution is to use request queue, and process the request one by one. However, if all transactions are queued, and you're running business like Amazon (millions of transactions every now and then), how do we expect users to know whether or not their purchase succeeded shortly after they clicked that purchase now button?
One of the ways to solve this problem is to allow both users to order products simultaneously.
Then there are two possible situations:
One of the users doesn't finish a transaction (refuses to pay, closes a browser window etc). Then another one will have the requested amount of a product.
Both users finished their transactions. Then you will get a random user your product and say sorry to another one giving away a coupon with $10 to him/her.
The second situation should happen extremely rare. So you won't blow out all your money on coupons and your users will be happy whatever the outcome. But you still need to monitor the 2nd situation in order to react and make changes to your system if it happens more often than you expected.
because of MAGE price calculation complexity + EPR incompatibility with MAGE calculation, I was thinking about overriding getPrice() and getFinalPrice() methods in a way, that they will call external webservice for a requested price.
Does anybody tried to solve price calculation in a suggested way and if, does this work in a real environment?
Second option is to reverse engineer price engine from ERP in MAGE database (additinal tables + logic inside MAGE).
What do you tink? Any advice would be welcome.
I had a similar problem with complex pricing issues.
I ended up with adding some custom attribute fields that where dynamically chosen on the
customer number.
Could you give me some background on your problem?
we have very complex price calculation. Every customer has its own pricing rules(per product,per product group, special discount, etc..).
There is 15.000 customers and 60.000 items.
It is possible to add all rules into MAGE, but price indexing takes very, very long and MAGE is almost unusable. pricing engine on the other hand is not so hard to implement, but a question remain if it is possible to use price engine from ERP(ERP has API for getting a price) or is it better to implement it inside MAGE (on mysql) with extending original logic.
There is no need to have administrator GUI for checking prices, because sync is done automatically and never entered by the user. (A goal is to completely replace pricing logic from MAGE).
Thank for your answer.
After some work and testing, I did new models in Magento and reimplement price calculation logic based od ERP rules. Webservice would work, but it would be very very slow(call to getPrice or getFinalPrice is executed at least twice for every item displayed).