initBasti / Amazon2PlentySync (public) (License: GPLv3) (since 2019-01-27) (hash sha1)
Transfer your data from you Amazon Flatfile spreadsheet over to the Plentymarkets system. How to is included in the readme
Merge request 2 (b5d1675bcb56c38a97c928d7800b6a29c2dea116 -> 6349c4a7177345c25aa6d8ecd03740a75fa2520f)
By: anonymous
Against ref: refs/heads/elastic-version
Date: 2019-06-13 12:58
This merge request can be merged without conflicts.
List of commits:
Subject Hash Author Date (UTC)
Removed the image upload from item upload and added a exportfile together with functions to get the variation id for the image upload, the image upload is now a single process 6349c4a7177345c25aa6d8ecd03740a75fa2520f Sebastian Fricke 2019-06-13 12:58:36
Commit 6349c4a7177345c25aa6d8ecd03740a75fa2520f - Removed the image upload from item upload and added a exportfile together with functions to get the variation id for the image upload, the image upload is now a single process
Author: Sebastian Fricke
Author date (UTC): 2019-06-13 12:58
Committer name: Sebastian Fricke
Committer date (UTC): 2019-06-13 12:58
Parent(s): b5d1675bcb56c38a97c928d7800b6a29c2dea116
Signing key:
Tree: 2041fc419031c7096a61df591a72154b4242eb30
File Lines added Lines deleted
packages/amazon_data_upload.py 0 6
packages/gui/__pycache__/category_chooser.cpython-37.pyc 0 0
packages/gui/category_chooser.py 58 34
packages/image_upload.py 6 2
packages/item_upload.py 24 22
product_import.py 18 1
File packages/amazon_data_upload.py changed (mode: 100644) (index ec64839..9712e77)
... ... def featureUpload(flatfile, features, folder):
89 89 for row in reader: for row in reader:
90 90 if(row['parent_child'] == 'child'): if(row['parent_child'] == 'child'):
91 91 for feature in features: for feature in features:
92 if(row['item_sku'] == '101012000221'):
93 print("1. Feature: {0}, value: {1}".format(feature, row[feature]))
94 92 if(feature in [*row]): if(feature in [*row]):
95 if(row['item_sku'] == '101012000221'):
96 print("2. Feature: {0}, value: {1}".format(feature, row[feature]))
97 93 if(row[feature]): if(row[feature]):
98 if(row['item_sku'] == '101012000221'):
99 print("3. Feature: {0}, value: {1}".format(feature, row[feature]))
100 94 values = [ values = [
101 95 row['item_sku'], features[feature], row['item_sku'], features[feature],
102 96 '1', '1', '1', '1',
File packages/gui/__pycache__/category_chooser.cpython-37.pyc changed (mode: 100644) (index 58422ac..623fdc6)
File packages/gui/category_chooser.py changed (mode: 100644) (index 5827d16..1631dae)
... ... class DropdownChooser(tkinter.Frame):
171 171 self.grid() self.grid()
172 172
173 173 self.optionvar = tkinter.StringVar(self) self.optionvar = tkinter.StringVar(self)
174 self.activityvar = tkinter.StringVar(self)
174 175 self.resultvar = tkinter.StringVar(self) self.resultvar = tkinter.StringVar(self)
175 176
176 177 self.options = {'Men.Aladinhose':'34', self.options = {'Men.Aladinhose':'34',
177 178 'Men.Sommerhose':'36', 'Men.Sommerhose':'36',
178 179 'Men.Stoffhose':'35', 'Men.Stoffhose':'35',
180 'Men.Shorts':'37',
179 181 'Men.Fischerhose':'85', 'Men.Fischerhose':'85',
180 182 'Men.Hemden': '38', 'Men.Hemden': '38',
181 'Men.Jacken' :'41',
182 'Men.Hoodie' : '40',
183 183 'Men.Tshirt' :'39', 'Men.Tshirt' :'39',
184 'Men.Hoodie' : '40',
185 'Men.Jacken' :'41',
184 186 'Women.Kleid' :'62', 'Women.Kleid' :'62',
185 'Women.Skirt' :'87',
186 'Women.Sarong-K' :'64',
187 187 'Women.Tunika' :'63', 'Women.Tunika' :'63',
188 'Women.Top' :'65',
189 'Women.Jacken' :'84',
190 'Women.Sarong-O' :'69',
191 'Women.Hoodie' :'68',
192 'Women.Tshirt' :'66',
188 'Women.Sarong-K' :'64',
189 'Women.Skirt' :'87',
193 190 'Women.Aladinhose' :'53', 'Women.Aladinhose' :'53',
194 'Women.Fischerhose' :'96',
195 'Women.Legging' :'73',
196 'Women.Hosenrock' :'72',
197 'Women.Sommerhose' :'71',
198 191 'Women.Stoffhose' :'70', 'Women.Stoffhose' :'70',
199 'Acce.Men.Patch' :'80',
200 'Acce.Men.Halstuch' :'91',
201 'Acce.Men.Sarong' :'89',
202 'Acce.Men.Suncatcher' :'83',
203 'Acce.Men.Kissen' :'82',
204 'Acce.Men.Airbrush' :'81',
205 'Acce.Women.Patch' :'76',
206 'Acce.Women.Halstuch' :'90',
207 'Acce.Women.Sarong' :'88',
208 'Acce.Women.Suncatcher' :'79',
209 'Acce.Women.Kissen' :'78',
210 'Acce.Women.Airbrush' :'77',
211 'Bags.Men.Schultertasche' :'58',
212 'Bags.Men.Rucksack' :'59',
213 'Bags.Women.Schultertasche' :'60',
214 'Bags.Women.Rucksack':'61'}
192 'Women.Sommerhose' :'71',
193 'Women.Hosenrock' :'72',
194 'Women.Legging' :'73',
195 'Women.Fischerhose' :'96',
196 'Women.Top' :'65',
197 'Women.Tshirt/Hemden' :'66',
198 'Women.Hoodie' :'68',
199 'Women.Sarong-O' :'69',
200 'Women.Jacken' :'84',
201 'Accessoires.Taschen':'58',
202 'Accessoires.Patch':'76',
203 'Accessoires.Backdrop':'77',
204 'Accessoires.Kissen':'78',
205 'Accessoires.Suncatcher':'79',
206 'Accessoires.Halstuch':'90'
207 }
208
209 self.activities = {
210 'Women.Yoga': '95',
211 'Women.Retreat': '96',
212 'Women.Summerwear': '97',
213 'Women.Festival': '98',
214 'Men.Yoga': '99',
215 'Men.Retreat': '100',
216 'Men.Summerwear': '101',
217 'Men.Festival': '102'
218 }
215 219
216 220 self.optionvar.set('category') self.optionvar.set('category')
221 self.activityvar.set('activities')
222
223 self.menu_header_major = tkinter.Label(self, text='Major category')
224 self.menu_header_major.grid(row=0, column=0, sticky='NESW')
225
226 self.menu_header_activity = tkinter.Label(self, text='Activity category')
227 self.menu_header_activity.grid(row=0, column=1, sticky='NESW')
217 228
218 229 self.dropdown_menu = tkinter.OptionMenu(self, self.optionvar, *[ *self.options ]) self.dropdown_menu = tkinter.OptionMenu(self, self.optionvar, *[ *self.options ])
219 self.dropdown_menu.grid(row=0, column=0, sticky="EW")
230 self.dropdown_menu.grid(row=1, column=0, sticky="EW", padx=50)
231
232 self.activity_menu = tkinter.OptionMenu(self, self.activityvar, *[ *self.activities ])
233 self.activity_menu.grid(row=1, column=1, sticky="EW", padx=50)
220 234
221 235 self.optionvar.trace('w', self.change_dropdown) self.optionvar.trace('w', self.change_dropdown)
236 self.activityvar.trace('w', self.change_dropdown)
222 237 self.resultvar.trace('w', self.add_desc) self.resultvar.trace('w', self.add_desc)
223 238
224 239 # Create a textbox to show the result of the choosing # Create a textbox to show the result of the choosing
225 240 self.resultbox = tkinter.Entry(self, textvariable=self.resultvar, width=50, bg="white") self.resultbox = tkinter.Entry(self, textvariable=self.resultvar, width=50, bg="white")
226 self.resultbox.grid(row=1, column=0, columnspan=2, sticky="EW")
241 self.resultbox.grid(row=2, column=0, columnspan=2, sticky="EW", padx=50)
227 242
228 243 # Create a label with an info about the standard category which hides if the entry is empty # Create a label with an info about the standard category which hides if the entry is empty
229 244 self.category_info = tkinter.Label(self, text="The first category in the list will be used as standard category!") self.category_info = tkinter.Label(self, text="The first category in the list will be used as standard category!")
230 245
231 246 def change_dropdown(self, *args): def change_dropdown(self, *args):
232 247 if( not( self.resultbox.get() ) ): if( not( self.resultbox.get() ) ):
248 if(not( self.activityvar.get() == 'activities' )):
249 print(self.activityvar.get())
250 tmb.showerror("No Major category!",
251 "Please enter first a major category, so that the first gets set as standard category. After that add a activity category!")
252 self.activityvar.set('activities')
253
233 254 self. resultbox.insert(tkinter.INSERT, self.options[ self.optionvar.get() ] ) self. resultbox.insert(tkinter.INSERT, self.options[ self.optionvar.get() ] )
234 255 else: else:
235 self.resultbox.insert(tkinter.INSERT, ', ' + self.options[ self.optionvar.get() ] )
256 if(self.optionvar.get() and not( re.search( self.options[ self.optionvar.get() ] ,self.resultbox.get()) ) ):
257 self.resultbox.insert(tkinter.INSERT, ', ' + self.options[ self.optionvar.get() ] )
258 if(self.activityvar.get() and not( self.activityvar.get() == 'activities' )):
259 if(not( re.search( self.activities[ self.activityvar.get() ] ,self.resultbox.get()) ) ):
260 self.resultbox.insert(tkinter.INSERT, ', ' + self.activities[ self.activityvar.get() ] )
236 261
237 262 def add_desc(self, *args): def add_desc(self, *args):
238 263 if(len(self.resultvar.get())>1): if(len(self.resultvar.get())>1):
239 self.category_info.grid(row=2, columnspan=2, sticky="EW")
264 self.category_info.grid(row=3, columnspan=2, sticky="EW")
240 265 else: else:
241 266 self.category_info.grid_remove() self.category_info.grid_remove()
242 267
 
... ... class CategoryChooser(tkinter.Tk):
348 373 self.toplevelWarning = tkinter.Toplevel(self) self.toplevelWarning = tkinter.Toplevel(self)
349 374 self.toplevelWarning.title("Warning missing Colors") self.toplevelWarning.title("Warning missing Colors")
350 375 self.toplevelWarning.lift(self) self.toplevelWarning.lift(self)
351 #self.toplevel_positiondown = int( self.winfo_screenheight()/1.3 - self.window_h)
352 376 self.toplevelWarning.geometry("+{}+{}".format(self.positionright, self.positiondown)) self.toplevelWarning.geometry("+{}+{}".format(self.positionright, self.positiondown))
353 377 self.warningbox = WarningBox(self.toplevelWarning, colorlist) self.warningbox = WarningBox(self.toplevelWarning, colorlist)
354 378 except Exception as err: except Exception as err:
File packages/image_upload.py changed (mode: 100644) (index 1f99ff8..13971f0)
... ... import csv
2 2 from sortedcontainers import SortedDict from sortedcontainers import SortedDict
3 3 import re import re
4 4 import sys import sys
5 from packages import item_upload, barcode
5 6
6 7 def searchSpecialImage(image): def searchSpecialImage(image):
7 8 if(re.search(r'( SWATCH|SIZE )', image)): if(re.search(r'( SWATCH|SIZE )', image)):
 
... ... def getColorAttributeID(attributefile, product):
27 28 return attributeid return attributeid
28 29
29 30
30 def imageUpload(flatfile, attributefile):
31 def imageUpload(flatfile, attributefile, exportfile, uploadfolder):
31 32
32 33 try: try:
33 34 Data = SortedDict() Data = SortedDict()
 
... ... def imageUpload(flatfile, attributefile):
36 37 'availability', 'listing', 'connect-color'] 'availability', 'listing', 'connect-color']
37 38 linkstring = '' linkstring = ''
38 39 attributeID = '' attributeID = ''
40 variation_id = 0
39 41
40 42 with open(flatfile['path'], mode='r', encoding=flatfile['encoding']) as item: with open(flatfile['path'], mode='r', encoding=flatfile['encoding']) as item:
41 43 reader = csv.DictReader(item, delimiter=';') reader = csv.DictReader(item, delimiter=';')
 
