Пример #1
0
def transaction_recode(o):
    t = recurse_encode(o)

    for row in t['one_to_two']:
        row['contenttype'] = ndb.Key(
            "Product", row['product'],
            parent=TypeGroup.product_ancestor()).get().contenttype
        row['id'] = row['product']
        del row['value']
        del row['product']
        del row['modamounts']

    for i, row in enumerate(t['two_to_one']):
        row['contenttype'] = ndb.Key(
            "Product", row['product'],
            parent=TypeGroup.product_ancestor()).get().contenttype
        row['id'] = row['product']
        row['price'] = without_mod_values(o.two_to_one[i])
        del row['value']
        del row['product']
        del row['modamounts']

    for row in t['services']:
        row['contenttype'] = row['service']
        row['price'] = row['value']
        del row['value']
        del row['service']

    return t
Пример #2
0
def edituser(user_id):
    form = request.json or request.form

    user = Key("User", user_id, parent=TypeGroup.relation_ancestor()).get()

    if request.method == "POST":
        user.username = form.get('username', user.username)

        if 'password' in form:
            update_password(user, form['password'])

        if 'relation' in form:
            rel = Key("Relation", int(form['relation']), ancestor=TypeGroup.relation_ancestor())
            if rel.get() is None:
                abort(400)
            user.relation = rel

        user.right_admin = form.get('is_admin', user.right_admin)
        user.right_viewstock = form.get('viewstock', user.right_viewstock)
        user.right_viewalltransactions = form.get('viewtransactions', user.right_viewalltransactions)
        user.right_posaction = form.get('posaction', user.right_posaction)

        user.put()
        return jsonify(user)

    return render_template('tantalus_user.html', user=user, relations=Relation.query().fetch())
Пример #3
0
def editposproduct(posproduct_id):
    form = request.json

    pos = Key("PosProduct", posproduct_id,
              parent=TypeGroup.product_ancestor()).get()

    if pos is None:
        return abort(404)

    if request.method == "POST":
        try:
            if "product" in form:
                pos.product = Key("Product",
                                  form['product'],
                                  parent=TypeGroup.product_ancestor())
                prd = pos.product.get()
                if prd is None:
                    raise BadValueError("Product does not exist.")
                pos.name = prd.contenttype
            elif 'name' in form:
                if len(form['name']) < 1:
                    raise BadValueError("Name too short!")
                pos.name = form['name']
                pos.product = None
            pos.price = form.get('price', pos.price)
            pos.scan_id = form.get('scan_id', pos.scan_id)
            pos.keycode = form.get('keycode', pos.keycode)
            pos.put()
        except BadValueError as e:
            return jsonify({"messages": [e.message]}, 400)
        return jsonify(pos)

    return render_template('tantalus_posproduct.html', pos=pos)
Пример #4
0
def showrelation(relation_id, page):
    if page < 0:
        page = 0

    pagination = Paginator(
        Transaction.query(
            Transaction.relation == Key('Relation', relation_id, parent=TypeGroup.relation_ancestor())).order(
            -Transaction.reference), page, 20,
        relation_id=relation_id)
    return render_template('tantalus_transactions.html',
                           relation=Key('Relation', relation_id, parent=TypeGroup.relation_ancestor()).get(),
                           pagination=pagination)
Пример #5
0
def editproduct(product_id):
    form = request.json

    product = Key("Product", product_id, parent=TypeGroup.product_ancestor()).get()

    if product is None:
        return abort(404)

    if request.method == "POST":
        if 'group' in form:
            group = Group.query(Group.name == form.get('group')).fetch(1)
            if len(group) == 0:
                if form.get('group', '') != '':
                    group = Group(name=form['group'])
                    group.put()
                else:
                    return abort(400)
            else:
                group = group[0]
        else:
            group = product.group.get()

        try:
            losemods = product.losemods
            if 'losemods' in form:
                losemods = [Key("Mod", id, parent=TypeGroup.product_ancestor()) for id in form.get('losemods')]
            for mod in losemods:
                if mod.get() is None:
                    raise BadValueError("Mod {} does not exists.".format(mod))

            gainmods = product.gainmods
            if 'gainmods' in form:
                gainmods = [Key("Mod", id, parent=TypeGroup.product_ancestor()) for id in form.get('gainmods')]
            for mod in gainmods:
                if mod.get() is None:
                    raise BadValueError("Mod {} does not exists.".format(mod))

            product.contenttype = form.get('name', form.get('contenttype', product.contenttype))
            product.tag = form.get('tag', '')
            product.group = group.key
            product.amount = form.get('amount', product.amount)
            product.value = form.get('value', product.value)
            product.losemods = losemods
            product.gainmods = gainmods
            product.put()
        except BadValueError as e:
            return jsonify({"messages": [e.message]}, 400)
        return jsonify(product)

    return render_template('tantalus_product.html', product=product, mods=Mod.query().fetch())
