Rewritten from python 2.7 to python 3.11

This commit is contained in:
Igor Raznatovic 2024-01-27 22:32:07 +01:00
commit d70da1d39d
9 changed files with 387 additions and 0 deletions

3
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.11 (mssql2mysql)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (mssql2mysql)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/mssql2mysql.iml" filepath="$PROJECT_DIR$/.idea/mssql2mysql.iml" />
</modules>
</component>
</project>

10
.idea/mssql2mysql.iml generated Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

269
abacus2woo.py Normal file
View File

@ -0,0 +1,269 @@
import ast
import sqlite3
import sys
import time
import pyodbc
from woocommerce import API
# import all_from_woo
conn = sqlite3.connect('imd.db') # intermediary db
c = conn.cursor()
# Create table in SLQLite - we use this for syncing
c.execute('''CREATE TABLE IF NOT EXISTS products (id INTEGER NOT NULL PRIMARY KEY ON CONFLICT IGNORE, aid INTEGER,
sifra TEXT, naziv TEXT, price REAL, qty INTEGER, snc INTEGER, grupa INTEGER)''')
# all_from_woo.initSQLite()
# Connect to WooCommerce API
wcapi = API(
url="https://www.rasterdoo.com/",
consumer_key="ck_b3169b1723f6f39a965ed04ecfa77860fb89bbf5",
consumer_secret="cs_a83f0217ed8d6191ab7de9df06a0c2b652f6bd57",
wp_api=True,
timeout=360,
version="wc/v2"
)
print("Resting for for a bit...")
# time.sleep(50)
print("Connecting to MS SQL server")
'''
cnxn = pyodbc.connect('Driver={SQL Server};'
'Server=SERVER-BS;'
'Database=abacus_raster;'
'Trusted_Connection=yes;')
'''
cnxn = pyodbc.connect('DRIVER={SQL Server};'
'SERVER=raster.mywire.org,1433;'
'DATABASE=abacus_raster;'
'UID=sa;'
'PWD=!Pos456!;'
'TDS_Version=7.3;')
cursor = cnxn.cursor()
# Prvi artikal pocetnog stanja 2019 se vodi pod brojem "306570", za 2020 pod brojem "396498".
# Ako racunamo lager za artikle od njega dobicemo pravo stanje za 2019. Ukoliko ovo ne uradimo,
# lager se racuna od pocetka rada sa Abacusom - i vodi do gresaka.
# prvo nadjemo id_document pocetnog stanja (prvog dokumenta u godini)
# /****** Script for SelectTopNRows command from SSMS ******/
# SELECT id_dokument, id_vrsta, broj_dok, datum
# FROM abacus_raster.dbo.artikal_dokument
# WHERE (datum > CONVERT(DATETIME, '2020-12-31 00:00:00', 102))
#
# A onda nadjemo artikal u lageru - Stari kod:
# SELECT id_artikal, multiply * kol AS qty
# FROM abacus_raster.dbo.artikal_dnevnik
# WHERE (multiply <> 0) AND id_dnevnik >=396498.
cursor.execute('''SELECT a.id_artikal,
SUM (a.qty) AS stanje
INTO tmplager
FROM (SELECT artikal_dnevnik.id_artikal,
artikal_dnevnik.multiply*artikal_dnevnik.kol AS 'qty'
FROM abacus_raster.dbo.artikal_dnevnik artikal_dnevnik, abacus_raster.dbo.artikal_dokument artikal_dokument
WHERE artikal_dnevnik.id_dokument = artikal_dokument.id_dokument AND ((artikal_dokument.datum_fak>={d '2024-01-01'})) AND (artikal_dokument.id_vrsta <> 18) ) \
AS a INNER JOIN
abacus_raster.dbo.artikal ON a.id_artikal = abacus_raster.dbo.artikal.id_artikal
GROUP BY a.id_artikal ''')
cursor.execute('''SELECT abacus_raster.dbo.artikal_cijenik.id_artikal, abacus_raster.dbo.artikal_cijenik.cijena,
abacus_raster.dbo.artikal.naziv, abacus_raster.dbo.artikal.sifra,
tmplager.stanje, abacus_raster.dbo.artikal.id_grupa, tmplager.id_artikal AS tid
FROM abacus_raster.dbo.artikal_cijenik INNER JOIN
abacus_raster.dbo.artikal INNER JOIN
tmplager ON abacus_raster.dbo.artikal.id_artikal = tmplager.id_artikal ON
abacus_raster.dbo.artikal_cijenik.id_artikal = abacus_raster.dbo.artikal.id_artikal
WHERE (abacus_raster.dbo.artikal_cijenik.id_mjesto = 2) AND abacus_raster.dbo.artikal.id_grupa <> 11''')
# Save products from Abacus in SQLite table
row = cursor.fetchone()
print("Abacus row in works:"), row #
snc = 0
for row in cursor:
while row is not None:
# print("Abacus row entered for loop and it is not None")
# input("Press Enter to continue...") #
aid = row[0]
aprice = float(row[1])
aname = row[2]
asifra = row[3]
aqty = int(row[4])
agroup = row[5]
print("MS Sql group value:", agroup)
# This dictionary matches abacus product category id to equivalent id in woocommerce
groupdict = {
1: 21472, 2: 21473, 4: 21474, 5: 21475, 10: 21476, 11: 21477, 13: 21477, 15: 21477, 19: 21478, 24: 21479,
30: 21480, 32: 21481, 33: 21482, 37: 21483, 38: 21484, 44: 21485, 45: 21486, 47: 21477, 48: 21477
}
print("Coverted to Woocommerce group it becomes wgroup:", groupdict[agroup])
if agroup in groupdict:
wgroup = groupdict[agroup]
print("Group in abacusu is from dictionary:", agroup, " - while woocommerce now holds:", wgroup) #
else:
wgroup = 3557
print("Group ", agroup, "does not exist in dictionary - we put it in woocommerce group -other-:", wgroup) #
# Test id Woo product exists in SQLite table
q = (asifra,)
c.execute('SELECT * FROM products WHERE sifra=?', q)
print("Abacus data to be saved in SQLite:", aid, aprice, aname, asifra, aqty, wgroup)
# input("Press Enter to continue...") #
# We test SqlLite rows so that we update the table only with products that changed
trow = c.fetchone()
if trow is not None:
tnaziv = trow[3]
tprice = trow[4]
tqty = trow[5]
tgroup = trow[7]
# print("There is an SQLite trow we need to check for an update: "), tnaziv, tprice, tqty, tgroup
if aprice != tprice:
snc = 1
print("bad price")
if aqty != tqty:
snc = 1
print("bad qty")
if aname != tnaziv:
snc = 1
print("bad naziv")
if wgroup != tgroup:
snc = 1
print(wgroup, "bad tgroup: ", tgroup)
if snc == 1:
# print("=======")
c.execute('''UPDATE products SET aid = ?, price = ?, qty =?, naziv = ?,
snc = ?, grupa = ? WHERE sifra = ?''',
(aid, aprice, aqty, aname, snc, wgroup, asifra))
conn.commit()
c.execute('SELECT * FROM products WHERE sifra=?', q)
trow = c.fetchone()
print(trow)
print("=======")
# input("Press Enter to continue...")
else:
print("If sqlite trow does not exist (is ", trow, "), then first create one in Woo", aid, asifra, aname,
aprice, aqty, wgroup)
# input("Press Enter to continue...") #
aprice = str(aprice)
data = {
"sku": asifra,
"name": aname,
"regular_price": aprice,
"description": "",
"managing_stock": "true",
"in_stock": "true",
"status": "publish",
"stock_quantity": aqty,
"categories": [
{
"id": wgroup
}
],
}
w = wcapi.post("products", data).json()
# w = wcapi.get("products/categories").json()
class ListStream:
def __init__(self):
self.data = []
def write(self, s):
self.data.append(s)
sys.stdout = x = ListStream()
print(w)
sys.stdout = sys.__stdout__
wresponse = (x.data[0])
print("Full woo response: ", wresponse)
# print("wresponse:", wresponse[38:53])
if wresponse[38:53] == "duplicirani SKU":
# if wresponse[26:40] == "duplicated SKU":
d = ast.literal_eval(wresponse)
errd = d.get('data')
print(errd)
rogueone = errd.get('resource_id')
print("We have a duplicated product in Woo: ", rogueone)
c.execute('INSERT INTO products VALUES (?,?,?,?,?,?,?,?)',
(rogueone, aid, asifra, aname, aprice, aqty, 1, wgroup)) # if no product it will create
print("Inserting rogueone in SQLlite data:", rogueone, aid, asifra, aname, aprice, aqty, 1, wgroup)
conn.commit()
# rgpath = "\"products/" + str(rogueone) + "\""
# print rgpath
# rg = wcapi.get(rogueone).json()
# print("The rogueone:", rg)
else:
print("Since trow was NONE, we had to create it on woo, get the id (woo), then save it (SQLite):",
type(w), w)
wid = w.get('id')
wsku = w.get('sku')
wname = w.get('name')
wprice = w.get('price')
wqty = w.get('qty')
if wname is None:
print("Why problems? ...:", wid, aid, wsku, wname, wprice, wqty)
else:
c.execute('INSERT INTO products VALUES (?,?,?,?,?,?,?,"")',
(wid, aid, wsku, wname, wprice, wqty, 1)) # if no product it will create
conn.commit()
row = cursor.fetchone()
# print("Resting for for a bit...")
# time.sleep(5)
conn.close()
# Update Woo with our SQLite table
conn = sqlite3.connect('imd.db') # intermediary db
c = conn.cursor()
c.execute('''SELECT * FROM products WHERE snc = 1 ORDER BY naziv''')
trow = c.fetchone()
print("Selected for update:", trow)
# cleantrow is not None:
grupa = 0
while trow is not None:
id = trow[0]
tnaziv = trow[3]
tprice = str(trow[4])
tqty = trow[5]
tgroup = trow[7]
# print type(id), type(tnaziv), type(tprice), type(tqty), "Grupa:", type(tgroup), tgroup
# input("Press enter ...")
data = {
"id": id,
"manage_stock": "true",
"stock_quantity": tqty,
"name": tnaziv,
"status": "publish",
"regular_price": tprice,
"categories": [
{
"id": tgroup
}
],
}
# print data
uplink = "products/" + str(id)
# print uplink
up = wcapi.put((uplink), data).json()
print(up)
# input("Press enter ...")
if trow is None:
break
else:
trow = c.fetchone()
print("___________________________________________")
print("Selected next for update:", trow)
c.execute('UPDATE products SET snc = 0')
conn.commit()
# Drop the temporary table
print("Preparing to drop the tmptable")
cursor.execute('''drop table tmplager''')
print("Dropped the tmptable")
cursor.close()
del cursor
conn.close() # close sqlite connection
print("All done!")