... ... def imageUpload(flatfile, attributefile):
53 55 ] ]
54 56
55 57 num = 1 num = 1
58 variation_id = item_upload.get_variationid(exportfile=exportfile, sku=row['item_sku'])
56 59 try: try:
57 60 if(imglinks[0]): if(imglinks[0]):
58 61 for img in imglinks: for img in imglinks:
 
... ... def imageUpload(flatfile, attributefile):
82 85 print("Error @ get Color Attribute ID {0}\n".format(err)) print("Error @ get Color Attribute ID {0}\n".format(err))
83 86
84 87
85 values=[linkstring, 1, -1,
88 values=[linkstring, variation_id, -1,
86 89 -1, -1, attributeID] -1, -1, attributeID]
87 90
88 91 Data[row['item_sku']] = dict(zip(column_names, values)) Data[row['item_sku']] = dict(zip(column_names, values))
 
... ... def imageUpload(flatfile, attributefile):
90 93 except Exception as err: except Exception as err:
91 94 print("Error @ imageupload line: {0} : {1}".format(sys.exc_info()[2].tb_lineno, err)) print("Error @ imageupload line: {0} : {1}".format(sys.exc_info()[2].tb_lineno, err))
92 95
96 barcode.writeCSV(dataobject=Data, name='Image_', columns=column_names, folder=uploadfolder)
93 97 return Data return Data
File packages/item_upload.py changed (mode: 100644) (index 2ae4bad..fc462e4)
... ... def check_encoding(file_dict):
49 49
50 50 return file_dict return file_dict
51 51
52 def get_variationid(exportfile, sku):
53
54 variationid = 0
55 with open(exportfile['path'], mode = 'r', encoding = exportfile['encoding']) as item:
56 reader = csv.DictReader(item, delimiter = ';')
57
58 for row in reader:
59 if(row['VariationNo'] == sku):
60 variationid = row['VariationId']
61 if(not(variationid)):
62 print("No Variation ID found for {0}\n".format(sku))
63
64 return variationid
65
52 66 def itemUpload(flatfile, intern, stocklist, attributefile, folder, input_data): def itemUpload(flatfile, intern, stocklist, attributefile, folder, input_data):
53 67 # The column headers for the output file as expected from the # The column headers for the output file as expected from the
54 68 # plentymarkets dataformat # plentymarkets dataformat
 
