How I fit the Presta Shop product management system into five buttons

Attention!

After reading the article, you might get the impression that I love BDSM or something like that, but it only seems to you.





Store problems

I work in a regular bike shop in the center of Warsaw. We trade both stationary and on the Internet. Average number of bought bicycles per day ~ 2 for the whole year. At the same time, the peak of sales falls on the summer, and then we can have ~ 17 online orders a day and the same in the store, and in winter we can not sell anything at all.





In 2020. In connection with the COVID pandemic, the demand for bicycles has grown to incredible rates, and we, as a decent office, have begun to expand.





This led to the fact that at the end of last season, orders for only non-existent bicycles increased on average up to 4 times a week during the 4 most productive months. And this is ~ 16 inconsistencies on the site per month (not counting the failures in the store).





Canceled orders
Canceled orders

This year, with the appearance of another large warehouse, the situation has worsened and now, in addition to non-existent bicycles, those that were not there were added and it was often impossible to bring them to customers on time.





, - EXEL, , . , . 2 2-3 .





. , , , – , . .





, , - . . , . :





, .





:





  1. Python API PrestaShop;





  2. , -, . ;





  3. Chrome . , Chrome.





middle-, . .





API PrestaShop

API PrestaShop Python , , PS 5% ( 1.6 ). — prestapyt, . , , .





, , API, PS. , , .





, , ! , .





Git





- , .





, , .





:





  1. reference ;





  2. — ;





  3. , , stock_availables. ;





  4. associations .





  5. , , > 0 — . – , .





  6. XML stock_availables, .





.





, - , .





API

https://domain.com/api. , . id – , «products» . , .





API XML, :





<prestashop>
	<api shopName="myshop">
		<addresses xlink:href="https://domain.com/api/addresses" get="true" put="false" post="false" delete="false" head="false"></addresses>
	</api>
</prestashop>
      
      



- . https://domain.com/api/products:





<prestashop>
  <products>
    <product id="22" xlink:href="https://domain.com/api/products/22"/>
    <product id="24" xlink:href="https://domain.com/api/products/24"/>
    <product id="265" xlink:href="https://domain.com/api/products/265"/>
    <product id="294" xlink:href="https://domain.com/api/products/294"/>
  <products />
<prestashop />
      
      



.





requests. , Requests — , .





API PS Basic ( ). . requests:





request_url = «https://domain.com/api»
get_combination_xml = requests.get(request_url, auth=(self.api_secret_key, ''))
      
      



  200, , XML. .





XML

– xml.etree. , , ( ), , Python.





:





#     2 
from xml.etree import ElementTree as ET
from xml.etree.ElementTree import ElementTree
#  xml.etree


def xml_data_extractor(data, tag):
# data – XML 
# tag = products–     
try:
	xml_content = ET.fromstring(data.content) #   ElementTree.     .     .
	general_tag = xml_content[0] #    –   
	tag = general_tag.find(tag) #   
	tag_inner_link = tag.get('{http://www.w3.org/1999/xlink}href') #    
	#      href         

  #      
	product_meta = {'product_link': tag_inner_link}
	
  return product_meta

except:
	return None
      
      



 : https://domain.com/api/products. , .





None except Try. , , , , .





PS

PS . , – SQL . XML , — , .





:





https://domain.com/api/combinations/?filter[reference]=reference



, reference — .





- -, : KRHE1Z26X14M200034.





  , . ! Git:





«»

( , ). base64 , , , :





def __init__(self, api_secret_key, request_url=None, **kwargs):
	try:
		self.api_secret_key = str(api_secret_key) #!API key is necessary!
		self.api_secret_key_64 = base64.b64encode((self.api_secret_key + ':').encode())
    
except:
	raise TypeError('The secret_key must be a string!')

  
# Main path to working directory
self.base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
self.request_url = request_url
self.kwargs = kwargs.items()

#product meta to return
self.name = None
self.total_quantity = None
self.w_from = None
self.w_to = None
self.date = str(datetime.datetime.now().strftime("%d-%m-%Y, %H:%M"))
      
      



: _xml_data_extractor(), _wd() _logging(), . -.





— . 11. . , , .





middle-

c Python. , - . WSGI- , !





, , .





, . , Django, — middle-, .





, , - .





Invalid request

! https://palachintosh.com/xxx/xxx/



? ( ) , , . .





/?code=1122334455&token=IUFJ44KPQE342M3M109DNWI



( ):





Example of a successful request

success – , , , , - . .





, , , , . Django Django REST. Java Retrofit, .





– – . – - :





