def edit_delivery_slip(self): order_id = None w = self.stack.currentWidget() if self.order_overview_widget == w: order_id = self.order_overview_widget.current_order_id() elif isinstance(w,EditOrderPartsWidget): if w._current_order.order_id and w.save_if_necessary(): order_id = w._current_order.order_id if order_id: res = handle_edit_delivery_slip(order_id,self) if res: # self.edit_order_parts_widget.refresh_panel() # self.trigger_order_refresh() # pub.sendMessage('delivery_slip.insert') mainlog.debug("Refreshing panels") for panel in self.stack.panels(): mainlog.debug("Panel {} {} ".format(type(panel), isinstance(panel,EditOrderPartsWidget))) if isinstance(panel,EditOrderPartsWidget) and panel.current_order_id == order_id: mainlog.debug("Refreshing panel") panel.refresh_panel() self.order_overview_widget.refresh_panel() self.get_monthly_production_overview_widget().refresh_panel() # self.module.financial_panel.refresh_panel() self.get_delivery_slip_widget().refresh_panel() else: showErrorBox(_("There's no selected order. We can't create a delivery slip without that.")) return False
def delete_action(self): if self.current_item: o_id = getattr( self.current_item, self.key_field) if o_id >= 0: # For some reason I have o_id = 0 somewhere... # mainlog.debug("About to delete {}".format(o_id)) try: if self.delete_object(o_id): self.current_item = None # Do this only if delete was successful ! self.in_save = True self._refresh_list() # The current filter might lead to a 0-length list # or we might delete the only item of the list # In that case, we clear the form. if self.list_view.model().rowCount() > 0: self.list_view.selectRow(0) else: self._populate_form(None) self.in_save = False except Exception as e: showErrorBox(_("There was an error while deleting"),str(e),e) return else: mainlog.error("The current object has no id => I can't delete it") else: showWarningBox(_("You have selected nothing for delete."),None) return
def _add_day_off(self, action): if action.data() != 'Remove': day_event_type, day_event_duration = action.data() day_event_type = DayEventType.from_str(day_event_type) mainlog.debug("selected action {} {}".format( day_event_type, day_event_duration)) ndx = self.table_view.currentIndex() day_event_id = ndx.data(Qt.UserRole + 1) # if day_event_id: # showWarningBox(_("There's already a day off here")) # return employee_id = self._employee_id_on_row(ndx) if employee_id in self.all_presences: day = ndx.column() - 1 mainlog.debug("_add_day_off : employee_id={}, day={}".format( employee_id, day)) mainlog.debug(self.all_presences[employee_id]) mainlog.debug(type(self.all_presences[employee_id])) # if self.all_presences[employee_id][day]: # showWarningBox(_("One can't add day off where there is activity")) # return else: mainlog.debug( "_add_day_off : employee_id={} not yet known".format( employee_id)) day_event = DayEvent() day_event.employee_id = employee_id day_event.event_type = day_event_type day, last_day = self._selection_to_period() if day_event_duration in (0.5, 1): days_durations = [(day, day_event_duration)] else: days_durations = [] day, last_day = self._selection_to_period() while day <= last_day: days_durations.append( (day, 1)) # One full work day on the day day += timedelta(1) # mainlog.debug(days_durations) mainlog.debug("Creating day event of type {}".format( day_event.event_type)) try: people_admin_service.set_event_on_days(day_event, days_durations) except ServerException as ex: showErrorBox(ex.translated_message) self.refresh_action()
def _download_on_button_id(self, button_id, destination): """ Download a file. Returns the path to file or None if nothing was downloaded """ # mainlog.debug("_download_on_button_id() : button_id={}".format(button_id)) doc_id = self.button_data[button_id] # if os.path.isabs(full_path_client): # # The file was uploaded during this GUI session. Therefore we # # still know where we picked it from (FIXME unless someone has # # removed it...) # # return full_path_client # else: progress_bar = make_progress(_("Downloading"), 100) def progress_tracker(percent): progress_bar.setValue(int(percent)) try: path = download_document(doc_id, progress_tracker, destination) return path except Exception as exc: progress_bar.close() showErrorBox(_( "There was a problem while downloading the file from the server" ), ex=exc, object_name="file_upload_error") return None progress_bar.close()
def _add_file(self, full_path_client: str, document_category_id=None): mainlog.debug( "document widget _add_file categ={}".format(document_category_id)) if self._test_file_access(full_path_client): progress_bar = make_progress(_("Uploading"), 100) def progress_tracker(percent): progress_bar.setValue(int(percent)) try: doc_id = upload_document(full_path_client, progress_tracker) except Exception as exc: progress_bar.close() showErrorBox(_( "There was a problem while uploading the file to the server" ), ex=exc, object_name="file_upload_error") return d = self.documents_service.find_by_id(doc_id) doc = Document() doc.document_id = d.document_id doc.file_size = d.file_size doc.description = d.description doc.filename = d.filename doc.server_location = d.server_location doc.upload_date = d.upload_date if document_category_id: doc.document_category_id = document_category_id self.model.append_objects([doc])
def delete_filter_action_slot(self): try: fq_id = None if self.filter_name.currentIndex() >= 0: fq_id = self.filter_name.itemData(self.filter_name.currentIndex()) if not fq_id: showWarningBox(_("The filter you want to delete was never saved"),None,parent=self,object_name="no_need_to_delete_filter") return fq = dao.filters_dao.find_by_id(fq_id) if fq.owner_id != user_session.user_id: showWarningBox(_("You can't delete the filter because it doesn't belong to you."),None,parent=self,object_name="not_my_filter") return dao.filters_dao.delete_by_id(fq_id,user_session.user_id) self.filter_name.reload() self.filter_name.preselect(None) except Exception as e: mainlog.error("Can't delete fq_id = {}".format(fq_id)) showErrorBox(_("There was a problem while deleting the filter."),None,e,object_name="delete_filter_fatal") self.filter_name.reload() self.filter_name.preselect(None)
def _apply_filter(self, filter_text): mainlog.debug(u"_apply_filter : {}".format(filter_text)) parts = [] len_check = False if " " in filter_text.strip(): # More than one word in the filter => I assume it's the full # fledged filtering check = check_parse(filter_text) if check == True: parts = supply_order_service.find_parts_expression_filter( filter_text) len_check = True else: showErrorBox(_("Error in the filter !"), check, object_name="filter_is_wrong") elif filter_text: parts = supply_order_service.find_parts_filtered(filter_text) len_check = True else: parts = supply_order_service.find_recent_parts() len_check = False if len_check and len(parts) >= supply_order_service.MAX_RESULTS: showWarningBox( _("Too many results"), _("The query you've given brought back too many results. Only a part of them is displayed. Consider refining your query" )) self._fill_model(parts) self.search_results_view.setFocus(Qt.OtherFocusReason)
def delete_object(self, o_id): if not dao.operation_definition_dao.is_used(o_id): return super(EditOperationDefinitionsDialog, self).delete_object(o_id) else: showErrorBox(_("Operation definition already in use !"), "") return False
def _add_file(self, full_path_client): """ Adds a file to the templates. First it is uploaded and then it is added to the list of files. """ if self._test_file_access(full_path_client): progress_bar = make_progress(_("Uploading"), 100) def progress_tracker(percent): progress_bar.setValue(int(percent)) try: doc_id = upload_template(full_path_client, progress_tracker, 0) except Exception as exc: progress_bar.close() showErrorBox(_( "There was a problem while uploading the file {} to the server" ).format(os.path.basename(full_path_client)), ex=exc, object_name="file_upload_error") return self.refresh_templates_list()
def delete(self): if self.current_supply_order_id: s = _("About to delete order {}").format(self.accounting_label) if confirmationBox(s, _("Are you sure ?")): try: supply_order_service.deactivate( self.current_supply_order_id) except Exception as ex: showErrorBox("I could not delete the order", ex=ex) return rep = supply_order_service.find_last_order_id( self.current_supplier.supplier_id) if rep: self.edit(rep) else: self.edit_new(self.current_supplier) else: showErrorBox( _("No order or non-saved order selected"), _("You can only delete an order that has already been saved"), object_name="delete_only_saved_order") return
def accept(self): try: dao.delivery_slip_part_dao.delete_last(self.last_id) super(DeleteLastDeliverySlipDialog,self).accept() except DataException as ex: showErrorBox(_("Unable to delete the last delivery slip"), str(ex)) super(DeleteLastDeliverySlipDialog,self).reject()
def delete_remote_clicked(self, button_id): doc_id = self.button_data[button_id] doc = self.model.locate_object(lambda obj: obj.document_id == doc_id) if confirmationBox( _("Deleting a document"), _("Are you sure you want to remove {}").format(doc.filename)): try: self.model.delete_document(doc) except Exception as ex: showErrorBox(_("There was an error while deleting a document"), ex=ex)
def _add_edit_order_tab_if_necessary(self,order): chrono_start() h = (order.customer_id, order.order_id) mainlog.debug("New edit order panel : hash {}".format(h)) chrono_click("_add_edit_order_tab_if_necessary : 0") p = self.stack.has_panel(EditOrderPartsWidget,h) chrono_click("_add_edit_order_tab_if_necessary : 1") if not p: chrono_click("_add_edit_order_tab_if_necessary : 2") try: p = self._make_edit_order_parts_widget() except Exception as ex: mainlog.exception(ex) showErrorBox(_("Unable to show the order"),ex=ex) return chrono_click("_add_edit_order_tab_if_necessary : 3") p.reset_order(order.order_id, overwrite=True) chrono_click("_add_edit_order_tab_if_necessary : 4") self.stack.add_panel(p) # Add or make it visible chrono_click("_add_edit_order_tab_if_necessary : done") return p # edit_order_parts_widget = self.stack.add_panel_if_necessary(EditOrderPartsWidget,order.order_id) # if w.current_order_id != order.order_id: # edit_order_parts_widget.reset_order(order.order_id) # i = 0 # edit_order_parts_widget = None # while True: # w = self.stack.widget(i) # if w and isinstance(w, EditOrderPartsWidget) and w.current_order_id == order.order_id: # edit_order_parts_widget = w # break # elif not w: # break # else: # i = i + 1 # if not edit_order_parts_widget: # edit_order_parts_widget = self._make_edit_order_parts_widget() # edit_order_parts_widget.reset_order(order.order_id) # else: # self.stack.add_panel(edit_order_parts_widget) return edit_order_parts_widget
def open_clicked(self, button_id): filepath = self._download_on_button_id(button_id, None) if filepath: try: if sys.platform.startswith('darwin'): subprocess.call(('open', filepath)) elif os.name == 'nt': os.startfile(filepath) elif os.name == 'posix': subprocess.call(('xdg-open', filepath)) except Exception as ex: showErrorBox(_("Can't open file"), _("I'm unable to open the file"), ex)
def save(self): if self.model_data_changed: focused_widget = QApplication.focusWidget() if isinstance(focused_widget, QLineEdit) and focused_widget.parent() != self: focused_widget.clearFocus() focused_widget = QApplication.focusWidget() validation_results = self._validate() if validation_results != True: showErrorBox(_("The data are not correct"), "<br>-" + "<br>-".join(validation_results)) return False mainlog.debug("save : supplier_id : {}".format( self.current_supplier.supplier_id)) obj = blank_dto(SupplyOrder) obj.supply_order_id = self.current_supply_order_id obj.creation_date = date.today() obj.description = self.edit_comment_widget.toPlainText() obj.supplier_id = self.current_supplier.supplier_id obj.expected_delivery_date = self.delivery_date_widget.value() obj.supplier_reference = self.supplier_reference_widget.text() obj.accounting_label = self.accounting_label def factory(): return blank_dto(SupplyOrderPart) parts_actions = self.model.model_to_objects(factory) try: mainlog.debug("Saving") self.current_supply_order_id = supply_order_service.save( obj, parts_actions) # Reload the data self.reload() mainlog.debug("Emitting change signal") self.supply_order_saved.emit() # self.current_supply_order_id) except Exception as ex: showErrorBox( _("Error while saving"), _("There was an unexpected error while saving your data"), ex, object_name="saveError") if focused_widget: focused_widget.setFocus(Qt.OtherFocusReason)
def save_filter_as_action_slot(self): d = GiveNewNameDialog(self) d.exec_() if d.result() == QDialog.Accepted: new_name = d.line_edit.text() if not dao.filters_dao.is_name_used(new_name, user_session.user_id, self._filter_family): fq = dao.filters_dao.get_dto(None) if self._populate_dto(fq): fq.name = new_name fq_id = dao.filters_dao.save(fq) self.filter_name.reload() self._show_filter(fq) self.filter_name.preselect(fq_id, emit_selection_signal=False) else: showErrorBox(_("There is already a filter with that name. You must delete it first if you want to use that name."),None,None,object_name="filter_with_same_name")
def add_template_dialog(self): dialog = TemplateSelectDialog(None) dialog.refresh_templates_list() dialog.exec_() if dialog.template_id: try: for tpl_id in dialog.template_id: doc_id = instanciate_template(tpl_id) doc = self.documents_service.find_by_id(doc_id) self._add_one_document(doc.filename, doc.document_id, doc.file_size, doc.description) self._mark_changed() except Exception as exc: showErrorBox(_( "There was a problem while uploading the template to the server" ), ex=exc, object_name="template_upload_error")
def _test_file_access(self, full_path_client): import os.path file_size = 0 # Test the file access try: t = open(full_path_client, 'rb') t.close() file_size = os.path.getsize(full_path_client) if file_size == 0: raise Exception(_("The file is empty")) return True except Exception as exc: showErrorBox(_("Can't open the file located at {}").format( full_path_client), ex=exc, object_name="drag_drop_error") return False
def delete_remote_clicked(self, button_id): doc_id = self.button_data[button_id] doc = self.model.locate_object(lambda obj: obj.document_id == doc_id) if doc.reference and \ not confirmationBox(_("Confirmation for deleting reference template"), _("You're about to delete a reference template document. These documents are used by some parts of this program. Deleting them will break those parts. So you should immediately upload another template with the same reference. OK to proceed ?")): return elif not confirmationBox( _("Deleting a template"), _("Are you sure you want to remove {}").format(doc.filename)): return try: self.model.delete_document(doc) self._apply_pending_changes() except Exception as ex: showErrorBox(_("There was an error while deleting a document"), ex=ex)
def _replace_file(self, full_path_client, document): if self._test_file_access(full_path_client): progress_bar = make_progress(_("Replacing"), 100) def progress_tracker(percent): progress_bar.setValue(int(percent)) try: doc_id = upload_template(full_path_client, progress_tracker, document.document_id) self.refresh_templates_list() except Exception as exc: progress_bar.close() showErrorBox(_( "There was a problem while uploading the file to the server" ), ex=exc, object_name="file_upload_error") return
def accepted(self): parser = SimpleDateParser() cost = 0 try: cost = float(self.hourly_cost.text()) except ValueError as ex: showErrorBox(_("The given cost is not valid"), _("The given cost doesn't look like a cost")) return False d = parser.parse(self.date_edit.text()) if not d: showErrorBox(_("The given date is not valid"), _("Please check the syntax and that the date exists")) return False # elif d <= self.periods[-1].start_date: # showErrorBox(_("The given date is not valid"), # _("The given date is before or equal to the current last date ({}). It must be after.").\ # format(self.base_opdef.periods[-1].start_date)) # FIXME Use proper date formatter # return False else: return super(AddPeriodDialog, self).accept()
def apply_filter_slot(self, filter_string): if filter_string: try: self.slip_data = dao.delivery_slip_part_dao.load_slip_parts_on_filter(filter_string) except DataException as de: if de.code == DataException.CRITERIA_IS_EMPTY: showErrorBox(_("Error in the filter !"),_("The filter can't be empty"),object_name="filter_is_empty") elif de.code == DataException.CRITERIA_IS_TOO_SHORT: showErrorBox(_("Error in the filter !"),_("The filter is too short"),object_name="filter_is_too_short") elif de.code == DataException.CRITERIA_IS_TOO_LONG: showErrorBox(_("Error in the filter !"),_("The filter is too long"),object_name="filter_is_too_long") return else: self.slip_data = dao.delivery_slip_part_dao.find_recent2(1000) self.refresh_action()
def _validate_and_save(self, form_data): """ Returns saved object's id or False is save could not be completed (either because there are errors in the validation or because there are other technical errors). """ errors = dict() for p in self.form_prototype: data = form_data[p.field] if p.is_editable: v = p.validate(data) if v != True: errors[p.title] = v if len(errors) > 0: info_text = "" for field,error in errors.items(): info_text += u"<li>{}</li>".format(error) showErrorBox(_("Some of the data you encoded is not right"),u"<ul>{}</ul>".format(info_text)) return False # check = self.check_before_save(self.current_item) check = True if check == True: try: return self.save_object(form_data) except Exception as e: showErrorBox(_("There was an error while saving"),str(e),e) return False else: showErrorBox(_("There was an error while saving"),check) return False
def find_by_text(self,text): text = text.strip() try: too_many_results, res = dao.order_part_dao.find_ids_by_text(text.strip()) if too_many_results: showWarningBox(_("Too many results"),_("The query you've given brought back too many results. Only a part of them is displayed. Consider refining your query"),object_name="too_many_results") return dao.order_part_dao.find_by_ids(res) except DataException as de: if de.code == DataException.CRITERIA_IS_EMPTY: showErrorBox(_("Error in the filter !"), _("The filter can't be empty"),object_name="filter_is_empty") elif de.code == DataException.CRITERIA_IS_TOO_SHORT: showErrorBox(_("Error in the filter !"), _("The filter is too short"),object_name="filter_is_too_short") elif de.code == DataException.CRITERIA_IS_TOO_LONG: showErrorBox(_("Error in the filter !"), _("The filter is too long"),object_name="filter_is_too_long") return []
splash = QSplashScreen(pixmap) splash.setMask(pixmap.mask()) # splash.setWindowFlags(Qt.WindowStaysOnTopHint) splash.show() splash_msg( u"{} - ".format(configuration.this_version) + _("Contacting updates server")) splash_msg( _("Loading database URL")) try: configuration.load_database_param() except Exception as e: mainlog.error(e) mainlog.error( "I was unable to get the DB URL from the server {}, so I'll continue with the file configuration".format( configuration.database_url_source)) showErrorBox( _("Can't connect to the main server"), _("I was unable to contact the main server (located here : {}). It is not 100% necessary to do so but that's not normal either. You should tell your administrator about that. I will now allow you to change the network address of the server I know in the preferences panel.").format( configuration.database_url_source)) splash.repaint() from datetime import datetime from PySide.QtCore import * from PySide.QtGui import * # from PySide.QtGui import QDesktopServices # from PySide.QtCore import QUrl # from PySide.QtTest import QTest from koi.tools.chrono import * from koi.datalayer.sqla_mapping_base import metadata from koi.datalayer.database_session import init_db_session,session
def make_delivery_slip(self): global dao t = self.controller_part.model # mainlog.debug(u"make_delivery_slip() {}".format(t.objects)) # Extract the quantities to get out from the order part table parts_ids_quantities = dict() info = u"" for i in range(t.rowCount()): qty = t.data( t.index(i,self.qty_out_column), Qt.UserRole) or 0 order_part = t.objects[i] mainlog.debug("Line {} qty = {}, order part={} ".format(i,qty, order_part is not None)) if order_part and qty > 0: if order_part.order_part_id not in parts_ids_quantities: parts_ids_quantities[order_part.order_part_id] = 0 parts_ids_quantities[order_part.order_part_id] += qty info = info + ("<li>" + _("For {} {}, quantity {}")\ + "</li>").format(t.data( t.index(i,0), Qt.UserRole), t.data( t.index(i,1), Qt.UserRole), qty) info = u"<ul>{}</ul>".format(info) mainlog.debug("edit_dialog : checking for missing quantities") if len(parts_ids_quantities) == 0: showWarningBox(_("You requested to create a new delivery slip. However, you didn't encode any quantities"),None,None,"quantity_missing") return False mainlog.debug("edit_dialog : checking for quantities") if self._check_for_quantities_too_big(): showErrorBox(_("One quantity is too big"), _("Pay attention ! On some parts, you gave a quantity out that will make the total quantity out bigger than what was ordered. You must either change the quantity out or change the planned quantity."),None,"quantityTooBig") return False if self._check_unpriced_part(): showWarningBox(_("Some of the parts you want to make a delivery slip for have a null sell price. This is not an error but you may want to double check that situation."),None,None,"unpriced_part") mainlog.debug("edit_dialog : confirmationBox to be opened order_id is {}".format(self.order_id)) if confirmationBox(u"<font color='red'><b>{}</b></font>".format(_("<b>You're about to make a new delivery slip. This can't be reversed, please confirm.\n Here are the quantities you're going to record")),info,"confirmDSCreation"): mainlog.debug("confirmationBox was OK") try: self.slip_id = dao.delivery_slip_part_dao.make_delivery_slip_for_order( self.order_id, parts_ids_quantities, datetime.now(), self.close_order_checkbox.checkState() == Qt.Checked) mainlog.debug("A delivery slip was created {}".format(self.slip_id)) return True except Exception as ex: showErrorBox(_("Error while creating the delivery slip"), _("The delivery slip was not created due to an unexpected error."),ex) return False
def print_supply_order(self): if self._save_if_necessary(): try: print_supply_order(self.current_supply_order_id) except Exception as e: showErrorBox(str(e))
def database_operational_error(ex): showErrorBox(_("There was a serious problem while accessing the database"), _("This problem might require you to contact your local administrator"), ex)