78
all_from_woo.py Normal file
View File

@ -0,0 +1,78 @@
def initSQLite():
# The following will download all existing woocommerce products and save them in SQLite.
# From that point the synchronization can start in local.
from woocommerce import API
import sqlite3
import pyodbc
conn = sqlite3.connect('imd.db') # intermediary db
c = conn.cursor()
# Create table in SLQLite - we use this for syncing
c.execute('DROP TABLE products')
c.execute('''CREATE TABLE IF NOT EXISTS products (id INTEGER NOT NULL PRIMARY KEY ON CONFLICT IGNORE, aid INTEGER,
sifra TEXT, naziv TEXT, price REAL, qty INTEGER, snc INTEGER, grupa INTEGER)''')
# Connect to WooCommerce API
wcapi = API(
url="https://www.rasterdoo.com/",
consumer_key="ck_b3169b1723f6f39a965ed04ecfa77860fb89bbf5",
consumer_secret="cs_a83f0217ed8d6191ab7de9df06a0c2b652f6bd57",
wp_api=True,
version="wc/v2"
)
r = wcapi.get("products") # get woo web page where products are
h = int(r.headers['X-WP-TotalPages']) # in the header we see number of tot pages
print("Total pages:", h)
for page_no in range(1, h+1): # lets go through pages
goto_page = 'products?page=' + str(page_no)
print(page_no, "(", h, ")")
r = wcapi.get(goto_page)
page_txt = r.json() # contents of one page ar stored in variable
# We fill our SQLite table with Woo Products
for product in page_txt: # first we go through products in this page
wsku = product.get('sku')
wid = product.get('id')
wname = product.get('name')
wprice = product.get('regular_price')
wqty = product.get('stock_quantity')
if wqty is None:
wqty = 0
# FIX THIS! - It does not update - just inserts if new ...
c.execute('INSERT INTO products VALUES (?,?,?,?,?,?,?,?)',
(wid, "", wsku, wname, wprice, wqty, 0)) # if no product it will create
c.execute('UPDATE products SET aid = ?, sifra = ?, naziv = ?, price = ?, qty = ?, snc = ? WHERE id = ?',
("", wsku, wname, wprice, wqty, 0, wid, ""))
print("Insert woocommerce data to SQLlite:", wid, "", wsku, wname, wprice, wqty, 0)
conn.commit()
print("")
print("Fixing some problems with decimals...")
c.execute('''UPDATE products SET price = replace( price, ',', '.' ) WHERE price LIKE ?''', ('%,%',))
conn.commit()
# Sometimes woo has a product, but abacus does not, meaning we don't have them anymore. SO, qty needs to be 0.
print("Checking if products on woo exist on abacus")
# list of woo products
c.execute('''SELECT sifra, naziv, qty FROM products''')
trow = c.fetchone()
# find them on abacus
cnxn = pyodbc.connect('Driver={SQL Server};'
'Server=SERVER-BS;'
'Database=abacus_raster;'
'Trusted_Connection=yes;')
cursor = cnxn.cursor()
while trow is not None:
sifra = trow[0]
naziv = trow[1]
cursor.execute('''SELECT id_artikal, sifra, naziv FROM abacus_raster.dbo.artikal WHERE sifra = ?''', (sifra, ))
row = cursor.fetchone()
if row is None:
print(sifra, naziv, " - does not exist on abacus, at least we should set qty to 0")
c.execute('''UPDATE products SET qty = 0 WHERE sifra = ?''', (sifra,))
conn.commit()
trow = c.fetchone()
conn.close()

BIN
imd.db Normal file

Binary file not shown.