token = None

with open(‘token.txt’) as file_t:
	token = file_t[0]

if token == str(request.GET.get(‘token’)):
	// 

return JsonResponse({‘Error’: ‘Invalid token’})
      
      



, , .





Chrome

, , ..





, . . XMLHttpRequest.





CORS. , Access-Control-Allow-Origin. , OPTIONS.





views.py def options(self, request). GET .





100 , .





- , . . :





Warranty card issuance process

, . «Kod roweru» , .





– PrestaRequest . , .





«sku» , ajax . , ajax . .





var interval;

function main_interval({
    clearInterval(interval);
    
  interval = setInterval(function ({
        href = window.location.href
        if (href.indexOf('https://24.kross.pl/warranty/new') >= 0 ||
            href.indexOf('id_product=') >= 0) {

            if (href.indexOf('id_product=') >= 0) {
                prestaCheck();
                clearInterval(interval);
            }

            if (href.indexOf('https://24.kross.pl/warranty/new') >= 0) {
                location.reload();
                get_buttons();
            }
        }

        if (href.indexOf('https://24.kross.pl/bike-overview/new') >= 0) {
            clearInterval(interval);
            check_all();
        }
    }, 1000);
}
      
      



:





// onclick or enter events
 function getFormData() {
    var getForm = document.forms[0];

    if (getForm != null) {
        if (getForm.hasChildNodes("sku") && getForm.sku != null){
            var code = String(getForm.sku.value);
        }

        if (getForm.hasChildNodes("bike_model") && getForm.bike_model != null) {
            edit_msg = document.querySelector(".message-container > span > h1");
            edit_msg.innerText = "Rower " + String(getForm.bike_model.value) + " zostanie usunięty ze stanów!";
        }

        if (code != null && getForm.serial_number != null) {
            sendRequest(code);
        }
    }
}
      
      



bike_model , , . :





var getBodyBlock = document.querySelector('body');
var alert_div = document.createElement('div');

alert_div.innerHTML = '<div class="alert-message"><div class="message-container">\
<span><h1></h1></span>\
<div class="inner-buttons">\
<button id="btnYes" class="ant-btn ant-btn-danger">Potwierdzam!</button>\
<button id="btnReserve" class="ant-btn ant-btn-danger">Zdjąć rezerwację</button>\
<button id="btnNo" class="ant-btn ant-btn-success">Nie teraz</button>\
</div></div></div>';

loader = document.createElement('div');
getBodyBlock.appendChild(alert_div);
      
      



: https://github.com/palachintosh/shop_extension





– Android-

, , . . , , , 50 ., .





. , . , .





( )

3 . , :





  • , .





  • , , , - , .





, . - . , - . Java .





Retrofit 2. , Python. , , , , , .





Main Activity 3 – onCreate, scanCode, enterCode , :





protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Spinner fromSpinner = (Spinner) findViewById(R.id.fromSpinner);
    Spinner toSpinner = (Spinner) findViewById(R.id.toSpinner);

    ArrayAdapter<String> adapter = new ArrayAdapter<String> (
            this, android.R.layout.simple_spinner_item, warehouses);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    fromSpinner.setAdapter(adapter);
    toSpinner.setAdapter(adapter);
}

public void scanCode(View view) {
    Intent intent = new Intent(MainActivity.this, Scan.class);
    Spinner get_w_from = (Spinner) findViewById(R.id.fromSpinner);
    Spinner get_w_to = (Spinner) findViewById(R.id.toSpinner);
    EditText editText = (EditText) findViewById(R.id.prodctQuantity);
    String quantity_tt = editText.getText().toString();

    RequestData requestData = new RequestData(
            get_w_from.getSelectedItem().toString(),
            get_w_to.getSelectedItem().toString(),
            quantity_tt);
    intent.putExtra(RequestData.class.getSimpleName(), requestData);
    startActivity(intent);
}
      
      



“Enter Code” . , . – .





Manual code submission

Scan Code Activity co , Barcode Scanner Google.





Code scan window

Send Code – . , . Retrofit . , , – Java Android , .





github: https://github.com/palachintosh/product_control.git





:





  • – ;





  • – , , ;





  • - , .





:





  • – - , ;





  • – ;





  • – .





  , 2- -.





, , 5:





  1. .





  2. ( , PrestaShop).





  3. "Enter code" .





  4. "Scan code".





  5. – "Send Code".





, , , .





, , , . - - .





: , , , .





, , , .





People who have looked at the repositories or generally read this will be grateful for constructive comments and criticism.





 








All Articles