Пример #6
0
def showtransaction(transaction_id):
    transaction = Key("Transaction", transaction_id, parent=TypeGroup.transaction_ancestor()).get()

    if transaction is None:
        return abort(404)

    return render_template('tantalus_transaction_viewer.html', **transaction_record(transaction))
Пример #7
0
def addtransaction():
    form = request.json
    ref = None

    if request.method == "POST":
        try:
            relation_key = Key("Relation", int(form['relation']), parent=TypeGroup.relation_ancestor())
            relation = relation_key.get()
            if relation is None:
                raise BadValueError("Relation does not exist!")
            transaction = new_transaction(form)
            add_to_budget(relation_key, -transaction.total)

            taskqueue.add(url='/invoice',
                          target='worker',
                          params={'transaction': transaction.key.id()})

        except BadValueError as e:
            if ref is not None:  # free number of transaction
                ref.key.delete()
            return jsonify({"messages": [e.message]}, 400)
        return jsonify(transaction)

    return render_template('tantalus_transaction.html',
                           products=Product.query(Product.hidden == False).fetch(),
                           mods=Mod.query().fetch(),
                           relations=Relation.query().fetch())
Пример #8
0
def edittransaction(transaction_id):
    form = request.json

    transaction = Key("Transaction", transaction_id, parent=TypeGroup.transaction_ancestor()).get()

    if transaction is None:
        return abort(404)

    if request.method == "POST":
        try:
            old_total = transaction.total
            transaction = edit_transaction(transaction, form)
            add_to_budget(transaction.relation, old_total - transaction.total)

            taskqueue.add(url='/invoice',
                          target='worker',
                          params={'transaction': transaction.key.id()})
        except BadValueError as e:
            return jsonify({"messages": [e.message]}, 400)
        return jsonify(transaction)

    return render_template('tantalus_transaction.html', transaction=transaction,
                           products=Product.query(Product.hidden == False).fetch(),
                           mods=Mod.query().fetch(),
                           relations=Relation.query().fetch())
Пример #9
0
def addposproduct():
    form = request.json

    if request.method == "POST":
        try:
            pos = PosProduct(price=form["price"],
                             scan_id=form.get("scan_id", ""),
                             keycode=form.get("keycode", ""))

            if 'product' in form:
                prd = Key("Product",
                          form['product'],
                          parent=TypeGroup.product_ancestor()).get()
                if prd is None:
                    raise BadValueError("Product does not exist.")
                pos.product = prd.key
                pos.name = prd.contenttype
            elif 'name' in form:
                if len(form['name']) < 1:
                    raise BadValueError("Name too short!")
                pos.name = form['name']
            else:
                raise BadValueError("Need to specify either product or name!")
            pos.put()
        except (BadValueError, KeyError) as e:
            return jsonify({"messages": [e.message]}, 400)
        return jsonify(pos)

    return render_template(
        'tantalus_posproduct.html',
        products=Product.query(Product.hidden == False).order(
            Product.contenttype).fetch())
