def __init__(self, parent): super(StoragesFrame, self).__init__(parent) # create categories data self.tree_categories_manager = helper.tree.TreeManager(self.tree_categories) self.tree_categories_manager.AddTextColumn("name") self.tree_categories_manager.AddTextColumn("description") self.tree_categories_manager.DropAccept(DataModelCategory, self.onTreeCategoriesDropCategory) self.tree_categories_manager.DropAccept(DataModelStorage, self.onTreeCategoriesDropStorage) self.tree_categories_manager.OnSelectionChanged = self.onTreeCategoriesSelChanged # storages filters self.storages_filter = Filter(self.filters_panel, self.onButtonRemoveFilterClick) # create storage list self.tree_storages_manager = TreeManagerStorages(self.tree_storages) self.tree_storages_manager.AddIntegerColumn("id") self.tree_storages_manager.AddTextColumn("name") self.tree_storages_manager.AddTextColumn("description") self.tree_storages_manager.AddIntegerColumn("comment") self.tree_storages_manager.OnSelectionChanged = self.onTreeStoragesSelChanged # create storage part list self.tree_storage_parts_manager = helper.tree.TreeManager(self.tree_storage_parts) self.tree_storage_parts_manager.AddIntegerColumn("id") self.tree_storage_parts_manager.AddTextColumn("name") self.tree_storage_parts_manager.AddIntegerColumn("quantity") self.tree_storage_parts_manager.AddTextColumn("description") self.tree_storage_parts_manager.OnSelectionChanged = self.onTreeStoragePartsSelChanged # initial edit state self.show_storage(None) self.edit_state = None self.loaded = False ;
def __init__(self, parent): super(PartsFrame, self).__init__(parent) # create categories list self.tree_categories_manager = helper.tree.TreeManager(self.tree_categories) self.tree_categories_manager.AddTextColumn("name") self.tree_categories_manager.AddTextColumn("description") self.tree_categories_manager.DropAccept(DataModelCategory, self.onTreeCategoriesDropCategory) self.tree_categories_manager.DropAccept(DataModelPart, self.onTreeCategoriesDropPart) self.tree_categories_manager.OnSelectionChanged = self.onTreeCategoriesSelChanged # parts filters self.parts_filter = Filter(self.filters_panel, self.onButtonRemoveFilterClick) # create parts list self.tree_parts_manager = TreeManagerParts(self.tree_parts) self.tree_parts_manager.AddIntegerColumn("id") self.tree_parts_manager.AddTextColumn("name") self.tree_parts_manager.AddTextColumn("description") self.tree_parts_manager.AddIntegerColumn("comment") self.tree_parts_manager.OnSelectionChanged = self.onTreePartsSelChanged self.tree_parts_manager.DropAccept(DataModelPart, self.onTreePartsDropPart) # # create edit part panel self.panel_edit_part = EditPartFrame(self.part_splitter) self.part_splitter.SplitHorizontally(self.part_splitter.Window1, self.panel_edit_part, 400) self.panel_edit_part.Bind( EVT_EDIT_PART_APPLY_EVENT, self.onEditPartApply ) self.panel_edit_part.Bind( EVT_EDIT_PART_CANCEL_EVENT, self.onEditPartCancel ) # initial edit state self.show_part(None) self.edit_state = None self.load()
def __init__(self, parent): super(PartsFrame, self).__init__(parent) # create categories list self.tree_categories_manager = helper.tree.TreeManager(self.tree_categories, context_menu=self.menu_category) self.tree_categories_manager.AddTextColumn("name") self.tree_categories_manager.AddTextColumn("description") self.tree_categories_manager.DropAccept(DataModelCategory, self.onTreeCategoriesDropCategory) self.tree_categories_manager.DropAccept(DataModelPart, self.onTreeCategoriesDropPart) self.tree_categories_manager.OnSelectionChanged = self.onTreeCategoriesSelChanged self.tree_categories_manager.OnItemBeforeContextMenu = self.onTreeCategoriesBeforeContextMenu # parts filters self.parts_filter = Filter(self.filters_panel, self.onButtonRemoveFilterClick) # create parts list self.tree_parts_manager = TreeManagerParts(self.tree_parts, context_menu=self.menu_part) self.tree_parts_manager.AddIntegerColumn("id") self.tree_parts_manager.AddTextColumn("name") self.tree_parts_manager.AddTextColumn("description") self.tree_parts_manager.AddIntegerColumn("comment") self.tree_parts_manager.AddTextColumn("symbol") self.tree_parts_manager.AddTextColumn("footprint") self.tree_parts_manager.OnSelectionChanged = self.onTreePartsSelChanged self.tree_parts_manager.OnColumnHeaderRightClick = self.onTreePartsColumnHeaderRightClick self.tree_parts_manager.DropAccept(DataModelPart, self.onTreePartsDropPart) self.tree_parts_manager.OnItemBeforeContextMenu = self.onTreePartsBeforeContextMenu # # create edit part panel self.panel_edit_part = EditPartFrame(self.part_splitter) self.part_splitter.SplitHorizontally(self.part_splitter.Window1, self.panel_edit_part, 400) self.panel_edit_part.Bind( EVT_EDIT_PART_APPLY_EVENT, self.onEditPartApply ) self.panel_edit_part.Bind( EVT_EDIT_PART_CANCEL_EVENT, self.onEditPartCancel ) self.toolbar_part.ToggleTool(self.toggle_part_path.GetId(), True) # initial edit state self.show_part(None) self.edit_state = None self.show_categories = True self.load()
def __init__(self, parent): super(FootprintsFrame, self).__init__(parent) # create categories data self.tree_categories_manager = helper.tree.TreeManager( self.tree_categories) self.tree_categories_manager.AddTextColumn("name") self.tree_categories_manager.AddTextColumn("description") self.tree_categories_manager.DropAccept( DataModelCategory, self.onTreeCategoriesDropCategory) self.tree_categories_manager.DropAccept( DataModelFootprint, self.onTreeCategoriesDropFootprint) self.tree_categories_manager.OnSelectionChanged = self.onTreeCategoriesSelChanged # footprints filters self.footprints_filter = Filter(self.filters_panel, self.onButtonRemoveFilterClick) # create footprint list self.tree_footprints_manager = TreeManagerFootprints( self.tree_footprints) self.tree_footprints_manager.AddIntegerColumn("id") self.tree_footprints_manager.AddTextColumn("name") self.tree_footprints_manager.AddTextColumn("description") self.tree_footprints_manager.AddIntegerColumn("comment") self.tree_footprints_manager.OnSelectionChanged = self.onTreeFootprintsSelChanged # create edit footprint panel self.panel_edit_footprint = EditFootprintFrame(self.footprint_splitter) self.footprint_splitter.SplitHorizontally( self.footprint_splitter.Window1, self.panel_edit_footprint, 400) self.panel_edit_footprint.Bind(EVT_EDIT_FOOTPRINT_APPLY_EVENT, self.onEditFootprintApply) self.panel_edit_footprint.Bind(EVT_EDIT_FOOTPRINT_CANCEL_EVENT, self.onEditFootprintCancel) # initial edit state self.show_footprint(None) self.edit_state = None self.load()
class FootprintsFrame(PanelFootprints): def __init__(self, parent): super(FootprintsFrame, self).__init__(parent) # create categories data self.tree_categories_manager = helper.tree.TreeManager( self.tree_categories) self.tree_categories_manager.AddTextColumn("name") self.tree_categories_manager.AddTextColumn("description") self.tree_categories_manager.DropAccept( DataModelCategory, self.onTreeCategoriesDropCategory) self.tree_categories_manager.DropAccept( DataModelFootprint, self.onTreeCategoriesDropFootprint) self.tree_categories_manager.OnSelectionChanged = self.onTreeCategoriesSelChanged # footprints filters self.footprints_filter = Filter(self.filters_panel, self.onButtonRemoveFilterClick) # create footprint list self.tree_footprints_manager = TreeManagerFootprints( self.tree_footprints) self.tree_footprints_manager.AddIntegerColumn("id") self.tree_footprints_manager.AddTextColumn("name") self.tree_footprints_manager.AddTextColumn("description") self.tree_footprints_manager.AddIntegerColumn("comment") self.tree_footprints_manager.OnSelectionChanged = self.onTreeFootprintsSelChanged # create edit footprint panel self.panel_edit_footprint = EditFootprintFrame(self.footprint_splitter) self.footprint_splitter.SplitHorizontally( self.footprint_splitter.Window1, self.panel_edit_footprint, 400) self.panel_edit_footprint.Bind(EVT_EDIT_FOOTPRINT_APPLY_EVENT, self.onEditFootprintApply) self.panel_edit_footprint.Bind(EVT_EDIT_FOOTPRINT_CANCEL_EVENT, self.onEditFootprintCancel) # initial edit state self.show_footprint(None) self.edit_state = None self.load() def loadCategories(self): # clear all self.tree_categories_manager.ClearItems() # load categories categories = rest.api.find_footprints_categories() # load tree to_add = [] id_category_map = {} for category in categories: to_add.append(category) while len(to_add) > 0: category = to_add[0] id_category_map[category.id] = DataModelCategory(category) to_add.pop(0) # add to model if category.parent: self.tree_categories_manager.AppendItem( id_category_map[category.parent.id], id_category_map[category.id]) else: self.tree_categories_manager.AppendItem( None, id_category_map[category.id]) # load childs if category.childs: for child in category.childs: to_add.append(child) def loadFootprints(self): # clear all self.tree_footprints_manager.ClearItems() # load footprints footprints = rest.api.find_footprints( **self.footprints_filter.query_filter()) # load categories categories = {} for footprint in footprints: if footprint.category: category_name = footprint.category.path else: category_name = "/" if categories.has_key(category_name) == False: categories[category_name] = DataModelCategoryPath( footprint.category) self.tree_footprints_manager.AppendItem( None, categories[category_name]) self.tree_footprints_manager.AppendItem( categories[category_name], DataModelFootprint(footprint)) for category in categories: self.tree_footprints_manager.Expand(categories[category]) # Virtual event handlers, overide them in your derived class def load(self): try: self.loadCategories() except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) try: self.loadFootprints() except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def show_footprint(self, footprint): # disable editing self.panel_edit_footprint.enable(False) # enable evrything else self.panel_category.Enabled = True self.panel_footprints.Enabled = True # set part self.panel_edit_footprint.SetFootprint(footprint) def edit_footprint(self, footprint): self.show_footprint(footprint) # enable editing self.panel_edit_footprint.enable(True) # disable evrything else self.panel_category.Enabled = False self.panel_footprints.Enabled = False def new_footprint(self): footprint = rest.model.FootprintNew() # set category item = self.tree_categories.GetSelection() if item.IsOk(): category = self.tree_categories_manager.ItemToObject(item) if category.category: footprint.category = category.category self.edit_footprint(footprint) def onButtonRefreshCategoriesClick(self, event): self.loadCategories() def onButtonAddCategoryClick(self, event): category = EditCategoryFrame(self).addCategory( rest.model.FootprintCategoryNew) if category: try: # retrieve parent item from selection parentitem = self.tree_categories.GetSelection() parentobj = None category.parent = None if parentitem: parentobj = self.tree_categories_manager.ItemToObject( parentitem) category.parent = parentobj.category # create category on server category = rest.api.add_footprints_category(category) # create category on treeview newitem = self.tree_categories_manager.AppendItem( parentobj, DataModelCategory(category)) # add category to item element self.tree_categories_manager.SelectItem(newitem) self.onTreeCategoriesSelChanged(None) except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonEditCategoryClick(self, event): sel = self.tree_categories.GetSelection() categoryobj = self.tree_categories_manager.ItemToObject(sel) if categoryobj is None: return category = EditCategoryFrame(self).editCategory(categoryobj.category) if not category is None: try: categoryobj.category = rest.api.update_footprints_category( categoryobj.category.id, category) self.tree_categories_manager.UpdateItem(categoryobj) self.onTreeCategoriesSelChanged(None) except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonRemoveCategoryClick(self, event): sel = self.tree_categories.GetSelection() categoryobj = self.tree_categories_manager.ItemToObject(sel) if categoryobj is None: return try: res = wx.MessageDialog( self, "Remove category '" + categoryobj.category.name + "'", "Remove?", wx.OK | wx.CANCEL).ShowModal() if res == wx.ID_OK: rest.api.delete_footprints_category(categoryobj.category.id) self.tree_categories_manager.DeleteItem( categoryobj.parent, categoryobj) else: return except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonRemoveFilterClick(self, event): button = event.GetEventObject() self.footprints_filter.remove(button.GetName()) self.tree_categories.UnselectAll() self.loadFootprints() def onTreeCategoriesSelChanged(self, event): item = self.tree_categories.GetSelection() category = None if item.IsOk(): category = self.tree_categories_manager.ItemToObject(item) # set category filter self.footprints_filter.remove('category') if category: self.footprints_filter.add('category', category.category.id, category.category.name) # apply new filter and reload self.loadFootprints() def onTreeCategoriesDropCategory(self, x, y, data): dest_categoryitem, _ = self.tree_categories.HitTest((x, y)) try: source_category_id = data['id'] source_category = rest.api.find_footprints_category( source_category_id) source_categoryitem = helper.tree.TreeManager.drag_item source_categoryobj = self.tree_categories_manager.ItemToObject( source_categoryitem) dest_category = None dest_categoryobj = None if dest_categoryitem.IsOk(): dest_categoryobj = self.tree_categories_manager.ItemToObject( dest_categoryitem) dest_category = dest_categoryobj.category if source_category_id == dest_category.id: return wx.DragError source_category.parent = rest.model.FootprintCategoryRef( id=dest_category.id) else: # set if as root category source_category.parent = None # update on server category = rest.api.update_footprints_category( source_category.id, source_category) # update tree model if source_categoryobj: self.tree_categories_manager.MoveItem( source_categoryobj.parent, dest_categoryobj, source_categoryobj) except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) return wx.DragMove def onTreeCategoriesDropFootprint(self, x, y, data): dest_categoryitem, _ = self.tree_categories.HitTest((x, y)) try: source_footprint_id = data['id'] source_footprint = rest.api.find_footprint(source_footprint_id) dest_category = None dest_categoryobj = None if dest_categoryitem.IsOk(): dest_categoryobj = self.tree_categories_manager.ItemToObject( dest_categoryitem) dest_category = dest_categoryobj.category source_footprint.category = rest.model.FootprintCategoryRef( id=dest_category.id) else: # set if as root category source_footprint.category = None # update on server footprint = rest.api.update_footprint(source_footprint.id, source_footprint) # update tree model self.tree_footprints_manager.DeleteFootprint(source_footprint) self.tree_footprints_manager.AppendFootprint(footprint) except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) return wx.DragMove def onTreeFootprintsSelChanged(self, event): item = self.tree_footprints.GetSelection() footprint = None if not item.IsOk(): return obj = self.tree_footprints_manager.ItemToObject(item) if isinstance(obj, DataModelFootprint): footprint = obj.footprint self.show_footprint(footprint) def onEditFootprintApply(self, event): footprint = event.data try: if self.edit_state == 'edit': # update part on server footprint = rest.api.update_footprint(footprint.id, footprint) self.tree_footprints_manager.UpdateFootprint(footprint) elif self.edit_state == 'add': footprint = rest.api.add_footprint(footprint) self.tree_footprints_manager.AppendFootprint(footprint) except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) return self.edit_state = None self.show_footprint(footprint) def onEditFootprintCancel(self, event): footprint = None item = self.tree_footprints.GetSelection() if item.IsOk(): footprintobj = self.tree_footprints_manager.ItemToObject(item) footprint = footprintobj.footprint self.edit_state = None self.show_footprint(footprint) def onButtonAddFootprintClick(self, event): self.edit_state = 'add' self.new_footprint() def onButtonEditFootprintClick(self, event): item = self.tree_footprints.GetSelection() if not item.IsOk(): return obj = self.tree_footprints_manager.ItemToObject(item) if isinstance(obj, DataModelCategoryPath): return self.edit_state = 'edit' self.edit_footprint(obj.footprint) # def onButtonRemoveFootprintClick(self, event): item = self.tree_footprints.GetSelection() if not item.IsOk(): return obj = self.tree_footprints_manager.ItemToObject(item) if isinstance(obj, DataModelCategoryPath): return footprint = obj.footprint res = wx.MessageDialog(self, "Remove footprint '" + footprint.name + "'", "Remove?", wx.OK | wx.CANCEL).ShowModal() if res == wx.ID_OK: # remove part rest.api.delete_footprint(footprint.id) self.tree_footprints_manager.DeleteFootprint(footprint) else: return self.show_footprint(None) def onButtonRefreshFootprintsClick(self, event): self.loadFootprints() def onSearchFootprintsTextEnter(self, event): # set search filter self.footprints_filter.remove('search') if self.search_footprints.Value != '': self.footprints_filter.add('search', self.search_footprints.Value) # apply new filter and reload self.loadFootprints() def onSearchFootprintsButton(self, event): return self.onSearchFootprintsTextEnter(event)
class StoragesFrame(PanelStorages): def __init__(self, parent): super(StoragesFrame, self).__init__(parent) # create categories data self.tree_categories_manager = helper.tree.TreeManager(self.tree_categories) self.tree_categories_manager.AddTextColumn("name") self.tree_categories_manager.AddTextColumn("description") self.tree_categories_manager.DropAccept(DataModelCategory, self.onTreeCategoriesDropCategory) self.tree_categories_manager.DropAccept(DataModelStorage, self.onTreeCategoriesDropStorage) self.tree_categories_manager.OnSelectionChanged = self.onTreeCategoriesSelChanged # storages filters self.storages_filter = Filter(self.filters_panel, self.onButtonRemoveFilterClick) # create storage list self.tree_storages_manager = TreeManagerStorages(self.tree_storages) self.tree_storages_manager.AddIntegerColumn("id") self.tree_storages_manager.AddTextColumn("name") self.tree_storages_manager.AddTextColumn("description") self.tree_storages_manager.AddIntegerColumn("comment") self.tree_storages_manager.OnSelectionChanged = self.onTreeStoragesSelChanged # create storage part list self.tree_storage_parts_manager = helper.tree.TreeManager(self.tree_storage_parts) self.tree_storage_parts_manager.AddIntegerColumn("id") self.tree_storage_parts_manager.AddTextColumn("name") self.tree_storage_parts_manager.AddIntegerColumn("quantity") self.tree_storage_parts_manager.AddTextColumn("description") self.tree_storage_parts_manager.OnSelectionChanged = self.onTreeStoragePartsSelChanged # initial edit state self.show_storage(None) self.edit_state = None self.loaded = False ; def activate(self): if self.loaded==False: self.load() self.loaded = True def loadCategories(self): try: check_backend() except Exception as e: print_stack() self.GetParent().GetParent().error_message(format(e)) return # clear all self.tree_categories_manager.ClearItems() # load categories categories = rest.api.find_storages_categories() # load tree to_add = [] id_category_map = {} for category in categories: to_add.append(category) while len(to_add)>0: category = to_add[0] id_category_map[category.id] = DataModelCategory(category) to_add.pop(0) # add to symbol if category.parent: self.tree_categories_manager.AppendItem(id_category_map[category.parent.id], id_category_map[category.id]) else: self.tree_categories_manager.AppendItem(None, id_category_map[category.id]) # load childs if category.childs: for child in category.childs: to_add.append(child) def loadStorages(self): try: check_backend() except Exception as e: print_stack() self.GetParent().GetParent().error_message(format(e)) return # clear all self.tree_storages_manager.ClearItems() # load storages storages = rest.api.find_storages(**self.storages_filter.query_filter()) # load categories categories = {} for storage in storages: if storage.category: category_name = storage.category.path else: category_name = "/" if category_name not in categories: categories[category_name] = DataModelCategoryPath(storage.category) self.tree_storages_manager.AppendItem(None, categories[category_name]) self.tree_storages_manager.AppendItem(categories[category_name], DataModelStorage(storage)) for category in categories: self.tree_storages_manager.Expand(categories[category]) # Virtual event handlers, overide them in your derived class def load(self): try: check_backend() except Exception as e: print_stack() self.GetParent().GetParent().error_message(format(e)) return try: self.loadCategories() except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) try: self.loadStorages() except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def show_storage(self, storage): # enable evrything else self.panel_category.Enabled = True self.panel_storages.Enabled = True self.load_storage_parts(storage) def load_storage_parts(self, storage): if storage is None: return parts = rest.api.find_parts(storage=storage.id, with_storages=True) self.tree_storage_parts_manager.ClearItems() for part in parts: if part.storages: for part_storage in part.storages: if part_storage.id==storage.id: storage_partobj = DataModelStoragePart(part, part_storage.quantity) self.tree_storage_parts_manager.AppendItem(None, storage_partobj) def onButtonRefreshCategoriesClick( self, event ): self.loadCategories() def onButtonAddCategoryClick( self, event ): category = EditCategoryFrame(self).addCategory(rest.model.StorageCategoryNew) if category: try: # retrieve parent item from selection parentitem = self.tree_categories.GetSelection() parentobj = None category.parent = None if parentitem: parentobj = self.tree_categories_manager.ItemToObject(parentitem) category.parent = parentobj.category # create category on server category = rest.api.add_storages_category(category) # create category on treeview newitem = self.tree_categories_manager.AppendItem(parentobj, DataModelCategory(category)) # add category to item element self.tree_categories_manager.SelectItem(newitem) self.onTreeCategoriesSelChanged(None) except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonEditCategoryClick( self, event ): sel = self.tree_categories.GetSelection() categoryobj = self.tree_categories_manager.ItemToObject(sel) if categoryobj is None: return category = EditCategoryFrame(self).editCategory(categoryobj.category) if not category is None: try: categoryobj.category = rest.api.update_storages_category(categoryobj.category.id, category) self.tree_categories_manager.UpdateItem(categoryobj) self.onTreeCategoriesSelChanged(None) except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonRemoveCategoryClick( self, event ): sel = self.tree_categories.GetSelection() categoryobj = self.tree_categories_manager.ItemToObject(sel) if categoryobj is None: return try: res = wx.MessageDialog(self, "Remove category '"+categoryobj.category.name+"'", "Remove?", wx.OK|wx.CANCEL).ShowModal() if res==wx.ID_OK: rest.api.delete_storages_category(categoryobj.category.id) self.tree_categories_manager.DeleteItem(categoryobj.parent, categoryobj) else: return except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonRemoveFilterClick( self, event ): button = event.GetEventObject() self.storages_filter.remove(button.GetName()) self.tree_categories.UnselectAll() self.loadStorages() def onTreeCategoriesSelChanged( self, event ): item = self.tree_categories.GetSelection() category = None if item.IsOk(): category = self.tree_categories_manager.ItemToObject(item) # set category filter self.storages_filter.remove('category') if category: self.storages_filter.add('category', category.category.id, category.category.name) # apply new filter and reload self.loadStorages() def onTreeCategoriesDropCategory(self, x, y, data): dest_categoryitem, _ = self.tree_categories.HitTest((x, y)) try: source_category_id = data['id'] source_category = rest.api.find_storages_category(source_category_id) source_categoryitem = helper.tree.TreeManager.drag_item source_categoryobj = self.tree_categories_manager.ItemToObject(source_categoryitem) dest_category = None dest_categoryobj = None if dest_categoryitem.IsOk(): dest_categoryobj = self.tree_categories_manager.ItemToObject(dest_categoryitem) dest_category = dest_categoryobj.category if source_category_id==dest_category.id: return wx.DragError source_category.parent = rest.model.StorageCategoryRef(id=dest_category.id) else: # set if as root category source_category.parent = None # update on server category = rest.api.update_storages_category(source_category.id, source_category) # update tree symbol if source_categoryobj: self.tree_categories_manager.MoveItem(source_categoryobj.parent, dest_categoryobj, source_categoryobj) except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) return wx.DragMove def onTreeCategoriesDropStorage(self, x, y, data): dest_categoryitem, _ = self.tree_categories.HitTest((x, y)) try: source_storage_id = data['id'] source_storage = rest.api.find_storage(source_storage_id) dest_category = None dest_categoryobj = None if dest_categoryitem.IsOk(): dest_categoryobj = self.tree_categories_manager.ItemToObject(dest_categoryitem) dest_category = dest_categoryobj.category source_storage.category = rest.model.StorageCategoryRef(id=dest_category.id) else: # set if as root category source_storage.category = None # update on server storage = rest.api.update_storage(source_storage.id, source_storage) # update tree symbol self.tree_storages_manager.DeleteStorage(source_storage) self.tree_storages_manager.AppendStorage(storage) except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) return wx.DragMove def onTreeStoragesSelChanged( self, event ): item = self.tree_storages.GetSelection() storage = None if not item.IsOk(): return obj = self.tree_storages_manager.ItemToObject(item) if isinstance(obj, DataModelStorage): storage = obj.storage self.show_storage(storage) def onEditStorageApply( self, event ): storage = event.data try: if self.edit_state=='edit': # update part on server storage = rest.api.update_storage(storage.id, storage) self.tree_storages_manager.UpdateStorage(storage) elif self.edit_state=='add': storage = rest.api.add_storage(storage) self.tree_storages_manager.AppendStorage(storage) except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) return self.edit_state = None self.show_storage(storage) def onEditStorageCancel( self, event ): storage = None item = self.tree_storages.GetSelection() if item.IsOk(): storageobj = self.tree_storages_manager.ItemToObject(item) storage = storageobj.storage self.edit_state = None self.show_storage(storage) def onButtonAddStorageClick( self, event ): storage = EditStorageFrame(self).addStorage(rest.model.StorageNew) if storage: try: # retrieve parent item from selection categoryitem = self.tree_categories.GetSelection() categoryobj = None storage.category = None if categoryitem: categoryobj = self.tree_categories_manager.ItemToObject(categoryitem) storage.category = categoryobj.category # create category on server storage = rest.api.add_storage(storage) # create category on treeview newitem = self.tree_storages_manager.AppendItem(None, DataModelStorage(storage)) # add category to item element self.tree_storages_manager.SelectItem(newitem) self.onTreeStoragesSelChanged(None) except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonEditStorageClick( self, event ): sel = self.tree_storages.GetSelection() if sel.IsOk()==False: return storageobj = self.tree_storages_manager.ItemToObject(sel) if storageobj is None: return storage = EditStorageFrame(self).editStorage(storageobj.storage) if not storage is None: try: storageobj.storage = rest.api.update_storage(storageobj.storage.id, storage) self.tree_storages_manager.UpdateItem(storageobj) self.onTreeStoragesSelChanged(None) except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) # def onButtonRemoveStorageClick( self, event ): sel = self.tree_storages.GetSelection() if sel.IsOk()==False: return storageobj = self.tree_storages_manager.ItemToObject(sel) if storageobj is None: return try: res = wx.MessageDialog(self, "Remove storage '"+storageobj.storage.name+"'", "Remove?", wx.OK|wx.CANCEL).ShowModal() if res==wx.ID_OK: rest.api.delete_storage(storageobj.storage.id) self.tree_storages_manager.DeleteItem(storageobj.parent, storageobj) self.onTreeStoragesSelChanged(None) else: return except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonRefreshStoragesClick( self, event ): self.loadStorages() def onSearchStoragesTextEnter( self, event ): # set search filter self.storages_filter.remove('search') if self.search_storages.Value!='': self.storages_filter.add('search', self.search_storages.Value) # apply new filter and reload self.loadStorages() def onButtonAddStoragePartClick( self, event ): item = self.tree_storages.GetSelection() if item.IsOk()==False: return obj = self.tree_storages_manager.ItemToObject(item) if isinstance(obj, DataModelStorage)==False: return dropdown = DropdownDialog(self.button_add_storage_part, SelectPartFrame, "") dropdown.panel.Bind( EVT_SELECT_PART_OK_EVENT, self.onSelectPartCallback ) dropdown.Dropdown() def onButtonRemoveStoragePartClick( self, event ): event.Skip() def onSearchStoragesButton(self, event): return self.onSearchStoragesTextEnter(event) def onTreeStoragePartsSelChanged( self, event ): pass def onButtonAddStorageItemClick( self, event ): item = self.tree_storages.GetSelection() if item.IsOk()==False: return storageobj = self.tree_storages_manager.ItemToObject(item) if isinstance(storageobj, DataModelStorage)==False: return sel = self.tree_storage_parts.GetSelection() if sel.IsOk()==False: return partobj = self.tree_storage_parts_manager.ItemToObject(sel) if partobj is None: return if self.spin_num_parts.Value==0: return try: res = wx.MessageDialog(self, "Add %d items of %s to storage?"%(self.spin_num_parts.Value, partobj.part.name), "Add?", wx.OK|wx.CANCEL).ShowModal() if res==wx.ID_OK: part = rest.api.find_part(partobj.part.id, with_storages=True) for part_storage in part.storages: if part_storage.id==storageobj.storage.id: part_storage.quantity = part_storage.quantity+self.spin_num_parts.Value break partobj.part = rest.api.update_part(part.id, part) partobj.quantity = part_storage.quantity self.tree_storage_parts_manager.UpdateItem(partobj) else: return except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonRemoveStorageItemClick( self, event ): item = self.tree_storages.GetSelection() if item.IsOk()==False: return storageobj = self.tree_storages_manager.ItemToObject(item) if isinstance(storageobj, DataModelStorage)==False: return sel = self.tree_storage_parts.GetSelection() if sel.IsOk()==False: return partobj = self.tree_storage_parts_manager.ItemToObject(sel) if partobj is None: return if self.spin_num_parts.Value==0: return try: res = wx.MessageDialog(self, "Remove %d items of %s to storage?"%(self.spin_num_parts.Value, partobj.part.name), "Remove?", wx.OK|wx.CANCEL).ShowModal() if res==wx.ID_OK: part = rest.api.find_part(partobj.part.id, with_storages=True) for part_storage in part.storages: if part_storage.id==storageobj.storage.id: part_storage.quantity = part_storage.quantity-self.spin_num_parts.Value break partobj.part = rest.api.update_part(part.id, part) if part_storage.quantity<0: part_storage.quantity = 0 partobj.quantity = part_storage.quantity self.tree_storage_parts_manager.UpdateItem(partobj) else: return except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onSelectPartCallback(self, part_event): item = self.tree_storages.GetSelection() if item.IsOk()==False: return storageobj = self.tree_storages_manager.ItemToObject(item) if isinstance(storageobj, DataModelStorage)==False: return part = part_event.data # check if part already exist for data in self.tree_storage_parts_manager.data: if data.part.id==part.id: wx.MessageDialog(self, "%s already added, skipped" % part_event.data.name, "Error adding part", wx.OK | wx.ICON_ERROR).ShowModal() return # update storages on part part = rest.api.find_part(part.id, with_storages=True) if part.storages is None: part.storages = [] part_storage = PartStorage() part_storage.id = storageobj.storage.id part_storage.quantity = self.spin_num_parts.Value part.storages.append(part_storage) part = rest.api.update_part(part.id, part) partobj = DataModelStoragePart(part, part_storage.quantity) self.tree_storage_parts_manager.AppendItem(None, partobj)
class PartsFrame(PanelParts): def __init__(self, parent): super(PartsFrame, self).__init__(parent) # create categories list self.tree_categories_manager = helper.tree.TreeManager(self.tree_categories, context_menu=self.menu_category) self.tree_categories_manager.AddTextColumn("name") self.tree_categories_manager.AddTextColumn("description") self.tree_categories_manager.DropAccept(DataModelCategory, self.onTreeCategoriesDropCategory) self.tree_categories_manager.DropAccept(DataModelPart, self.onTreeCategoriesDropPart) self.tree_categories_manager.OnSelectionChanged = self.onTreeCategoriesSelChanged self.tree_categories_manager.OnItemBeforeContextMenu = self.onTreeCategoriesBeforeContextMenu # parts filters self.parts_filter = Filter(self.filters_panel, self.onButtonRemoveFilterClick) # create parts list self.tree_parts_manager = TreeManagerParts(self.tree_parts, context_menu=self.menu_part) self.tree_parts_manager.AddIntegerColumn("id") self.tree_parts_manager.AddTextColumn("name") self.tree_parts_manager.AddTextColumn("description") self.tree_parts_manager.AddIntegerColumn("comment") self.tree_parts_manager.AddTextColumn("symbol") self.tree_parts_manager.AddTextColumn("footprint") self.tree_parts_manager.OnSelectionChanged = self.onTreePartsSelChanged self.tree_parts_manager.OnColumnHeaderRightClick = self.onTreePartsColumnHeaderRightClick self.tree_parts_manager.DropAccept(DataModelPart, self.onTreePartsDropPart) self.tree_parts_manager.OnItemBeforeContextMenu = self.onTreePartsBeforeContextMenu # # create edit part panel self.panel_edit_part = EditPartFrame(self.part_splitter) self.part_splitter.SplitHorizontally(self.part_splitter.Window1, self.panel_edit_part, 400) self.panel_edit_part.Bind( EVT_EDIT_PART_APPLY_EVENT, self.onEditPartApply ) self.panel_edit_part.Bind( EVT_EDIT_PART_CANCEL_EVENT, self.onEditPartCancel ) self.toolbar_part.ToggleTool(self.toggle_part_path.GetId(), True) # initial edit state self.show_part(None) self.edit_state = None self.show_categories = True self.load() def loadCategories(self): # clear all self.tree_categories_manager.ClearItems() # load categories categories = rest.api.find_parts_categories() # load tree to_add = [] id_category_map = {} for category in categories: to_add.append(category) while len(to_add)>0: category = to_add[0] id_category_map[category.id] = DataModelCategory(category) to_add.pop(0) # add to symbol if category.parent: self.tree_categories_manager.AppendItem(id_category_map[category.parent.id], id_category_map[category.id]) else: self.tree_categories_manager.AppendItem(None, id_category_map[category.id]) # load childs if category.childs: for child in category.childs: to_add.append(child) def loadParts(self): # clear all self.tree_parts_manager.ClearItems() # load parts parts = rest.api.find_parts( with_parameters=True, **self.parts_filter.query_filter()) if self.show_categories: # load categories categories = {} for part in parts: if part.category: category_name = part.category.path else: category_name = "/" if categories.has_key(category_name)==False: categories[category_name] = DataModelCategoryPath(part.category) self.tree_parts_manager.AppendItem(None, categories[category_name]) self.tree_parts_manager.AppendItem(categories[category_name], DataModelPart(part, self.tree_parts_manager.model.columns)) for category in categories: self.tree_parts_manager.Expand(categories[category]) else: for part in parts: self.tree_parts_manager.AppendItem(None, DataModelPart(part, self.tree_parts_manager.model.columns)) def load(self): try: self.loadCategories() except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) try: self.loadParts() except Exception as e: print_stack() wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def load_full_part(self, partobj): if partobj: # read whole part from server partobj.part = rest.api.find_part(partobj.part.id, with_offers=True, with_parameters=True, with_childs=True, with_distributors=True, with_manufacturers=True, with_storages=True, with_attachements=True) def show_part(self, part): # disable editing self.panel_edit_part.enable(False) # enable evrything else self.panel_category.Enabled = True self.panel_parts.Enabled = True # set part self.panel_edit_part.SetPart(part) def edit_part(self, part): self.show_part(part) # enable editing self.panel_edit_part.enable(True) # disable evrything else self.panel_category.Enabled = False self.panel_parts.Enabled = False def new_part(self): part = rest.model.PartNew() # set category item = self.tree_categories.GetSelection() if item.IsOk(): category = self.tree_categories_manager.ItemToObject(item) if category.category: part.category = category.category self.edit_part(part) def export_parts(self): # exporters = plugin_loader.load_export_plugins() # wildcards = '|'.join([x.wildcard for x in exporters]) # wildcards # exportpath=os.path.join(os.getcwd(),'test','TESTimportCSV.csv') # exportpath # base, ext = os.path.splitext(exportpath) # TODO: implement export exporters = plugin_loader.load_export_plugins() wildcards = '|'.join([x.wildcard for x in exporters]) export_dialog = wx.FileDialog(self, "Export Parts", "", "", wildcards, wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) if export_dialog.ShowModal() == wx.ID_CANCEL: return base, ext = os.path.splitext(export_dialog.GetPath()) filt_idx = export_dialog.GetFilterIndex() # load parts parts = rest.api.find_parts(**self.parts_filter.query_filter()) exporters[filt_idx]().export(base, parts) self.edit_state = None def import_parts(self): importers = plugin_loader.load_import_plugins() wildcards = '|'.join([x.wildcard for x in importers]) import_dialog = wx.FileDialog(self, "Import Parts", "", "", wildcards, wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) if import_dialog.ShowModal() == wx.ID_CANCEL: return base, ext = os.path.splitext(import_dialog.GetPath()) filt_idx = import_dialog.GetFilterIndex() # set category item = self.tree_categories.GetSelection() if item.IsOk(): category = self.tree_categories_manager.ItemToObject(item) if category.category: import_items = importers[filt_idx]().fetch(base, category.category, rest.model) progression_frame = ProgressionFrame(self, "Importing parts ") ; progression_frame.Show() for i, importItem in enumerate(import_items): wx.Yield() part = rest.model.PartNew() # SET imported Parts Fields part.name = importItem.name part.description = importItem.description # Update progress indicator progression_frame.SetProgression(part.name, i+1, len(import_items)) if progression_frame.Canceled(): break if isinstance(importItem.footprint, str) and len(importItem.footprint) == 0: # Blank Footprint part.footprint = None else: # Determine or Create correct Footprint References searchparam = {'search': importItem.footprint} matching_footprints = rest.api.find_footprints(**searchparam) if len(matching_footprints)==0: # ADD new footprint # Check Footprint Category: "Uncatagorized" exists try: footprintcategoryid = {i.name: i.id for i in rest.api.find_footprints_categories()}['Uncategorized'] except KeyError, e: # Category 'Uncategorized' does not exist print_stack() # Create the "Uncategorized" category category = rest.model.FootprintCategoryNew() category.name = "Uncategorized" category.description = 'imported footprint names not already defined' category = rest.api.add_footprints_category(category) footprintcategoryid = category.id except: print_stack() # TODO: handle other errors cleanly raise pass part.footprint = rest.model.FootprintNew() part.footprint.category = rest.model.FootprintCategoryRef(id=footprintcategoryid) part.footprint.name = importItem.footprint part.footprint.description = u'' part.footprint.comment = u'' # update part on server part.footprint = rest.api.add_footprint(part.footprint)
class PartsFrame(PanelParts): def __init__(self, parent): super(PartsFrame, self).__init__(parent) # create categories list self.tree_categories_manager = helper.tree.TreeManager(self.tree_categories) self.tree_categories_manager.AddTextColumn("name") self.tree_categories_manager.AddTextColumn("description") self.tree_categories_manager.DropAccept(DataModelCategory, self.onTreeCategoriesDropCategory) self.tree_categories_manager.DropAccept(DataModelPart, self.onTreeCategoriesDropPart) self.tree_categories_manager.OnSelectionChanged = self.onTreeCategoriesSelChanged # parts filters self.parts_filter = Filter(self.filters_panel, self.onButtonRemoveFilterClick) # create parts list self.tree_parts_manager = TreeManagerParts(self.tree_parts) self.tree_parts_manager.AddIntegerColumn("id") self.tree_parts_manager.AddTextColumn("name") self.tree_parts_manager.AddTextColumn("description") self.tree_parts_manager.AddIntegerColumn("comment") self.tree_parts_manager.OnSelectionChanged = self.onTreePartsSelChanged self.tree_parts_manager.DropAccept(DataModelPart, self.onTreePartsDropPart) # # create edit part panel self.panel_edit_part = EditPartFrame(self.part_splitter) self.part_splitter.SplitHorizontally(self.part_splitter.Window1, self.panel_edit_part, 400) self.panel_edit_part.Bind( EVT_EDIT_PART_APPLY_EVENT, self.onEditPartApply ) self.panel_edit_part.Bind( EVT_EDIT_PART_CANCEL_EVENT, self.onEditPartCancel ) # initial edit state self.show_part(None) self.edit_state = None self.load() def loadCategories(self): # clear all self.tree_categories_manager.ClearItems() # load categories categories = rest.api.find_parts_categories() # load tree to_add = [] id_category_map = {} for category in categories: to_add.append(category) while len(to_add)>0: category = to_add[0] id_category_map[category.id] = DataModelCategory(category) to_add.pop(0) # add to model if category.parent: self.tree_categories_manager.AppendItem(id_category_map[category.parent.id], id_category_map[category.id]) else: self.tree_categories_manager.AppendItem(None, id_category_map[category.id]) # load childs if category.childs: for child in category.childs: to_add.append(child) def loadParts(self): # clear all self.tree_parts_manager.ClearItems() # load parts parts = rest.api.find_parts(**self.parts_filter.query_filter()) # load categories categories = {} for part in parts: if part.category: category_name = part.category.path else: category_name = "/" if categories.has_key(category_name)==False: categories[category_name] = DataModelCategoryPath(part.category) self.tree_parts_manager.AppendItem(None, categories[category_name]) self.tree_parts_manager.AppendItem(categories[category_name], DataModelPart(part)) for category in categories: self.tree_parts_manager.Expand(categories[category]) def load(self): try: self.loadCategories() except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) try: self.loadParts() except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def load_full_part(self, partobj): if partobj: # read whole part from server partobj.part = rest.api.find_part(partobj.part.id, with_offers=True, with_parameters=True, with_childs=True, with_distributors=True, with_manufacturers=True, with_storages=True, with_attachements=True) def show_part(self, part): # disable editing self.panel_edit_part.enable(False) # enable evrything else self.panel_category.Enabled = True self.panel_parts.Enabled = True # set part self.panel_edit_part.SetPart(part) def edit_part(self, part): self.show_part(part) # enable editing self.panel_edit_part.enable(True) # disable evrything else self.panel_category.Enabled = False self.panel_parts.Enabled = False def new_part(self): part = rest.model.PartNew() # set category item = self.tree_categories.GetSelection() if item.IsOk(): category = self.tree_categories_manager.ItemToObject(item) if category.category: part.category = category.category self.edit_part(part) def GetMenus(self): return [{'title': 'Parts', 'menu': self.menu_parts}] def onButtonRefreshCategoriesClick( self, event ): self.loadCategories() def onButtonAddCategoryClick( self, event ): category = EditCategoryFrame(self).addCategory(rest.model.PartCategoryNew) if category: try: # retrieve parent item from selection parentitem = self.tree_categories.GetSelection() parentobj = None category.parent = None if parentitem: parentobj = self.tree_categories_manager.ItemToObject(parentitem) category.parent = parentobj.category # create category on server category = rest.api.add_parts_category(category) # create category on treeview newitem = self.tree_categories_manager.AppendItem(parentobj, DataModelCategory(category)) # add category to item element self.tree_categories_manager.SelectItem(newitem) self.onTreeCategoriesSelChanged(None) except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonEditCategoryClick( self, event ): sel = self.tree_categories.GetSelection() if sel.IsOk()==False: return categoryobj = self.tree_categories_manager.ItemToObject(sel) if categoryobj is None: return category = EditCategoryFrame(self).editCategory(categoryobj.category) if not category is None: try: categoryobj.category = rest.api.update_parts_category(categoryobj.category.id, category) self.tree_categories_manager.UpdateItem(categoryobj) self.onTreeCategoriesSelChanged(None) except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonRemoveCategoryClick( self, event ): sel = self.tree_categories.GetSelection() categoryobj = self.tree_categories_manager.ItemToObject(sel) if categoryobj is None: return try: res = wx.MessageDialog(self, "Remove category '"+categoryobj.category.name+"'", "Remove?", wx.OK|wx.CANCEL).ShowModal() if res==wx.ID_OK: rest.api.delete_parts_category(categoryobj.category.id) self.tree_categories_manager.DeleteItem(categoryobj.parent, categoryobj) else: return except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) def onButtonRemoveFilterClick( self, event ): button = event.GetEventObject() self.parts_filter.remove(button.GetName()) self.tree_categories.UnselectAll() self.loadParts() def onTreeCategoriesSelChanged( self, event ): item = self.tree_categories.GetSelection() category = None if item.IsOk(): category = self.tree_categories_manager.ItemToObject(item) # set category filter self.parts_filter.remove('category') if category: self.parts_filter.add('category', category.category.id, category.category.name) # apply new filter and reload self.loadParts() def onTreeCategoriesDropCategory(self, x, y, data): dest_categoryitem, _ = self.tree_categories.HitTest((x, y)) try: source_category_id = data['id'] source_category = rest.api.find_parts_category(source_category_id) source_categoryitem = helper.tree.TreeManager.drag_item source_categoryobj = self.tree_categories_manager.ItemToObject(source_categoryitem) dest_category = None dest_categoryobj = None if dest_categoryitem.IsOk(): dest_categoryobj = self.tree_categories_manager.ItemToObject(dest_categoryitem) dest_category = dest_categoryobj.category if source_category_id==dest_category.id: return wx.DragError source_category.parent = rest.model.PartCategoryRef(id=dest_category.id) else: # set if as root category source_category.parent = None # update on server category = rest.api.update_parts_category(source_category.id, source_category) # update tree model if source_categoryobj: self.tree_categories_manager.MoveItem(source_categoryobj.parent, dest_categoryobj, source_categoryobj) except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) return wx.DragMove def onTreeCategoriesDropPart(self, x, y, data): dest_categoryitem, _ = self.tree_categories.HitTest((x, y)) try: source_part_id = data['id'] source_part = rest.api.find_part(source_part_id) dest_category = None dest_categoryobj = None if dest_categoryitem.IsOk(): dest_categoryobj = self.tree_categories_manager.ItemToObject(dest_categoryitem) dest_category = dest_categoryobj.category source_part.category = rest.model.PartCategoryRef(id=dest_category.id) else: # set if as root category source_part.category = None # update on server part = rest.api.update_part(source_part.id, source_part) # update tree model self.tree_parts_manager.DeletePart(source_part) self.tree_parts_manager.AppendPart(part) except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) return wx.DragMove def onTreePartsSelChanged( self, event ): item = self.tree_parts.GetSelection() part = None if not item.IsOk(): return obj = self.tree_parts_manager.ItemToObject(item) if isinstance(obj, DataModelPart): self.load_full_part(obj) part = obj.part self.show_part(part) def onTreePartsDropPart(self, x, y, data): dest_item, _ = self.tree_parts.HitTest((x, y)) if not dest_item.IsOk(): return dest_obj = self.tree_parts_manager.ItemToObject(dest_item) if isinstance(dest_obj, DataModelPart) and isinstance(dest_obj.parent, DataModelCategoryPath): try: source_part_id = data['id'] source_partobj = self.tree_parts_manager.FindPart(source_part_id) dest_part = rest.api.find_part(dest_obj.part.id, with_childs=True) dest_part.childs.append(source_partobj.part) rest.api.update_part(dest_part.id, dest_part) # update tree model self.tree_parts_manager.AppendChildPart(dest_part, source_partobj.part) except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) return wx.DragMove def onEditPartApply( self, event ): part = event.data try: if self.edit_state=='edit': # update part on server part = rest.api.update_part(part.id, part) self.tree_parts_manager.UpdatePart(part) elif self.edit_state=='add': part = rest.api.add_part(part) self.tree_parts_manager.AppendPart(part) except Exception as e: wx.MessageBox(format(e), 'Error', wx.OK | wx.ICON_ERROR) return self.edit_state = None self.show_part(part) def onEditPartCancel( self, event ): part = None item = self.tree_parts.GetSelection() if item.IsOk(): partobj = self.tree_parts_manager.ItemToObject(item) self.load_full_part(partobj) part = partobj.part self.edit_state = None self.show_part(part) def onButtonAddPartClick( self, event ): self.edit_state = 'add' self.new_part() def onButtonEditPartClick( self, event ): item = self.tree_parts.GetSelection() if not item.IsOk(): return obj = self.tree_parts_manager.ItemToObject(item) if isinstance(obj, DataModelCategoryPath): return self.load_full_part(obj) self.edit_state = 'edit' self.edit_part(obj.part) def onButtonRemovePartClick( self, event ): item = self.tree_parts.GetSelection() if not item.IsOk(): return obj = self.tree_parts_manager.ItemToObject(item) if isinstance(obj, DataModelCategoryPath): return part = obj.part if isinstance(obj.parent, DataModelPart): parent = obj.parent.part res = wx.MessageDialog(self, "Remove part '"+part.name+"' from '"+parent.name+"'", "Remove?", wx.OK|wx.CANCEL).ShowModal() if res==wx.ID_OK: # remove selected part from subparts parent = rest.api.find_part(parent.id, with_childs=True) for child in parent.childs: if child.id==part.id: parent.childs.remove(child) #parent.childs.remove(part) rest.api.update_part(parent.id, parent) self.tree_parts_manager.DeleteChildPart(parent, part) else: return else: res = wx.MessageDialog(self, "Remove part '"+part.name+"'", "Remove?", wx.OK|wx.CANCEL).ShowModal() if res==wx.ID_OK: # remove part rest.api.delete_part(part.id) self.tree_parts_manager.DeletePart(part) else: return self.show_part(None) def onSearchPartsTextEnter( self, event ): # set search filter self.parts_filter.remove('search') if self.search_parts.Value!='': self.parts_filter.add('search', self.search_parts.Value) # apply new filter and reload self.loadParts() def onSearchPartsButton(self, event): return self.onSearchPartsTextEnter(event) def onButtonRefreshPartsClick( self, event ): self.loadParts() def OnMenuItem( self, event ): # events are not distributed by the frame so we distribute them manually if event.GetId()==self.menu_parts_refresh_octopart.GetId(): self.onMenuItemPartsRefreshOctopart(event) def onMenuItemPartsRefreshOctopart( self, event ): progression_frame = ProgressionFrame(self, "Refresh parts from Octopart") ; progression_frame.Show() ; self.Enabled = False # get category sel = self.tree_categories.GetSelection() if sel.IsOk(): categoryobj = self.tree_categories_manager.ItemToObject(sel) else: categoryobj = None if categoryobj is None: parts = rest.api.find_parts() else: parts = rest.api.find_parts(category=categoryobj.category.id) i = 1 for part in parts: wx.Yield() if part.octopart and part.octopart!="": self.refresh_octopart(part) progression_frame.SetProgression(part.name, i, len(parts)) ; if progression_frame.Canceled(): break i = i+1 self.Enabled = True progression_frame.Destroy() def refresh_octopart(self, part): # print "Refresh octopart for", part.name # get full part part = rest.api.find_part(part.id, with_offers=True, with_parameters=True, with_distributors=True, with_manufacturers=True) # get octopart data q = PartsQuery() q.get(part.octopart) sleep(1) # only one request per second allowed for octopart in q.results(): print "octopart:", octopart.json if octopart.item().uid()==part.octopart_uid: print "Refresh", part.octopart self.octopart_to_part(octopart, part) # update part rest.api.update_part(part.id, part) return def octopart_to_part(self, octopart, part): # convert octopart to part values octopart_extractor = OctopartExtractor(octopart) # import part fields part.name = octopart.item().mpn() part.description = octopart.snippet() if part.description is None: part.description = "" # set field octopart to indicatethat part was imported from octopart part.octopart = octopart.item().mpn() part.updated = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ") # import parameters for spec_name in octopart.item().specs(): parameter = octopart_extractor.ExtractParameter(spec_name) # check if parameter already exist for p in part.parameters: if p.name==parameter.name: part.parameters.remove(p) break part.parameters.append(parameter) # remove all offers from distributor prior to add new offers for offer in octopart.item().offers(): distributor_name = offer.seller().name() if part.distributors is None: return to_remove = [] for distributor in part.distributors: if distributor.name==distributor_name: to_remove.append(distributor) # don't remove in previous loop to avoid missing elements for distributor in to_remove: part.distributors.remove(distributor) # import distributors part_distributors = {} for offer in octopart.item().offers(): distributor_name = offer.seller().name() if part_distributors.has_key(distributor_name)==False: distributor = None try: distributors = rest.api.find_distributors(name=distributor_name) if len(distributors)>0: distributor = distributors[0] else: # distributor does not exists, create it distributor = rest.model.DistributorNew() distributor.name = offer.seller().name() distributor.website = offer.seller().homepage_url() distributor.allowed = True distributor = rest.api.add_distributor(distributor) except Exception as e: wx.MessageBox(format(e), 'Error with distributor %s'%distributor_name, wx.OK | wx.ICON_ERROR) if distributor: part_distributor = rest.model.PartDistributor() part_distributor.id = distributor.id part_distributor.name = distributor.name part_distributor.offers = [] part_distributors[distributor_name] = part_distributor if part_distributors.has_key(distributor_name): for price_name in offer.prices(): for quantity in offer.prices()[price_name]: part_offer = rest.model.PartOffer() part_offer.name = distributor_name part_offer.distributor = distributor part_offer.currency = price_name if offer.moq(): part_offer.packaging_unit = offer.moq() else: part_offer.packaging_unit = 1 part_offer.quantity = quantity[0] part_offer.unit_price = float(quantity[1]) part_offer.sku = offer.sku() part_distributors[distributor_name].offers.append(part_offer) # add part_distributors to part for distributor_name in part_distributors: part.distributors.append(part_distributors[distributor_name]) # import manufacturer manufacturer_name = octopart.item().manufacturer().name() manufacturer = None part.manufacturers = [] try: manufacturers = rest.api.find_manufacturers(name=manufacturer_name) if len(manufacturers)>0: manufacturer = manufacturers[0] else: # distributor does not exists, create it manufacturer = rest.model.Manufacturer() manufacturer.name = manufacturer_name manufacturer.website = octopart.item().manufacturer().homepage_url() manufacturer = rest.api.add_manufacturer(manufacturer) # add new manufacturer part_manufacturer = rest.model.PartManufacturer() part_manufacturer.name = manufacturer.name part_manufacturer.part_name = part.name part.manufacturers.append(part_manufacturer) except: wx.MessageBox('%s: unknown error retrieving manufacturer' % (manufacturer_name), 'Warning', wx.OK | wx.ICON_EXCLAMATION)