示例#1
0
 def export_quantity_url(self, url, key, filters, quantity):
     api = PrestaShopWebServiceDict(url, key)
     response = api.search(self._prestashop_model, filters)
     for stock_id in response:
         res = api.get(self._prestashop_model, stock_id)
         first_key = res.keys()[0]
         stock = res[first_key]
         stock['quantity'] = int(quantity)
         try:
             api.edit(self._prestashop_model,
                      {self._export_node_name: stock})
         except ElementTree.ParseError:
             pass
示例#2
0
 def export_quantity_url(self, url, key, filters, quantity):
     api = PrestaShopWebServiceDict(url, key)
     response = api.search(self._prestashop_model, filters)
     for stock_id in response:
         res = api.get(self._prestashop_model, stock_id)
         first_key = res.keys()[0]
         stock = res[first_key]
         stock['quantity'] = int(quantity)
         try:
             api.edit(self._prestashop_model, {
                 self._export_node_name: stock
             })
         except ElementTree.ParseError:
             pass
示例#3
0
from __future__ import print_function
from prestapyt import PrestaShopWebServiceDict
from xml.etree import ElementTree


prestashop = PrestaShopWebServiceDict('http://localhost:8080/api',
                                  'BVWPFFYBT97WKM959D7AVVD0M4815Y1L',)
print(prestashop.get(''))
print(prestashop.head(''))
print(prestashop.get('addresses', 1))
print(prestashop.get('products', 1))

address_data = prestashop.get('addresses', 1)
address_data['address']['firstname'] = 'Robert'
prestashop.edit('addresses', address_data)