Пример #10
0
def editmod(mod_id):
    form = request.json

    mod = Key("Mod", mod_id, parent=TypeGroup.product_ancestor()).get()
    if mod is None:
        abort(404)

    if request.method == "POST":
        try:
            mod.name = form.get('name', mod.name)
            mod.tag = form.get('tag', mod.tag)
            mod.description = form.get('description', mod.description)
            mod.pre_add = form.get('pre_add', mod.pre_add)
            mod.multiplier = form.get('multiplier', mod.multiplier)
            mod.post_add = form.get('post_add', mod.post_add)
            mod.modifies = form.get('modifies', mod.modifies)
            mod.divides = form.get('divides', mod.divides)
            mod.rounding = form.get('rounding', mod.rounding)
        except:
            return jsonify({"messsages": ["Improper datafields"]}, 402)

        try:
            mod.put()
        except BadValueError as e:
            return jsonify({"messages": [e.message]}, 400)
        return jsonify(mod)

    return render_template('tantalus_mod.html', mod=mod)
Пример #11
0
    def tricky_stuff():
        for prd in data["sell"]:
            product = Key('Product',
                          int(prd['id']),
                          parent=TypeGroup.product_ancestor()).get()
            if product is None:
                raise OperationError(
                    "Product with id {} does not exist.".format(product))
            line = product.take(int(prd['amount']))
            product.put()

            for mod in prd["mods"]:
                mod_obj = Key('Mod',
                              int(mod),
                              parent=TypeGroup.product_ancestor()).get()
                if mod_obj is None:
                    raise OperationError(
                        "Mod with id {} does not exist.".format(mod))
                mod_obj.apply(line)

            t.one_to_two.append(line)

        for prd in data["buy"]:
            product = Key('Product',
                          int(prd['id']),
                          parent=TypeGroup.product_ancestor()).get()
            if product is None:
                raise OperationError(
                    "Product with id {} does not exist.".format(product))
            line = TransactionLine(product=product.key,
                                   amount=int(prd['amount']),
                                   value=int(prd['price']))

            for mod in prd["mods"]:
                mod_obj = Key('Mod',
                              int(mod),
                              parent=TypeGroup.product_ancestor()).get()
                if mod_obj is None:
                    raise OperationError(
                        "Mod with id {} does not exist.".format(mod))
                mod_obj.apply(line)

            product.give(line)
            product.put()
            t.two_to_one.append(line)
Пример #12
0
def addproduct():
    form = request.json

    if request.method == "POST":
        group = Group.query(Group.name == form['group']).fetch(1)
        if len(group) == 0:
            if form.get('group', '') != '':
                group = Group(name=form['group'])
                group.put()
            else:
                return abort(403)
        else:
            group = group[0]

        try:
            name = form.get('name') or form.get('contenttype')
            if len(Product.query(Product.contenttype == name).fetch()):
                raise BadValueError("A product with this name already exists.")

            losemods = [Key("Mod", id, parent=TypeGroup.product_ancestor()) for id in (form.get('losemods') or [])]
            for mod in losemods:
                if mod.get() is None:
                    raise BadValueError("Mod {} does not exists.".format(mod))

            gainmods = [Key("Mod", id, parent=TypeGroup.product_ancestor()) for id in (form.get('gainmods') or [])]
            for mod in gainmods:
                if mod.get() is None:
                    raise BadValueError("Mod {} does not exists.".format(mod))

            product = Product(
                contenttype=name,
                tag=form.get('tag', ''),
                group=group.key,
                amount=form.get('amount', 0),
                value=form.get('value', 0),
                hidden=False,
                losemods=losemods,
                gainmods=gainmods
            ).put()
        except (BadValueError, KeyError) as e:
            return jsonify({"messages": [e.message]}, 400)
        return jsonify(product)

    return render_template('tantalus_product.html', mods=Mod.query().fetch())
Пример #13
0
def resend(transaction_id):
    transaction = Key("Transaction", transaction_id, parent=TypeGroup.transaction_ancestor()).get()

    if transaction is None:
        return abort(404)

    taskqueue.add(url='/invoice',
                  target='worker',
                  params={'transaction': transaction.key.id()})
    return redirect(url_for(".showtransaction", transaction_id=transaction_id))