... ... def itemUpload(flatfile, intern, stocklist, attributefile, folder, input_data):
71 85 'marketid', 'accountid', 'marketid', 'accountid',
72 86 'amazon_sku', 'amazon_parentsku', 'amazon_sku', 'amazon_parentsku',
73 87 'amazon-producttype', 'fba-enabled', 'fba-shipping', 'amazon-producttype', 'fba-enabled', 'fba-shipping',
74 'price-price', 'ebay-price', 'amazon-price', 'webshop-price', 'etsy-price',
88 'price-price', 'ebay-price', 'amazon-price',
89 'webshop-price', 'etsy-price', 'cdiscount-price',
75 90 'ASIN-countrycode', 'ASIN-type', 'ASIN-value', 'ASIN-countrycode', 'ASIN-type', 'ASIN-value',
76 'Multi-URL', 'connect-variation', 'mandant', 'availability', 'listing',
77 'connect-color']
91 'Item-Flag-1'
92 ]
78 93
79 94
80 95 # Unpack File and scrap data # Unpack File and scrap data
 
... ... def itemUpload(flatfile, intern, stocklist, attributefile, folder, input_data):
103 118 try: try:
104 119 # SET KEYWORDS # SET KEYWORDS
105 120 keywords = '' keywords = ''
121 # Item Flags for new products to download the correct export
122 item_flag = ''
106 123 if(row['generic_keywords']): if(row['generic_keywords']):
107 124 keywords = row[ 'generic_keywords' ] keywords = row[ 'generic_keywords' ]
108 125
 
