order.py 2.1 KB
from db.mongo import Model
from pymongo import ReadPreference
from bson.objectid import ObjectId
from pymongo.read_concern import ReadConcern
from pymongo.write_concern import WriteConcern


class Order(Model):
    def __init__(self, user_id, product_id):
        self.__id = None
        self.__user_id = user_id
        self.__product_id = product_id

    def store(self):
        client = Model.get_client()
        my_write_concern_majority = WriteConcern('majority', wtimeout=1000)

        def callback(my_session):
            product_collection = my_session.client.shoppe.products
            user_collection = my_session.client.shoppe.users

            # Important:: You must pass the session to the operations.
            p = product_collection.find_one({'_id': ObjectId(self.__product_id)}, session=my_session)
            u = user_collection.update_one(
                {'_id': ObjectId(self.__user_id)},
                {"$inc": {"balance": -1 * p["price"]}},
                session=my_session)
            print(u)
            print(p)
            pu = product_collection.update_one(
                {'_id': ObjectId(self.__product_id)},
                {"$inc": {"available": -1}},
                session=my_session)

            print(pu)

        # . Step 2: Start a client session.

        with client.start_session() as session:
            # Step 3: Use with_transaction to start a transaction, execute the callback, and commit (or abort on error).

            session.with_transaction(callback,
                                     read_concern=ReadConcern('local'),
                                     write_concern=my_write_concern_majority,
                                     read_preference=ReadPreference.PRIMARY)

        res = Order.get_collection().insert_one(self.to_dict())
        return str(res.inserted_id)

    @staticmethod
    def get_collection():
        return Model.get_db().get_collection("orders")

    @staticmethod
    def dict_to_object(dictionary):
        pass

    def to_dict(self):
        return {
            "user_id": self.__user_id,
            "product_id": self.__product_id
        }