Пример #14
0
def showgroup(group, page):
    if page < 0:
        page = 0

    pagination = Paginator(
        Product.query(Product.hidden == False and Product.group == Key('Group', group,
                                                                       parent=TypeGroup.product_ancestor())).order(
            Product.contenttype),
        page, 20, group=group)
    return render_template('tantalus_products.html', group=Key('Group', group, parent=TypeGroup.product_ancestor()).get().name, showgroup=False,
                           pagination=pagination)
Пример #15
0
 def decorated_function(*args, **kwargs):
     if not current_user.right_admin or current_user.right_viewalltransactions:
         transaction = ndb.Key(
             "Transaction",
             kwargs.get('transaction_id'),
             parent=TypeGroup.transaction_ancestor()).get()
         if transaction is None or not (current_user.relation is not None
                                        and current_user.relation
                                        == transaction.relation):
             flash.danger(
                 "Your user account is not allowed to perform this action.")
             return redirect('/')
     return f(*args, **kwargs)
Пример #16
0
def editrelation(relation_id):
    form = request.json or request.form

    relation = Key("Relation",
                   relation_id,
                   parent=TypeGroup.relation_ancestor()).get()

    if request.method == "POST":
        relation.name = form.get('name', relation.name)
        relation.email = form.get('email', relation.email)
        relation.budget = form.get('budget', relation.budget)
        relation.has_budget = form.get('has_budget', relation.has_budget)
        relation.send_mail = form.get('send_mail', relation.send_mail)
        relation.put()
        return jsonify(relation)

    return render_template('tantalus_relation.html', relation=relation)
Пример #17
0
def sell():
    sale = request.json
    if not sale:
        return jsonify({"messages": ["No JSON supplied."]}, 400)

    try:
        prd = Key("PosProduct",
                  sale["product"],
                  parent=TypeGroup.product_ancestor())
        if prd.get() is None:
            raise BadValueError("Product does not exist")

        possale = PosSale(user=current_user.key,
                          product=prd,
                          amount=sale.get('amount', 1))
        possale.put()
    except (BadValueError, KeyError) as e:
        return jsonify({"messages": [e.message]}, 400)
    return jsonify(possale)
Пример #18
0
    def post(self):
        transaction = ndb.Key("Transaction",
                              int(self.request.get('transaction')),
                              parent=TypeGroup.transaction_ancestor()).get()
        relation = transaction.relation.get()
        record = transaction_record(transaction)

        def get_budget():
            after = Transaction.query(
                Transaction.reference > transaction.reference,
                Transaction.relation == transaction.relation).fetch()
            return relation.budget + sum([t.total for t in after])

        if relation.has_budget:
            budget = get_budget()
        else:
            budget = None

        if relation.send_mail:
            pdf = make_invoice(record, budget)
            send_invoice(relation, transaction, pdf)
Пример #19
0
def new_user(username,
             password,
             isadmin=False,
             relation=None,
             viewstock=False,
             viewtransactions=False,
             ispos=False):
    user = User(username=username,
                passhash=hashf.hash(password),
                right_admin=isadmin,
                right_viewstock=viewstock,
                right_viewalltransactions=viewtransactions,
                right_posaction=ispos)

    if relation is not None:
        user.relation = ndb.Key("Relation",
                                relation,
                                parent=TypeGroup.relation_ancestor())
        if user.relation.get() is None:
            abort(400)

    return user
Пример #20
0
def showgroupjson(group):
    return jsonify(Product.query(Product.hidden == False and Product.group == Key('Group', group,
                                                                                  parent=TypeGroup.relation_ancestor())).fetch())
