Example #1
0
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
Example #2
0
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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
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')
Example #6
0
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)
Example #7
0
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)
Example #8
0
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)
Example #9
0
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')
Example #10
0
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)
Example #11
0
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)
Example #12
0
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)
Example #13
0
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)
Example #14
0
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)
Example #15
0
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)
Example #16
0
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)