def debug(collection, id): try: obj = current_app.mongo.db[collection].find_one(id) if obj is None: try: id = ObjectId(id) obj = current_app.mongo.db[collection].find_one_or_404(id) except: abort(404) obj = dumps(obj, indent=2) # transform to pretty JSON form = DebugForm(request.form, data=dict(document=obj)) if request.method == 'POST' and form.validate_on_submit(): try: new_obj = loads(form.document.data) result = current_app.mongo.db[collection].find_one_and_replace( filter={'_id': id}, replacement=new_obj ) if result: flash('data successfully updated', 'success') obj = current_app.mongo.db[collection].find_one_or_404(id) form.document.data = dumps(obj, indent=2) else: flash('data update failed', 'error') except Exception as e: flash(e, 'error') # show the form page extract_errors(form) return render_template('debug/debug_form.html', collection=collection, id=id, form=form, obj=obj) except Exception as e: return str(e) # always return something meaningful
def make_obsolete(partno): """ Marks the given component as obsolete. Precondition: The user must have the admin role and the item must not already be obsolete """ obj = _load_if_active(partno) form = ObsoleteForm(request.form) if request.method == 'POST' and form.validate_on_submit(): result = current_app.mongo.db.components.update_one( filter={'_id': partno}, update={ '$set': { 'obsolete': True }, '$push': { 'history': { 'date': datetime.now(), 'user': current_user.id, 'message': 'component obsoleted' } } } ) if result.modified_count == 1: flash('component obsoleted', 'success') else: # should not happen. flash('no data modified, please contact the administrator', 'error') return redirect(url_for('components.details', partno=partno)) extract_errors(form) return render_template('components/obsolete_form.html', data=obj, form=form)
def unrelease(partno): """ Un-releases the component when a POST form is submitted """ obj = _load_if_released(partno) form = UnReleaseForm(request.form) if request.method == 'POST' and form.validate_on_submit(): result = current_app.mongo.db.components.update_one( filter={'_id': partno}, update={ '$set': { 'released': False }, '$push': { 'history': { 'date': datetime.now(), 'user': current_user.id, 'message': 'un-released' } } } ) if result.modified_count == 1: flash('component un-released', 'success') else: # should not happen. flash('no data modified, please contact the administrator', 'error') return redirect(url_for('components.details', partno=partno)) extract_errors(form) return render_template('components/unrelease_form.html', data=obj, form=form)
def add(): """ Presents the form to add a new component, and adds it to the database if submitted """ form = ComponentForm(request.form) form.category.choices = _get_categories() # form submittal handling if request.method == 'POST' and form.validate_on_submit(): id = _create_new_partno() suppliers = _extract_suppliers(form) manufacturers = _extract_manufacturers(form) now = datetime.now() obj = dict(_id=id, name=form.name.data, description=form.description.data, category=form.category.data, suppliers=suppliers, manufacturers=manufacturers, revisions=[{'date': now, 'comment': form.comment.data}], released=False, obsolete=False, history=[{'date': now, 'user': current_user.id, 'message': 'created'}]) try: current_app.mongo.db.components.insert(obj) flash('component successfully created', 'success') return redirect(url_for('components.details', partno=id)) except DuplicateKeyError as e: flash('data insertion failed (%s), please contact the administrator' % e, 'error') extract_errors(form) return render_template('components/new_form.html', form=form, type=type)
def add(): """ Imports data from the uploaded file and updates the stock values including BOM results """ form = FileForm(request.form) # WTF is NOT used for the file handling, since the file upload handling seems broken. if request.method == 'POST' and form.validate_on_submit(): # show the validation page if a file is uploaded # else process the tmpname parameter if request.files.get('file'): try: save_to_tmp(form) success, headers, values = _import_file(extract_filepath(form)) # Also add the current quantity to the review list for item in values: current_quantity = 0 obj = current_app.mongo.db.stock.find_one(item.get('partno')) if obj: current_quantity = obj.get('quantity') item['current_quantity'] = current_quantity item['new_quantity'] = item.get('quantity') + current_quantity headers.append('current_quantity') headers.append('new_quantity') return render_template('stock/validate_form.html', form=form, headers=headers, data=values, title='Verify Input Data', action='Add to Stock') except Exception as e: flash(e, 'error') elif form.tmpname.data: success, headers, values = _import_file(extract_filepath(form)) if success: try: for v in values: partno = v.get('partno') quantity = v.get('quantity') batchname = v.get('batch') comment = v.get('comment', 'added to stock') update_counts(partno, quantity, batchname, comment) flash('stock import successful', 'success') return redirect(url_for('stock.overview')) except Exception as e: flash(e, 'error') return render_template('stock/validate_form.html', form=form, headers=headers, data=values, title='Verify Input Data', action='Add to Stock') extract_errors(form) return render_template('stock/import_form.html', form=form, title='Add Stock Items')
def correct(): """ Imports data from the uploaded file and corrects the corresponding stock values """ form = FileForm(request.form) warning = dict(category='warning', message='You are about to override the exising stock! Are you sure you want to continue?') # WTF is NOT used for the file handling, since the file upload handling seems broken. if request.method == 'POST' and form.validate_on_submit(): # show the validation page if a file is uploaded # else process the tmpname parameter if request.files.get('file'): try: save_to_tmp(form) success, headers, values = _import_file(extract_filepath(form)) for item in values: current_quantity = 0 obj = current_app.mongo.db.stock.find_one(item.get('partno')) if obj: current_quantity = obj.get('quantity') item['current_quantity'] = current_quantity headers.append('current_quantity') return render_template('stock/validate_form.html', form=form, headers=headers, data=values, title='Verify Correction Data', action='Apply Correction', warning=warning) except Exception as e: flash(e, 'error') elif form.tmpname.data: success, headers, values = _import_file(extract_filepath(form)) if success: try: for v in values: partno = v.get('partno') quantity = v.get('quantity') comment = v.get('comment', 'manual correction') correct_counts(partno, quantity, comment) flash('stock correction successful', 'success') return redirect(url_for('stock.overview')) except Exception as e: flash(e, 'error') return render_template('stock/validate_form.html', form=form, headers=headers, data=values, title='Verify Correction Data', action='Apply Correction', warning=warning) extract_errors(form) return render_template('stock/import_form.html', form=form, title='Correct Stock Items', warning=warning)
def add_comment(serial): current_app.mongo.db.items.find_one_or_404(serial) form = CommentForm(request.form) if request.method == 'POST' and form.validate_on_submit(): result = current_app.mongo.db.items.update_one( filter={'_id': serial}, update={'$push': {'comments': create_comment(form.message.data)}} ) if result.modified_count == 1: flash('comment successfully added', 'success') else: flash('comment adding failed, please contact the administrator', 'error') return redirect(url_for('items.details', serial=serial)) extract_errors(form) return render_template('items/comment_form.html', form=form, serial=serial)
def add_single(partno): """ Adds the given quantity to the stock """ obj = current_app.mongo.db.components.find_one_or_404(partno, projection=['name']) form = AddSingleForm(request.form) if request.method == 'POST' and form.validate_on_submit(): try: update_counts(partno, form.quantity.data, form.batch.data, 'added to stock') flash('Stock addition successful', 'success') return redirect(url_for('stock.details', partno=partno)) except Exception as e: flash('stock operation failed (%s), please contact the administrator' % e, 'error') extract_errors(form) name = obj.get('name') return render_template('stock/add_single.html', form=form, partno=partno, name=name)
def update_bom(): """ Imports data from the uploaded file and corrects the corresponding stock values """ form = FileForm(request.form) # WTF is NOT used for the file handling, since the file upload handling seems broken. if request.method == 'POST' and form.validate_on_submit(): # show the validation page if a file is uploaded # else process the tmpname parameter if request.files.get('file'): # a file was uploaded try: save_to_tmp(form) success, headers, values = _import_file(extract_filepath(form)) target_partno = 'unknown' if len(values) > 0: target_partno = values.pop(0).get('partno') return render_template('stock/validate_form.html', form=form, headers=headers, data=values, title='Verify BOM Data for '+target_partno, action='Update BOM') except Exception as e: flash(e, 'error') elif form.tmpname.data: success, headers, values = _import_file(extract_filepath(form)) target_partno = 'unknown' if len(values) > 0: target_partno = values.pop(0).get('partno') if success: try: set_bom(target_partno, values) flash('BOM update successful', 'success') return redirect(url_for('stock.overview')) except Exception as e: flash(e, 'error') return render_template('stock/validate_form.html', form=form, headers=headers, data=values, title='Verify BOM Data for '+target_partno, action='Update BOM') extract_errors(form) return render_template('stock/import_form.html', form=form, title='Update BOM')
def fileupload(partno): """ Presents the form to upload a new file for the design item. Stores the uploaded file in the correct location upon POST submit """ # the part number must be valid try: pn = PartNumber(partno) except ValueError: abort(404) # the revision must be specified if pn.revision is None: abort(404) # check the data obj = _load_if_unreleased(pn.base_number) # ensure the desired revision exists num_revisions = len(obj.get('revisions', list())) if pn.revision_number >= num_revisions: abort(404) pn.set_num_revisions(num_revisions) if pn.is_outdated(): flash('cannot upload files to outdated revisions', 'error') return redirect(url_for('components.details', partno=partno)) form = UploadForm(request.form) # WTF is NOT used for the file handling, since the file upload handling seems broken. file = request.files.get('file') if request.method == 'POST' and form.validate_on_submit() and file: try: filename = secure_filename(file.filename) dir = os.path.join(current_app.config['LPM_COMPONENT_FILES_DIR'], partno) if not os.path.exists(dir): os.makedirs(dir) path = os.path.join(dir, filename) file.save(path) flash('file successfully uploaded', 'success') return redirect(url_for('components.details', partno=partno)) except Exception as e: flash(e, 'error') extract_errors(form) return render_template('components/upload_form.html', form=form, partno=partno)
def change_status(serial, status=''): """ Changes the status of the given item to the specified value """ form = StatusForm(request.form) item = current_app.mongo.db.items.find_one_or_404(serial, projection=['partno', 'status']) if request.method == 'POST' and form.validate_on_submit(): try: do_update_status(item, form.status.data, form.project.data, form.comment.data) flash('status successfully updated', 'success') return redirect(url_for('items.details', serial=serial)) except Exception as e: flash(e, 'error') extract_errors(form) if status is not None: form.status.data=status return render_template('items/status_form.html', serial=serial, item=item, form=form)
def correct_single(partno): """ Corrects the stock and sets the new quantity """ component = current_app.mongo.db.components.find_one_or_404(partno, projection=['name']) form = CorrectSingleForm(request.form) if request.method == 'POST' and form.validate_on_submit(): try: message = 'stock correction' if form.comment.data: message += ' (%s)' % form.comment.data correct_counts(partno, form.quantity.data, message) flash('Stock correction successful', 'success') return redirect(url_for('stock.details', partno=partno)) except Exception as e: flash('stock operation failed (%s), please contact the administrator' % e, 'error') extract_errors(form) name = component.get('name') obj = current_app.mongo.db.stock.find_one(partno) current_quantity = obj.get('quantity') if obj is not None else 0 return render_template('stock/correct_single.html', form=form, partno=partno, name=name, current_quantity=current_quantity)
def import_items(): form = FileForm(request.form) # WTF is NOT used for the file handling, since the file upload handling seems broken. if request.method == 'POST' and form.validate_on_submit(): # show the validation page if a file is uploaded # else process the tmpname parameter if request.files.get('file'): # a file was uploaded try: save_to_tmp(form) success, headers, values = _import_file(extract_filepath(form)) return render_template('items/validate_form.html', title='Verify Item Data', form=form, headers=headers, data=values) except Exception as e: flash(e, 'error') elif form.tmpname.data: # re-run the data import and insert items into the database success, headers, values = _import_file(extract_filepath(form)) if success: try: _store_items(values) flash('item import successful', 'success') return redirect(url_for('items.overview')) except Exception as e: flash(e, 'error') return render_template('items/validate_form.html', title='Verify Item Data', form=form, headers=headers, data=values) extract_errors(form) return render_template('items/import_form.html', title='Import Items File', form=form)
def set_project(serial): """ Changes the project association of the given item to the specified value """ form = ProjectForm(request.form) current_app.mongo.db.items.find_one_or_404(serial) if request.method == 'POST' and form.validate_on_submit(): project = form.project.data comment = create_comment("[Auto] changed project association to '%s'" % project) result = current_app.mongo.db.items.update_one( filter={'_id': serial}, update={ '$set': {'project': project}, '$push': {'comments': comment} } ) if result.modified_count == 1: flash('project successfully set', 'success') else: flash('failed to set the project, please contact the administrator', 'error') return redirect(url_for('items.details', serial=serial)) extract_errors(form) return render_template('items/project_form.html', form=form, serial=serial)
def new_revision(partno): """ Presents the form to add a new revision, and creates it upon POST submit """ _load_if_released(partno) # ensures the component exists and is released form = RevisionForm(request.form) if request.method == 'POST' and form.validate_on_submit(): now = datetime.now() result = current_app.mongo.db.components.update_one( filter={'_id': partno}, update={ '$set': { 'released': False # a new revision is not already released }, '$push': { 'revisions': { 'date': now, 'comment': form.comment.data }, 'history': { 'date': now, 'user': current_user.id, 'message': 'new revision created' } } } ) if result.modified_count == 1: flash('new revision created', 'success') else: # should not happen. flash('no data modified, please contact the administrator', 'error') return redirect(url_for('components.details', partno=partno)) extract_errors(form) return render_template('components/revision_form.html', form=form, partno=partno)
def edit(partno): """ Presents the form to edit an already existing component """ obj = _load_if_unreleased(partno) # prepare the form data revisions = obj.get('revisions') suppliers = obj.get('suppliers', list()) manufacturers = obj.get('manufacturers', list()) revidx = len(revisions)-1 num_suppliers = len(suppliers) num_manufacturers = len(manufacturers) data = dict(name=obj.get('name'), description=obj.get('description'), category=obj.get('category'), comment=revisions[revidx].get('comment')) if num_suppliers > 0: data['supplier1'] = suppliers[0].get('name') data['supplier1part'] = suppliers[0].get('partno') if num_suppliers > 1: data['supplier2'] = suppliers[1].get('name') data['supplier2part'] = suppliers[1].get('partno') if num_manufacturers > 0: data['manufacturer1'] = manufacturers[0].get('name') data['manufacturer1part'] = manufacturers[0].get('partno') if num_manufacturers > 1: data['manufacturer2'] = manufacturers[1].get('name') data['manufacturer2part'] = manufacturers[1].get('partno') form = ComponentForm(request.form, data=data) form.category.choices = _get_categories() # form submittal handling # use $set for the updated fields, directly update the latest revision # add a comment in the history if request.method == 'POST' and form.validate_on_submit(): suppliers = _extract_suppliers(form) manufacturers = _extract_manufacturers(form) set_data = dict(name=form.name.data, description=form.description.data, category=form.category.data, suppliers=suppliers, manufacturers=manufacturers) set_data['revisions.'+str(revidx)+'.comment'] = form.comment.data result = current_app.mongo.db.components.update_one( filter={'_id': partno}, update={ '$set': set_data, '$push': { 'history': { 'date': datetime.now(), 'user': current_user.id, 'message': 'updated', } } } ) if result.modified_count == 1: flash('data successfully updated', 'success') else: # should not happen. If the ID is wrong, the initial lookup will fail flash('no data modified, please contact the administrator', 'error') return redirect(url_for('components.details', partno=partno)) extract_errors(form) return render_template('components/edit_form.html', form=form, partno=partno)