class EmailSubscription(db.Model): __tablename__ = ProdTables.EmailSubscriptionTable email_subscription_id = db.Column(db.Integer, primary_key = True, autoincrement = True) email = db.Column(db.String, nullable = False) unsubscribe_id = db.Column(db.String, unique = True) email_list_name = db.Column(db.String, db.ForeignKey(ProdTables.EmailListTable + '.' + Labels.EmailListName)) email_list_id = db.Column(db.Integer, db.ForeignKey(ProdTables.EmailListTable + '.' + Labels.EmailListId)) date_created = db.Column(db.DateTime, default=db.func.current_timestamp()) date_modified = db.Column(db.DateTime, default=db.func.current_timestamp(), onupdate=db.func.current_timestamp()) def __init__(self, email, email_list_id, email_list_name): self.email = email self.email_list_id = email_list_id self.email_list_name = email_list_name db.Model.__init__(self) @staticmethod def generateUnsubscribeKey(): new_unsubscribe_id = IdUtil.id_generator() missing = EmailSubscription.query.filter_by(unsubscribe_id = new_unsubscribe_id).one() while missing is not None: new_unsubscribe_id = IdUtil.id_generator() missing = User.query.filter_by(unsubscribe_id = new_unsubscribe_id).one() return new_unsubscribe_id @staticmethod def getEmailListSubscribers(email_list_name): subscribers_query = EmailSubscription.query.filter_by(email_list_name = email_list_name).all() return [subscriber.email for subscriber in subscribers_query] @staticmethod def addEmailSubscription(email, email_list_id): email_list_name = EmailList.getEmailListNameById(email_list_id) if not email_list_name: return None new_sub = EmailSubscription(email, email_list_id) db.session.add(new_sub) db.session.commit(new_sub) return new_sub.toPublicDict() def toPublicDict(self): public_dict = {} public_dict[Labels.Email] = self.email public_dict[Labels.EmailListId] = self.email_list_id public_dict[Labels.EmailListName] = self.email_list_name public_dict[Labels.UnsubscribeId] = self.unsubscribe_id return public_dict
class ManufacturerLogo(db.Model): __tablename__ = ProdTables.ManufacturerLogoTable logo_id = db.Column(db.String, primary_key=True) product_id = db.Column( db.Integer, db.ForeignKey(ProdTables.MarketProductTable + '.' + Labels.ProductId)) soft_deleted = db.Column(db.Boolean, default=False) date_created = db.Column(db.DateTime, default=db.func.current_timestamp()) date_modified = db.Column(db.DateTime, default=db.func.current_timestamp(), onupdate=db.func.current_timestamp()) def __init__(self, product_id): self.product_id = product_id self.logo_id = ManufacturerLogo.generateLogoId() db.Model.__init__(self) @staticmethod def generateLogoId(): new_logo_id = ENVIRONMENT + "/" + IdUtil.id_generator() missing = ManufacturerLogo.query.filter_by(logo_id=new_logo_id).first() while missing is not None: new_logo_id = ENVIRONMENT + "/" + IdUtil.id_generator() missing = ManufacturerLogo.query.filter_by( logo_id=new_logo_id).first() return new_logo_id def toPublicDict(self): public_dict = {} public_dict['product_id'] = self.product_id public_dict['logo_id'] = self.logo_id return public_dict
class ProductVariant(db.Model): __tablename__ = ProdTables.ProductVariantTable variant_id = db.Column(db.Integer, primary_key = True, autoincrement = True) product_id = db.Column(db.Integer, db.ForeignKey(ProdTables.MarketProductTable + '.' + Labels.ProductId)) inventory = db.Column(db.Integer, default = 0) variant_type = db.Column(db.String) active = db.Column(db.Boolean, default = False) price = db.Column(db.Integer) date_created = db.Column(db.DateTime, default=db.func.current_timestamp()) date_modified = db.Column(db.DateTime, default=db.func.current_timestamp(), onupdate=db.func.current_timestamp()) def __init__(self, product_id, variant_type, price, inventory = 0): self.product_id = product_id self.variant_type = variant_type self.price = price self.inventory = inventory db.Model.__init__(self) def updateVariant(self, variant): new_inventory = variant.get(Labels.Inventory) if new_inventory: self.inventory = new_inventory new_price = variant.get(Labels.Price) if new_price: self.price = new_price new_type = variant.get(Labels.VariantType) if new_type: self.variant_type = new_type db.session.commit() def delete(self): db.session.delete(self) db.session.commit() @staticmethod def activateVariant(variant_id): this_variant = ProductVariant.query.filter_by(variant_id = variant_id).first() this_variant.active = True db.session.commit() @staticmethod def deactivateVariant(variant_id): this_variant = ProductVariant.query.filter_by(variant_id = variant_id).first() this_variant.active = False db.session.commit() def toPublicDict(self): public_dict = {} public_dict[Labels.Inventory] = self.inventory public_dict[Labels.VariantType] = self.variant_type public_dict[Labels.ProductId] = self.product_id public_dict[Labels.VariantId] = self.variant_id public_dict[Labels.Active] = self.active public_dict[Labels.Price] = self.price return public_dict
class RelatedProductTag(db.Model): __tablename__ = ProdTables.RelatedProductTagTable product_tag_id = db.Column(db.Integer, primary_key=True, autoincrement=True) tag = db.Column(db.String) product_id = db.Column( db.Integer, db.ForeignKey(ProdTables.MarketProductTable + '.' + Labels.ProductId)) date_created = db.Column(db.DateTime, default=db.func.current_timestamp()) date_modified = db.Column(db.DateTime, default=db.func.current_timestamp(), onupdate=db.func.current_timestamp()) def __init__(self, product_id, tag): self.product_id = product_id self.tag = tag db.Model.__init__(self) def toPublicDict(self): public_dict = {} public_dict['product_id'] = self.product_id public_dict['tag'] = self.tag return public_dict
class OrderItem(db.Model): __tablename__ = ProdTables.OrderItemTable primary_key = db.Column(db.Integer, primary_key=True, autoincrement=True) date_created = db.Column(db.DateTime, default=db.func.current_timestamp()) date_modified = db.Column(db.DateTime, default=db.func.current_timestamp(), onupdate=db.func.current_timestamp()) price = db.Column(db.Integer) num_items = db.Column(db.Integer) variant_id = db.Column(db.Integer) name = db.Column(db.String) main_image = db.Column(db.String) product_id = db.Column( db.Integer, db.ForeignKey(ProdTables.MarketProductTable + '.' + Labels.ProductId)) account_id = db.Column( db.Integer, db.ForeignKey(ProdTables.UserInfoTable + '.' + Labels.AccountId)) # order_id = db.Column(db.String) order_id = db.Column( db.String, db.ForeignKey(ProdTables.OrderTable + "." + Labels.OrderId)) # name,email, password all come from user inputs # email_confirmation_id, stripe_customer_id will be generated with try statements def __init__(self, order_id, user, product, num_items=1, variant_id=None, variant_type=None): self.order_id = order_id self.price = product.price self.num_items = num_items if variant_type: self.name = product.name + " - " + variant_type else: self.name = product.name self.product_id = product.product_id self.account_id = user.account_id self.variant_id = variant_id self.main_image = product.main_image this_order = Order.query.filter_by(order_id=order_id).first() if this_order: self.date_created = this_order.date_created db.Model.__init__(self) def toPublicDict(self): public_dict = {} public_dict[Labels.OrderId] = self.order_id public_dict[Labels.NumItems] = self.num_items public_dict[Labels.Price] = self.price public_dict[Labels.TotalPrice] = self.price * self.num_items public_dict[Labels.DateCreated] = self.date_created public_dict[Labels.ProductId] = self.product_id public_dict[Labels.VariantId] = self.variant_id public_dict[Labels.Name] = self.name public_dict[Labels.MainImage] = self.main_image return public_dict
class Order(db.Model): __tablename__ = ProdTables.OrderTable order_id = db.Column(db.String, primary_key=True) items_price = db.Column(db.Integer) order_shipping = db.Column(db.Integer) sales_tax_price = db.Column(db.Integer, default=0) total_price = db.Column(db.Integer) refund_date = db.Column(db.DateTime) stripe_customer_id = db.Column(db.String, nullable=False) stripe_charge_id = db.Column(db.String) lob_address_id = db.Column(db.String) address_line1 = db.Column(db.String) address_line2 = db.Column(db.String) address_zip = db.Column(db.String) address_country = db.Column(db.String) address_city = db.Column(db.String) address_name = db.Column(db.String) address_description = db.Column(db.String) address_state = db.Column(db.String) card_last4 = db.Column(db.String) card_brand = db.Column(db.String) discounts = db.Column(db.Integer) date_created = db.Column(db.DateTime, default=db.func.current_timestamp()) date_modified = db.Column(db.DateTime, default=db.func.current_timestamp(), onupdate=db.func.current_timestamp()) account_id = db.Column( db.Integer, db.ForeignKey(ProdTables.UserInfoTable + '.' + Labels.AccountId)) def __init__(self, user, cart, address): self.order_id = self.generateOrderId() self.items_price = cart.getCartItemsPrice() self.order_shipping = cart.getCartShippingPrice(address) self.account_id = user.account_id self.stripe_customer_id = user.stripe_customer_id self.lob_address_id = address.id self.sales_tax_price = cart.getCartSalesTaxPrice(address) self.address_name = address.name self.address_description = address.description self.address_city = address.address_city self.address_country = address.address_country self.address_line1 = address.address_line1 self.address_line2 = address.address_line2 self.address_zip = address.address_zip self.address_state = address.address_state self.total_price = self.items_price + self.order_shipping + self.sales_tax_price self.discounts = cart.toPublicDict().get(Labels.Discounts) db.Model.__init__(self) @staticmethod def getOrderById(order_id): this_order = Order.query.filter_by(order_id=order_id).first() if this_order: return this_order else: return None def addItems(self, this_user, this_cart, address): # record this transaction for each product (enabling easier refunds), but group by quantity for cart_item in this_cart.items: # update the inventory this_product = MarketProduct.query.filter_by( product_id=cart_item.product_id).first() if cart_item.variant_type: this_variant = ProductVariant.query.filter_by( variant_id=cart_item.variant_id).first() if this_variant: new_inventory = this_variant.inventory - cart_item.num_items if new_inventory < 0: error_message = str(this_product.name) + " " + str(cart_item.variant_type) + " is out of stock. You can only purchase " \ + str(this_variant.inventory) + ". Please adjust your quantity and try again" return { Labels.Error: error_message, Labels.Inventory: this_variant.inventory, Labels.CartItem: cart_item } else: this_variant.inventory = new_inventory else: return { Labels.Error: "Seems like you tried to order a type that doesn't exist. Check your cart and try again." } else: new_inventory = this_product.inventory - cart_item.num_items if new_inventory < 0: error_message = str(this_product.name) + " is out of stock. You can only purchase " + str(this_product.inventory) \ + ". Please adjust your quantity and try again" return { Labels.Error: error_message, Labels.Inventory: this_product.inventory, Labels.CartItem: cart_item } else: this_product.inventory = new_inventory order_shipping = this_cart.getCartShippingPrice(address) new_order_item = OrderItem(self.order_id, this_user, this_product, cart_item.num_items, cart_item.variant_id, cart_item.variant_type) db.session.add(new_order_item) return None @staticmethod def generateOrderId(): new_order_id = IdUtil.id_generator() missing = Order.query.filter_by(order_id=new_order_id).first() while missing: new_order_id = IdUtil.id_generator() missing = OrderItem.query.filter_by(order_id=new_order_id).first() return new_order_id def updateCharge(self, charge): self.stripe_charge_id = charge[Labels.Id] self.card_last4 = charge[Labels.Source][Labels.Last4] self.card_brand = charge[Labels.Source][Labels.Brand] db.session.commit() def toPublicDict(self): public_dict = {} public_dict[Labels.OrderId] = self.order_id order_items = OrderItem.query.filter( OrderItem.order_id == self.order_id, OrderItem.num_items > 0).all() public_dict[Labels.Items] = [ item.toPublicDict() for item in order_items ] public_dict[Labels.ItemsPrice] = self.items_price public_dict[Labels.OrderShipping] = self.order_shipping public_dict[Labels.TotalPrice] = self.total_price public_dict[Labels.DateCreated] = self.date_created address = { Labels.AddressName: self.address_name, Labels.AddressDescription: self.address_description, Labels.AddressCity: self.address_city, Labels.AddressCountry: self.address_country, Labels.AddressLine1: self.address_line1, Labels.AddressLine2: self.address_line2, Labels.AddressZip: self.address_zip, Labels.AddressState: self.address_state } public_dict[Labels.Address] = address public_dict[Labels.CardLast4] = self.card_last4 public_dict[Labels.CardBrand] = self.card_brand public_dict[Labels.SalesTaxPrice] = self.sales_tax_price public_dict[Labels.Discounts] = self.discounts # public_dict[Labels.Card] = StripeManager.getCardFromChargeId(self.stripe_charge_id) return public_dict
class CartItem(db.Model): __tablename__ = ProdTables.ShoppingCartTable cart_id = db.Column(db.Integer, primary_key=True, autoincrement=True) account_id = db.Column( db.Integer, db.ForeignKey(ProdTables.UserInfoTable + '.' + Labels.AccountId)) product_id = db.Column( db.Integer, db.ForeignKey(ProdTables.MarketProductTable + '.' + Labels.ProductId)) num_items = db.Column(db.Integer) num_items_limit = db.Column(db.Integer) variant_id = db.Column(db.String) variant_type = db.Column(db.String) date_created = db.Column(db.DateTime, default=db.func.current_timestamp()) date_modified = db.Column(db.DateTime, default=db.func.current_timestamp(), onupdate=db.func.current_timestamp()) def __init__(self, account_id, product_id, num_items, variant_id=None, variant_type=None): self.account_id = account_id self.product_id = product_id self.num_items = num_items self.variant_id = variant_id self.variant_type = variant_type self.num_items_limit = MarketProduct.query.filter_by( product_id=product_id).first().num_items_limit db.Model.__init__(self) # called with a try statement def updateCartQuantity(self, new_num_items): # confirm num_items is an integer assert (new_num_items >= 0) assert (new_num_items % 1 == 0) if new_num_items == 0: self.deleteItem() elif new_num_items > self.num_items_limit: raise Exception("You've reached your limit for this product (" + str(self.num_items_limit) + "). You are now at your limit.") else: self.num_items = new_num_items db.session.commit() def deleteItem(self): CartItem.query.filter_by(cart_id=self.cart_id).delete() db.session.commit() def toPublicDict(self): public_dict = {} public_dict[Labels.CartId] = self.cart_id public_dict[Labels.NumItems] = self.num_items public_dict[Labels.ProductId] = self.product_id public_dict[Labels.AccountId] = self.account_id public_dict[Labels.NumItemsLimit] = min(self.num_items_limit, self.num_items) public_dict[Labels.VariantId] = self.variant_id return public_dict