Пример #21
0
def edit_transaction(t, data):
    # Easy stuff first
    # Note, this does not take care of money in budgets, do outside! Something with transactional limitations...
    t.revision += 1

    if "deliverydate" in data:
        t.deliverydate = datetime.strptime(data["deliverydate"],
                                           "%Y-%m-%d").date()

    if "description" in data:
        t.description = data["description"]

    newsell = []
    for prd in data["sell"]:
        product = Key('Product',
                      int(prd['id']),
                      parent=TypeGroup.product_ancestor()).get()
        if product is None:
            raise OperationError(
                "Product with id {} does not exist.".format(product))

        line = TransactionLine(value=0,
                               amount=int(prd['amount']),
                               product=product.key)
        product.put()

        for mod in prd["mods"]:
            mod_obj = Key('Mod', int(mod),
                          parent=TypeGroup.product_ancestor()).get()
            if mod_obj is None:
                raise OperationError(
                    "Mod with id {} does not exist.".format(mod))
            line.mods.append(mod_obj.key)

        newsell.append(line)

    t.one_to_two = transform_collection(t.one_to_two, newsell, True)

    newbuy = []
    for prd in data["buy"]:
        product = Key('Product',
                      int(prd['id']),
                      parent=TypeGroup.product_ancestor()).get()
        if product is None:
            raise OperationError(
                "Product with id {} does not exist.".format(product))
        line = TransactionLine(product=product.key,
                               amount=int(prd['amount']),
                               value=int(prd['price']))

        for mod in prd["mods"]:
            mod_obj = Key('Mod', int(mod),
                          parent=TypeGroup.product_ancestor()).get()
            if mod_obj is None:
                raise OperationError(
                    "Mod with id {} does not exist.".format(mod))
            mod_obj.apply(line)

        newbuy.append(line)
    t.two_to_one = transform_collection(t.two_to_one, newbuy, False)

    t.services = []
    for prd in data["service"]:
        line = ServiceLine(service=prd['contenttype'],
                           amount=int(prd['amount']),
                           value=int(prd['price']))

        t.services.append(line)

    t.total = transaction_total(t)
    t.put()
    return t
Пример #22
0
def new_transaction(data, ):
    relation = Key('Relation',
                   int(data["relation"]),
                   parent=TypeGroup.relation_ancestor())
    if relation.get() is None:
        raise OperationError("Relation does not exist!")

    tr = Transaction.query(
        Transaction.relation == relation).order(-Transaction.reference).get()
    if tr is None:
        reference = 1
    else:
        reference = tr.reference + 1

    t = Transaction(revision=0,
                    reference=reference,
                    relation=relation,
                    deliverydate=datetime.strptime(data["deliverydate"],
                                                   "%Y-%m-%d").date(),
                    processeddate=datetime.now(
                        timezone("Europe/Amsterdam")).date(),
                    description=data.get("description", ""))

    @transactional(xg=True)
    def tricky_stuff():
        for prd in data["sell"]:
            product = Key('Product',
                          int(prd['id']),
                          parent=TypeGroup.product_ancestor()).get()
            if product is None:
                raise OperationError(
                    "Product with id {} does not exist.".format(product))
            line = product.take(int(prd['amount']))
            product.put()

            for mod in prd["mods"]:
                mod_obj = Key('Mod',
                              int(mod),
                              parent=TypeGroup.product_ancestor()).get()
                if mod_obj is None:
                    raise OperationError(
                        "Mod with id {} does not exist.".format(mod))
                mod_obj.apply(line)

            t.one_to_two.append(line)

        for prd in data["buy"]:
            product = Key('Product',
                          int(prd['id']),
                          parent=TypeGroup.product_ancestor()).get()
            if product is None:
                raise OperationError(
                    "Product with id {} does not exist.".format(product))
            line = TransactionLine(product=product.key,
                                   amount=int(prd['amount']),
                                   value=int(prd['price']))

            for mod in prd["mods"]:
                mod_obj = Key('Mod',
                              int(mod),
                              parent=TypeGroup.product_ancestor()).get()
                if mod_obj is None:
                    raise OperationError(
                        "Mod with id {} does not exist.".format(mod))
                mod_obj.apply(line)

            product.give(line)
            product.put()
            t.two_to_one.append(line)

    tricky_stuff()
    for prd in data["service"]:
        line = ServiceLine(service=prd['contenttype'],
                           amount=int(prd['amount']),
                           value=int(prd['price']))

        t.services.append(line)
    t.total = transaction_total(t)
    t.put()
    return t
Пример #23
0
def showrelationjson(relation):
    return jsonify(Transaction.query(
        Transaction.relation == Key('Relation', relation, parent=TypeGroup.relation_ancestor())).fetch())