address_data = prestashop.get('addresses', options={'schema': 'blank'})
address_data['address'].update({'address1': '1 Infinite Loop',
                                'address2': '',
                                'alias': 'manufacturer',
                                'city': 'Cupertino',
                                'company': '',
                                'deleted': '0',
                                'dni': '',
                                'firstname': 'STEVE',
                                'id_country': '21',
                                'id_customer': '',
                                'id_manufacturer': '1',
                                'id_state': '5',
                                'id_supplier': '',
                                'lastname': 'JOBY',
示例#4
0
class Api(Core):
    def __init__(self, frame, log_interface, dsn, ip, key, debug=DebugApi()):
        """
        NB : The application is trying to connect at the instantiation of the object
        If you want to connect manually, use the connect() method
        :type frame: Tk
        :type log_interface: Log
        :type dsn: str
        :type ip: str
        :type key: str
        """
        super().__init__(frame, log_interface)
        # UI parameters
        self.dsn = dsn
        self.ip = ip
        self.key = key
        # DB
        self.gdr_db = DatabaseODBC()
        # Api
        self.api = None
        # Connect
        # self.i_log.draw_logs = False
        self.connect()
        # self.i_log.draw_logs = True
        # Debug
        self.debug = debug

    def connect(self):
        """
        Connects to the API and the GDR DB
        """
        # GDR connection
        self.i_log.add("Connexion à la BDD GDR")
        if self.gdr_db.connect(self.dsn):
            self.i_log.add("Connexion réussie")
        else:
            self.i_log.add("Connexion échouée")
        # Api connection
        self.i_log.add("Connexion à l'API")
        self.api = PrestaShopWebServiceDict(self.ip, self.key)
        try:
            self.api.get('')
            self.i_log.add("Connexion réussie")
        # PrestaShopAuthentificationError inherits of PrestaShopWebServiceError
        except PrestaShopAuthenticationError as PSAuthErr:
            self.i_log.add(f"Authentification échouée : {PSAuthErr}")
        except PrestaShopWebServiceError as PSWebServiceErr:
            self.i_log.add(f"Connexion échouée : {PSWebServiceErr}")

    def add_id(self, id_product, title, cat_name):
        gdr_cur = self.gdr_db.DB.cursor()
        # Photos not included atm
        self.i_log.add(f"Ajout du produit {id_product}")
        gdr_cur.execute(f"SELECT {l_to_str(self.product_cols)} FROM Produit WHERE IDProduit={id_product}")
        gdr_con = gdr_cur.fetchone()
        if gdr_con is not None:
            gdr_prod = {}
            for v in range(len(gdr_con)):
                gdr_prod[self.product_cols[v]] = gdr_con[v]
            # Reqs can not be moved since gdr_prod needs to be set
            reqs = [
                (gdr_prod['Nombre'], ([0], False, "La quantité de ce produit est à 0")),
                (gdr_prod['IDSortie'], ([0, 1], True, "Ce produit ne peut pas être mis en vente"))
            ]
            if self.requirements(reqs) or self.debug.force_reqs:
                prod_exists = False
                for id_prod in self.get_indexes(('product', 'products')):
                    if self.api.get('products', id_prod)['product']['reference'] == str(id_product):
                        prod_exists = True
                        break  # opti
                if prod_exists and not self.debug.force_yes:
                    self.i_log.add(f"La référence {id_product} existe déjà dans la base de données")
                    yesno(self.frame, "Duplicata",
                          "La référence existe déjà dans la base de données, voulez-vous la mettre à jour?",
                          lambda: self.do_prod(id_product, title, cat_name, gdr_prod, True))
                else:
                    self.do_prod(id_product, title, cat_name, gdr_prod, prod_exists)
                self.i_log.add("Produit ajouté")
                return True
        else:
            self.i_log.add(f"ID {id_product} incorrecte")
        return False

    def do_prod(self, id_product, title, cat_name, gdr_prod, edit=False):
        """
        :param id_product: The IDProduit in GDR
        :type id_product: int
        :type title: str
        :type cat_name: str
        :param gdr_prod: {title : field} of the Produit table in HDR
        :type gdr_prod: dict
        :param edit: if the object is edited or simply added
        :return: The JSON response when the product was added
        :rtype: dict
        """
        # Ajout ou non de catégorie
        cat_exists = self.x_exists(('category', 'categories'), 'name', cat_name)
        id_cat = cat_exists[1]
        if cat_exists[0]:
            self.i_log.add("Catégorie trouvée")
        else:
            self.i_log.add(f"Ajout {cat_name}")
            id_cat = self.add_cat(cat_name)['id']
            self.i_log.add(f"Catégorie ajoutée")

        # Ajout produit
        date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        prod_schema = self.api.get('products', options={'schema': 'blank'})['product']
        prod_dict = {
            'id_category_default': f"{id_cat}",
            'id_shop_default': f"{1}",
            'reference': f"{id_product}",
            'width': f"{gdr_prod['Largeur']}",
            'height': f"{gdr_prod['Hauteur']}",
            'depth': f"{gdr_prod['Profondeur']}",
            'weight': f"{gdr_prod['Poids']}",
            'state': f"{1}",
            'minimal_quantity': f"{1}",
            'price': f"{float(gdr_prod['PrixUnitaire'])}",
            'wholesale_price': f"{int(gdr_prod['PrixUnitaire']) * int(gdr_prod['Nombre'])}",
            'active': f"{1}",
            'redirect_type': f"'301-product'",
            'available_for_order': f"{1}",
            'show_condition': f"{1}",
            'show_price': f"{1}",
            'condition': f"refurbished",
            'date_add': f"{date}",
            'date_upd': f"{date}"
        }
        prod_schema = {**prod_schema, **prod_dict}
        link_rewrite = cat_name.lower().encode("ascii", "ignore").decode("utf-8")
        self.set_lang(prod_schema, 'link_rewrite', link_rewrite)
        self.set_lang(prod_schema, 'name', title)
        # Association des catégories au produit
        prod_schema['associations']['categories']['category'] = [{'id': '2'}, {'id': f"{id_cat}"}]
        # Edit de l'objet si exigé
        if edit:
            p_idx = self.get_indexes(('product', 'products'))
            i = len(p_idx)
            for i in p_idx:
                curr_prod = self.api.get('products', i)['product']
                if curr_prod['reference'] == str(id_product):
                    break
            prod_schema['id'] = i
            p_act = self.api.edit
        else:
            p_act = self.api.add
        last_prod = p_act('products', {'product': prod_schema})['prestashop']['product']

        # Ajout image
        self.i_log.add("Ajout image")
        if self.do_img(id_product, last_prod['id']):
            self.i_log.add("Image ajoutée")

        # Ajout quantité
        sa_schema = self.api.get('stock_availables', options={'schema': 'blank'})['stock_available']
        prod_asc = last_prod['associations']
        sa_dict = {
            'id': f"{prod_asc['stock_availables']['stock_available']['id']}",
            'id_product': f"{last_prod['id']}",
            'id_product_attribute': f"{prod_asc['stock_availables']['stock_available']['id_product_attribute']}",
            'id_shop': f"{1}",
            'quantity': f"{gdr_prod['Nombre']}",
            'depends_on_stock': f"{0}",
            'out_of_stock': f"{2}"
        }
        sa_schema = {**sa_schema, **sa_dict}
        self.api.edit('stock_availables', {'stock_available': sa_schema})
        return last_prod

    def do_img(self, id_prod, ps_id_prod):
        cur_gdr = self.gdr_db.DB.cursor()
        cur_gdr.execute(f"SELECT Photo FROM Produit WHERE IDProduit={id_prod}")
        gdr_con = cur_gdr.fetchall()
        if len(gdr_con[0]) > 0:
            photo = bytes(gdr_con[0][0])
            files = {'image': (f"image-{1}.png", photo)}
            img_url = f"{self.ip}/api/images/products/{ps_id_prod}"
            # debug = requests.get(img_url, auth=HTTPBasicAuth(self.key, ''))
            return requests.post(img_url, files=files, auth=HTTPBasicAuth(self.key, ''))
        else:
            self.i_log.add("Image non trouvée")
            return False

    def add_cat(self, cat):
        """
        :param cat: The name of the category to add
        :type cat: str
        :return: The JSON response when the category was added
        """
        cat_schema = self.api.get('categories', options={'schema': 'blank'})['category']
        date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        cat_dict = {
            'id_parent': f"{2}",
            'active': f"{1}",
            'position': f"{0}",
            'date_add': f"{date}",
            'date_upd': f"{date}",
        }
        cat_schema = {**cat_schema, **cat_dict}
        self.set_lang(cat_schema, 'name', cat)
        link_rewrite = cat.lower().encode("ascii", "ignore").decode("utf-8")
        self.set_lang(cat_schema, 'link_rewrite', link_rewrite)
        return self.api.add('categories', {'category': cat_schema})['prestashop']['category']

    def sync_ventes(self):
        gdr_cur = self.gdr_db.DB.cursor()
        self.i_log.add("Synchronisation des ventes")
        for id_prod in self.get_indexes(('product', 'products')):
            nvc = rev_col(self.ventes_cols)
            reference = self.api.get('products', id_prod)['product']['reference']
            gdr_cur.execute(
                f"SELECT {l_to_str(self.ventes_cols)} FROM Lignes_Vente WHERE IDProduit={reference}")
            sells = gdr_cur.fetchall()
            for s1 in sells:
                ex_sum = 0
                for s2 in sells:
                    if s1[nvc['IDProduit']] == s2[nvc['IDProduit']]:
                        ex_sum += s2[nvc['Montant']]
                if ex_sum >= 0 and self.x_exists(('product', 'products'), 'reference', reference)[0]:
                    # Modification produit
                    prod_schema = self.api.get('products', id_prod)['product']
                    prod = {
                        'on_sale': f"{0}",
                        'active': f"{0}",
                        'available_for_order': f"{0}"
                    }
                    prod_schema = {**prod_schema, **prod}
                    # Those two attributes are not writable
                    prod_schema.pop('manufacturer_name')
                    prod_schema.pop('quantity')
                    # The position in category is sometimes over evaluated
                    pos_cat = int(prod_schema['position_in_category']['value'])
                    if pos_cat > 0:
                        pos_cat -= 1
                    prod_schema['position_in_category']['value'] = f"{pos_cat}"

                    last_prod = self.api.edit('products', {'product': prod_schema})['prestashop']['product']

                    # Modification quantité
                    sa_schema = self.api.get('stock_availables', int(
                        last_prod['associations']['stock_availables']['stock_available']['id']))[
                        'stock_available']
                    sa = {
                        'quantity': f"{0}",
                        'out_of_stock': f"{1}"
                    }
                    sa_schema = {**sa_schema, **sa}
                    self.api.edit('stock_availables', {'stock_available': sa_schema})
                    self.i_log.add(f"{id_prod} mis à jour")
        self.i_log.add("Images synchronisées")

    def set_lang(self, schema, key, name):
        """
        Sets the name in 2 languages e.g English and French
        :param schema: The schema you're inserting the lang into
        :type schema: dict
        :param key: Key where the language is situated
        :type key: str
        :param name: The name that'll be displayed, the same in the 2 languages
        :type name: str
        :return: The schema now modified
        :rtype: dict
        """
        # e.g. key : {'language': [{'attrs': {'id': '1'}, 'value': name}, {'attrs': {'id': '2'}, 'value': name}]}
        try:
            klang = schema[key]['language']
            if isinstance(klang, dict):
                klang['value'] = name
            else:  # if there is more than one lang
                for lang in klang:
                    lang['value'] = name
            return schema
        except KeyError:
            schema[key] = {'language': [{'attrs': {'id': f"{idl}"}, 'value': ''} for idl in
                                        self.get_indexes(('language', 'languages'))]}
            return self.set_lang(schema, key, name)

    def reset_db(self):
        """
        Only resets products and categories
        """
        prods = self.get_indexes(('product', 'products'))
        if prods:
            self.i_log.add("Suppression des produits")
            self.api.delete('products', prods)
            self.i_log.add("Produits supprimés")
        cats = self.get_indexes(('category', 'categories'))[2:]
        if cats:
            self.i_log.add("Suppression des catégories")
            self.api.delete('categories', cats)
            self.i_log.add("Catégories supprimées")
        # stock_available n'est pas deletable

    def x_exists(self, head_name, x, name):
        """
        Check if the name exists in the objects list
        :param head_name: singular[0], plural[1]
        :type head_name: tuple
        :param x: The column you're looking into
        :type x: str
        :type name: str
        :return: [0] : exists?, [1]: where in the list
        :rtype: tuple
        """
        hid = 0
        for hid in self.get_indexes(head_name):
            col = self.api.get(head_name[1], hid)[head_name[0]][x]
            if isinstance(col, dict):
                try:
                    if col['language'][0]['value'] == name:
                        return True, hid
                except KeyError:
                    if col['language']['value'] == name:
                        return True, hid
            if col == name:
                return True, hid
        return False, hid

    def get_indexes(self, head_name):
        """
        Get all indexes for the head_name
        :param head_name: singular[0], plural[1]
        :type head_name: tuple
        :rtype: list
        """
        head = self.api.get(head_name[1])[head_name[1]]
        if head != '':
            hh = head[head_name[0]]
            if not isinstance(hh, dict):
                return [int(attr['attrs']['id']) for attr in hh]
            return [int(hh['attrs']['id'])]
        return []