... ... def itemUpload(flatfile, intern, stocklist, attributefile, folder, input_data):
114 131 if(row['parent_child'] == 'child'): if(row['parent_child'] == 'child'):
115 132 attributes = get_attributes(dataset=row, sets=color_size_sets) attributes = get_attributes(dataset=row, sets=color_size_sets)
116 133
134 if(row['parent_child'] == 'parent'):
135 item_flag = 21
117 136
118 137 try: try:
119 138 values = [ values = [
 
... ... def itemUpload(flatfile, intern, stocklist, attributefile, folder, input_data):
136 155 '', '', # market & accout id amazonsku '', '', # market & accout id amazonsku
137 156 '', '', # sku & parentsku amazonsku '', '', # sku & parentsku amazonsku
138 157 '', '', '',# producttype & fba amazon '', '', '',# producttype & fba amazon
139 '','','','','',# prices
158 '','','','','','',# prices
140 159 '', '', '', #asin '', '', '', #asin
141 '', '', '', '', #image
142 '', '' # image
160 item_flag
143 161 ] ]
144 162
145 163 except KeyError: except KeyError:
 
... ... def itemUpload(flatfile, intern, stocklist, attributefile, folder, input_data):
215 233 except Exception as err: except Exception as err:
216 234 print("ERROR @ Price Part for {0}.\n{1}.\n".format(row, err)) print("ERROR @ Price Part for {0}.\n{1}.\n".format(row, err))
217 235
218 # Include the images
219 image_data = image_upload.imageUpload(flatfile, attributefile)
220
221 for index, row in enumerate( image_data ):
222 try:
223 if(row in [*Data]):
224 Data[row]['Multi-URL'] = image_data[row]['Multi-URL']
225 Data[row]['connect-variation'] = image_data[row]['connect-variation']
226 Data[row]['mandant'] = image_data[row]['mandant']
227 Data[row]['availability'] = image_data[row]['availability']
228 Data[row]['listing'] = image_data[row]['listing']
229 Data[row]['connect-color'] = image_data[row]['connect-color']
230 except Exception as err:
231 print("ERROR @ Image Part for {0}.\n{1}.\n".format(row, err))
232
233
234 236 # Write Data into new CSV for Upload # Write Data into new CSV for Upload
235 237 # OUTPUT # OUTPUT
236 238 # -------------------------------------------------------------- # --------------------------------------------------------------
File product_import.py changed (mode: 100644) (index 21c60ab..e4fe0f4)
... ... from packages.amazon_data_upload import featureUpload
10 10 from packages.log_files import fileNotFoundLog, keyErrorLog, wrongEncodingLog, unboundLocalLog, emptyFieldWarningLog from packages.log_files import fileNotFoundLog, keyErrorLog, wrongEncodingLog, unboundLocalLog, emptyFieldWarningLog
11 11 from packages.gui.category_chooser import CategoryChooser from packages.gui.category_chooser import CategoryChooser
12 12 from packages.config import config_creation, config_read, config_write from packages.config import config_creation, config_read, config_write
13 from packages.image_upload import imageUpload
13 14
14 15
15 16 def main(): def main():
 
