Your IP : 216.73.217.13


Current Path : /home/deltalab/PMS/recommendations/recomsys-datapreparation-batch/components/
Upload File :
Current File : //home/deltalab/PMS/recommendations/recomsys-datapreparation-batch/components/DbService.py

import json
from os import path
from _library.data_utils.io_toolkit import read_settings, read_indaco_credentials

from sqlalchemy import create_engine,text
import pandas as pd

from components.mongoDbService import MongoDB
from pandas import DataFrame

class DbService:

    def __init__(self,db_type):
        appSettings = read_settings()
        self.db_type = db_type
        if(db_type in appSettings['databaseName']):
            hostname, port, username, password, db_name = read_indaco_credentials(db_type)
        else:
            print(f"Database not available! ?{appSettings['databaseName']}?")
            exit(1)

        if db_type == "mongodb":
            self.db_service = MongoDB(hostname, port, username, password, db_name)
        else:            
            #url_engine = f"mssql+pymssql://{username}:{password}@{hostname}:{port}/{db_name}?&Trusted_Connection=yes&TrustedServerCertificate=yes"
            url_engine = f"mssql+pymssql://{username}:{password}@{hostname}:{port}/{db_name}"

            self.db_service = create_engine(url_engine) 
        
            
    # --------------------------- GET DATA --------------------------------------------------
    def get_productTypes(self) -> DataFrame:
        if(self.db_type == "mongodb"):
            productTypes = self.db_service.getProductTypes()
        else:

            query = '''

            SELECT cat1._id,
                cat1.label AS 'categoryName',
                cat1.googleId,
                cat2.label AS 'parent',
                cat1.isRoot,
                cat1.isLeaf,
                cat1.createdAt,
                cat1.updatedAt
            FROM dbo.pms_categories cat1
            INNER JOIN dbo.pms_categories cat2 ON (cat1.parentId = cat2._id)

            '''
      
            productTypes = self.execute_query(query)
        return productTypes
    
    def get_products(self, consider_delatedProducts = False, consider_unavailableProducts = False) -> DataFrame:
        if(self.db_type == "mongodb"):
            products = self.db_service.getProducts(consider_delatedProducts, consider_unavailableProducts)
        else:

            query = '''

             SELECT 
                DISTINCT pms_products.title, 
                pms_products.sku, 
                pms_products.brand, 
                _id, 
                pms_products.categoryId, 
                pms_products.partnerId, 
                ISNULL(
                    indaco_general_productionarea,-1
                ) AS 'production_areas'
                FROM 
                pms_products 
                INNER JOIN pms_products_offers ON (
                    pms_products._id = pms_products_offers.parent_id
                ) 
                INNER JOIN pms_products_inventoryLevels_object ON(
                    pms_products._id = pms_products_inventoryLevels_object.parent_ID
                ) 
                INNER JOIN (
                    SELECT 
                    parent_id, 
                    indaco_general_productionarea
                    FROM 
                    (
                        SELECT 
                        parent_id, 
                        NAME, 
                        value 
                        FROM 
                        pms_products_offers_attributes
                    ) s PIVOT (
                        Max(value) FOR NAME IN (
                        indaco_general_productionarea
                        )
                    ) AS p
                ) AS p ON (pms_products._id = p.parent_id) 
                WHERE 
                pms_products_offers.deleted = 0
            
            '''
      
            products = self.execute_query(query)
            products['production_areas'].fillna(-1,inplace=True)

            # Convert the production areas codes into names
            file_path = path.join('_library', 'INDACO_collectionCodes.json')
            
            with open(file_path) as jsonFile:
                collectionTypes = json.load(jsonFile)
            
            productionArea_codes = collectionTypes['production_areas']
            products['production_areas'] = products['production_areas'].apply(
                lambda area_code: 
                    productionArea_codes[str(area_code)].capitalize() 
                    if str(area_code) in productionArea_codes.keys() else f"Unknown (code:{area_code})"
                    if int(area_code) != -1 else ""
            )
        return products
    
    # def get_dBproduct(self, item_sku, as_dict):
    #     product = self.db_service.getProduct(item_sku, as_dict)
    #     print("get_dBproduct:", type(product))
    #     return product
    
    def get_sellers(self, sellerId = None):
        if(self.db_type == "mongodb"):
            sellers = self.db_service.getSellers(sellerId)
        else:
            query = '''

             SELECT 
                pms_partners._id, 
                companyName, 
                email, 
                address, 
                pms_partners.phone, 
                pms_warehouses._id AS "warehouse_id", 
                vatNumber, 
                active, 
                pms_partners.createdAt, 
                pms_partners.updatedAt 
                FROM 
                pms_partners 
                INNER JOIN pms_warehouses ON (
                    pms_partners._id = pms_warehouses.partnerId
                )

            '''
      
            sellers = self.execute_query(query)
        return sellers
    
    # def get_warehouses(self) -> DataFrame:
    #     warehouses = self.db_service.getWarehouses()
    #     return warehouses
    
    def get_orders(self) -> DataFrame:
        if(self.db_type == "mongodb"):
            orders = self.db_service.getOrders()
        else:
            query = '''
             SELECT DISTINCT dbo.magento_sales_order.entity_id AS 'Transaction id',
                dbo.magento_sales_order.created_at AS 'timestamp',
                name AS 'product_name',
                sku,
                qty_ordered AS 'quantity'
            FROM dbo.magento_sales_order
                        
                        
            INNER JOIN (SELECT email,consent2,consent4, 
            MAX([timestamp]) AS most_recent_signin
            FROM dbo.iubenda_consent
            WHERE consent2 IS NOT NULL AND email IS NOT NULL
            GROUP BY email,consent2,consent4) AS t_consensi
                        ON (dbo.magento_sales_order.customer_email = t_consensi.email)
                        INNER JOIN dbo.magento_customer_entity
                        ON (customer_id = dbo.magento_customer_entity.entity_id)
                        INNER JOIN dbo.magento_sales_order_item
                        ON (dbo.magento_sales_order.entity_id = dbo.magento_sales_order_item.order_id)
                        WHERE t_consensi.consent2 = 1

            '''
      
            orders = self.execute_query(query)
        return orders

    # -------------------------- SQLALCHEMY ----------------------------
    def execute_query(self,query_str):
        query = text(query_str)
        with self.db_service.begin() as conn:
            toRtn = pd.read_sql_query(query, conn)
        return toRtn

    # def get_productTypeInfo(self, category_name) -> dict:
    #     categoryInfo = self.db_service.getCategoryInfo(category_name)
    #     return categoryInfo
    
    # def get_decryptedUsers(self, userIds) -> dict:
    #     decryptedUsers = self.db_service.decryptCustomers(userIds)
    #     decryptedUsers = dict(zip(userIds, decryptedUsers))
    #     return decryptedUsers
    
    # def get_customerProfiles(self) -> dict:
    #     userProfiles = self.db_service.getCustomerProfiles()
    #     return userProfiles
    
    # -------------------------- WRITE DATA ----------------------------
    # def write_newDbItem(self, tableName, object):
    #     self.db_service.writeNewDbItem(tableName, object)
    
    # def drop_existingTable(self, tableName):
    #     self.db_service.dropCollection(tableName)
    
    # def update_attributeDbItem(self, object, attribute_name, attribute_value):
    #     self.db_service.setNewProductAttribute(object, attribute_name, attribute_value)        
    # ---------------------------------------------------------------------------------------