... ... def main():
23 24 sheet = {'path':'', 'encoding':''} sheet = {'path':'', 'encoding':''}
24 25 intern_number = {'path':'', 'encoding':''} intern_number = {'path':'', 'encoding':''}
25 26 stocklist = {'path':'', 'encoding':''} stocklist = {'path':'', 'encoding':''}
27 plenty_export = {'path':'', 'encoding':''}
26 28 attributefile = {'path':'', 'encoding':''} attributefile = {'path':'', 'encoding':''}
27 29 step = int(0) step = int(0)
28 30 fexc = '' fexc = ''
 
... ... def main():
36 38 'import-stocklist', 'import-stocklist',
37 39 'item-upload', 'item-upload',
38 40 'feature_upload', 'feature_upload',
39 'property_upload'
41 'property_upload',
42 'import-exportfile',
43 'image-upload'
40 44 ] ]
41 45
42 46 # define the features for plentymarkets # define the features for plentymarkets
 
... ... def main():
237 241 print(err) print(err)
238 242 print("Missing Data, check if you have\n - a flatfile\n - a intern file table\n - export file from plentymarkets\n - a sheet with the stock numbers!\n") print("Missing Data, check if you have\n - a flatfile\n - a intern file table\n - export file from plentymarkets\n - a sheet with the stock numbers!\n")
239 243
244 # IMPORT Export FIlE
245 step += 1
246 plenty_export['path'] = askopenfilename(initialdir=recent_path,
247 title="Export File from Plentymarkets",
248 filetypes=[ ("csv files", "*.csv") ])
249
250 plenty_export = check_encoding(sheet)
251
252 step += 1
253 imageUpload(flatfile=sheet, attributefile=attributefile, exportfile=plenty_export, uploadfolder=upload_folder)
240 254 del fexc del fexc
255 # A stop in the script flow to interrupt a console window from closing itself
256 print('press ENTER to close the script...')
257 input()
241 258 else: else:
242 259 print("Choose a category and a name.\n") print("Choose a category and a name.\n")
243 260 if __name__ == '__main__': if __name__ == '__main__':
Hints:
How to merge on your machine?
git fetch origin refs/mr/2:mr-2
git checkout main
git merge mr-2

To "see" all the merge requests as branches,
add, in the config file (.git/config), under the remote you want, a line like this:
fetch = +refs/mr/*:refs/remotes/your_remote_name_for_example_origin/mr/*
After you run a git fetch, you will have all the pull requests locally.
For example, you can merge one of them:
git checkout main
git merge mr/2