Ejemplo n.º 1
0
def process_file(database, fname):
    if PYT3:
        with open(fname, 'r', encoding='iso-8859-1') as f:
            data = f.read()
    else:
        with open(fname, 'r') as f:
            data = f.read()

    print('Processing file ', fname)

    interested_id = ObjectId()

    with CommitContext(database) as ctx:
        interested = 'import-bgcreport-%s' % interested_id
        op = CreateToi('accounting.BgcReport',
                       None,
                       attrData=dict(filename=[os.path.basename(fname)],
                                     multiline=[data]))
        ctx.runCommit([op], interested=interested)
        (toid, ), error = wait_for_commit(database, interested=interested)
        if error:
            raise error

    with CommitContext(database) as ctx:
        interested = 'process-bgc-report-{}', interested_id
        op = CallToi(toid, 'process_data', [])
        ctx.runCommit([op], interested=interested)
        _, error = wait_for_commit(database, interested=interested)
        if error:
            raise error
Ejemplo n.º 2
0
def ticket(ticket, random, product, sig1, sig2):
    if random is None:
        random = ticket & 0xffffffff
        ticket = ObjectId('%024x' % (ticket >> 32))

    accounting.templating.formatters.apply(current_app.jinja_env, 'datetime')

    autovoid = bool(json.loads(request.cookies.get('autovoid', 'false')) or
                    request.values.get('autovoid'))

    with ReadonlyContext(g.database) as ctx:
        ticket = blm.members.Ticket._query(id=ticket, random=random).run()
        if not ticket:
            resp = make_response(
                render_template('ticket.html', ticket=None,
                                canvoid=bool(g.user), autovoid=autovoid))
            resp.set_cookie('autovoid', json.dumps(autovoid), path='/ticket',
                            expires=time.time() + 24 * 3600)
            return resp

        ticket, = ticket

        if 'print' in request.values:
            return redirect(url_for('getTicket', ticket=ticket.id[0],
                                    random=base64long.encode(ticket.random[0])))

        canvoid = False
        voided = False
        if g.user:
            canvoid = ticket.canWrite(g.user, 'void')
            if canvoid:
                if 'unvoid' in request.values:
                    interested = 'ticket-unvoid-%s' % ObjectId()
                    with CommitContext(g.database, g.user) as ctx:
                        op = CallToi(ticket.id[0], 'unvoid', [])
                        ctx.runCommit([op], interested)
                    result, error = wait_for_commit(g.database, interested)
                    if error:
                        raise error
                elif autovoid or 'void' in request.values:
                    interested = 'ticket-void-%s' % ObjectId()
                    with CommitContext(g.database, g.user) as ctx:
                        op = CallToi(ticket.id[0], 'void', [])
                        ctx.runCommit([op], interested)
                    result, error = wait_for_commit(g.database, interested)
                    voided = result[0][0]
                    if error:
                        raise error

        resp = make_response(
            render_template(
                'ticket.html', ticket=ticket, canvoid=canvoid,
                autovoid=autovoid, voided=voided,
                ticket_url=url_for('ticket_simple', _external=True)
            )
        )
        resp.set_cookie('autovoid', json.dumps(autovoid), path='/ticket',
                        expires=time.time() + 24 * 3600)
        return resp
Ejemplo n.º 3
0
def poll(database, providerId, purchaseId, invoiceRef):
    client, context, seqr_protocol = get_client_and_context(providerId,
                                                            purchaseId,
                                                            database=database)
    response = call_method(client.service.getPaymentStatus, context,
                           invoiceRef)

    if response.resultCode == 0 and response.status == 'PAID':
        with CommitContext(database) as ctx:
            purchase, = blm.members.BasePurchase._query(id=purchaseId).run()
            op = CreateToi(
                'members.SeqrPayment', None,
                dict(paymentProvider=[providerId],
                     matchedPurchase=[purchase],
                     amount=[response.receipt.invoice.totalAmount.value],
                     paymentDate=[
                         datetime_to_epoch(response.receipt.paymentDate)
                     ],
                     invoiceReference=[response.receipt.invoiceReference],
                     ersReference=[response.ersReference],
                     paymentReference=[response.receipt.paymentReference],
                     payerTerminalId=[response.receipt.payerTerminalId],
                     receiverName=[
                         r for r in [response.receipt.receiverName] if r
                     ]))
            interested = 'seqr-%s' % ObjectId()
            commit = ctx.runCommit([op], interested=interested)

        result, error = wait_for_commit(database, interested=interested)
        if error:
            raise error

        receiptDoc = client.factory.create('ns0:receiptDocument')
        receiptDoc.mimeType = 'text/plain'
        receiptDoc.receiptData = ''
        receiptDoc.receiptType = ''

        receipt_response = call_method(client.service.submitPaymentReceipt,
                                       context, response.ersReference,
                                       receiptDoc)

        paymentId = result[0]

        with CommitContext(database) as ctx:
            op = CallToi(paymentId, 'sendConfirmationEmail', [])
            interested = 'send-seqr-payment-confirmation-%s' % ObjectId()
            commit = ctx.runCommit([op], interested=interested)
        result, error = wait_for_commit(database, interested=interested)
        if error:
            raise error

    return jsonify({
        'resultCode': response.resultCode,
        'status': response.status
    })
Ejemplo n.º 4
0
def process_file(database, fname):
    if PYT3:
        with open(fname, 'r', encoding='iso-8859-1') as f:
            data = f.read()
    else:
        with open(fname, 'r') as f:
            data = f.read()

    interested_id = ObjectId()

    with CommitContext(database) as ctx:
        interested = 'import-payment-%s' % interested_id
        op = CreateToi('members.PGPaymentFile',
                       None,
                       attrData=dict(fileName=[os.path.basename(fname)],
                                     data=[data]))
        ctx.runCommit([op], interested=interested)
        (toid, ), error = wait_for_commit(database, interested=interested)
        if error:
            raise error

    with CommitContext(database) as ctx:
        interested = 'process-payment-file-%s' % interested_id
        op = CallToi(toid, 'process', [])
        ctx.runCommit([op], interested=interested)
        _, error = wait_for_commit(database, interested=interested)
        if error:
            raise error

    with ReadonlyContext(database):
        for paymentFile in blm.members.PGPaymentFile._query(id=toid).run():
            for payment in paymentFile.payments:
                paymentId = payment.id[0]
                interested = 'match-payment-%s-%s' % (interested_id, paymentId)
                with CommitContext(database) as ctx:
                    op = CallToi(paymentId, 'match', [])
                    ctx.runCommit([op], interested)
                _, error = wait_for_commit(database, interested=interested)
                if error:
                    raise error

    with ReadonlyContext(database):
        for payment in blm.members.PGPayment._query(paymentFile=toid).run():
            paymentId = payment.id[0]
            interested = 'send-payment-confirmation-%s-%s' % (paymentId,
                                                              ObjectId())
            with CommitContext(database) as ctx:
                op = CallToi(paymentId, 'sendConfirmationEmail', [])
                ctx.runCommit([op], interested)
            _, error = wait_for_commit(database, interested=interested)
            if error:
                raise error

    archive_file(fname)
Ejemplo n.º 5
0
 def do_create(self, blmname, tocname, params):
     tocname = '%s.%s' % (blmname, tocname)
     toc = blm.getTocByFullname(tocname)
     interested = 'direct-create-%s' % ObjectId()
     with CommitContext(self.database, self.user) as ctx:
         createops = params[0]
         if isinstance(createops, dict):
             createops = [createops]
         ops = []
         for attrdata in createops:
             toid = list(filter(None,
                                attrdata.pop('id', []) + [ObjectId()]))[0]
             self._toidata_from_json(toc, attrdata)
             op = CreateToi(tocname, toid, attrdata)
             ops.append(op)
         ctx.runCommit(ops, interested=interested)
     with ReadonlyContext(self.database, self.user) as ctx:
         result, error = wait_for_commit(self.database, interested)
         if error:
             return {'success': False}
         for i, toid in enumerate(result):
             query = toc._query(id=toid)
             query.attrList = toc._attributes.keys()
             toi, = query.run()
             result[i] = self._get_toidata(toi, query.attrList)
         return {'success': True, 'tois': result}
Ejemplo n.º 6
0
    def do_update(self, blmname, tocname, params):
        tocname = '%s.%s' % (blmname, tocname)
        interested = 'direct-update-%s' % ObjectId()
        with CommitContext(self.database, self.user) as ctx:
            updateops = params[0]
            if isinstance(updateops, dict):
                updateops = [updateops]
            opdata = {}
            toc = blm.getTocByFullname(tocname)
            attrList = set()

            for attrdata in updateops:
                toid, = map(ObjectId, attrdata.pop('id'))
                self._toidata_from_json(toc, attrdata)
                opdata[toid] = attrdata
                attrList.update(attrdata)

            q = toc._query(id=[toid for toid in opdata])
            q.attrList = attrList
            ops = []
            for toi in q.run():
                op = ChangeToi(toi, opdata[toi.id[0]])
                ops.append(op)
            ctx.runCommit(ops, interested=interested)
        with ReadonlyContext(self.database, self.user) as ctx:
            result, error = wait_for_commit(self.database, interested)
            if error:
                return {'success': False, 'message': error}
            for i, (toid, sentdata) in enumerate(zip(result, updateops)):
                query = toc._query(id=toid)
                query.attrList = sentdata.keys()
                toi, = query.run()
                result[i] = self._get_toidata(toi, query.attrList)
            return {'success': True, 'tois': result}
Ejemplo n.º 7
0
def webhook():
    data = request.get_json()
    log.info('WEBHOOK: %r', data)
    if not 'user_id' in data:
        return '' # Nothing we know what to do with
    with ReadonlyContext(g.database) as ctx:
        provider = blm.accounting.StripeProvider._query(stripe_id = data['user_id']).run()
        if not provider:
            return ''
        org_ug = provider[0].org[0].ug[0]

    interested = 'stripe-%s-%s-%s' % (data['type'], data['id'], ObjectId())
    with CommitContext(g.database, org_ug) as ctx:  # Use organisations permissions
        op = []
        if data['type'] == 'invoice.created':
            op.append(CallBlm('members', 'handleStripeInvoice', [[data], provider]))
        elif data['type'] == 'charge.succeeded':
            op.append(CallBlm('members', 'handleStripeCharge', [[data], provider]))
        elif data['type'] == 'invoice.payment_succeeded':
            pass
        ctx.runCommit(op, interested)
    _, error = wait_for_commit(g.database, interested)
    if error:
        raise error

    return ''
Ejemplo n.º 8
0
def update_payment(token, database, purchase=None, provider=None):
    log.info('Payson update')

    with ReadonlyContext(database):
        if blm.members.PaysonPayment._query(token=token).run():
            log.info('Payment %s already registered, aborting.', token)
            return
        if not provider:
            purchase, = blm.members.Purchase._query(id=purchase,
                                                    _attrList=['org']).run()
            provider = blm.accounting.PaysonProvider._query(
                org=purchase.org).run()[0]

        api = payson.PaysonApi(provider.apiUserId[0], provider.apiPassword[0])

    payData = api.payment_details(token)

    if payData.status == 'COMPLETED':
        with CommitContext(database) as ctx:
            purchase, = blm.members.Purchase._query(
                id=payData.trackingId).run()
            op = CreateToi(
                'members.PaysonPayment', None,
                dict(paymentProvider=[provider],
                     matchedPurchase=[purchase],
                     amount=[payData.receiverList[0].amount],
                     purchaseId=[payData.purchaseId],
                     senderEmail=[payData.senderEmail],
                     token=[payData.token],
                     receiverFee=[payData.receiverFee],
                     receiverEmail=[payData.receiverList[0].email],
                     type=[payData.type]))
            interested = 'payson-%s' % ObjectId()
            commit = ctx.runCommit([op], interested=interested)

        result, error = wait_for_commit(database, interested=interested)
        if error:
            raise error
        paymentId = result[0]

        with CommitContext(database) as ctx:
            op = CallToi(paymentId, 'sendConfirmationEmail', [])
            interested = 'send-payson-payment-confirmation-%s' % ObjectId()
            commit = ctx.runCommit([op], interested=interested)
        result, error = wait_for_commit(database, interested=interested)
        if error:
            raise error
Ejemplo n.º 9
0
def jslink():
    import pytransact.link
    import accounting.jslink
    factory = pytransact.link.LinkFactory()
    jslink = accounting.jslink.JsLink(linkFactory=factory)
    with CommitContext(g.database, g.user):
        result = jslink.render(request)
    return result
Ejemplo n.º 10
0
def main():
    database = db.connect()
    interested = 'bootstrap-%s' % ObjectId()
    with CommitContext(database) as ctx:
        ctx.set_read_preference(pymongo.ReadPreference.PRIMARY)
        op = CallBlm('accounting', 'bootstrap', [])
        ctx.runCommit([op], interested=interested)
    result, error = wait_for_commit(database, interested)
    if error:
        raise error
Ejemplo n.º 11
0
def simulatePayment(provider, purchase):
    interested = 'simulatePayment-%s' % ObjectId()
    amount = request.values['amount']
    with CommitContext(g.database, g.user) as ctx:
        op = CallBlm('members', 'generateFakePayment',
                     [[provider], [purchase], [amount]])
        ctx.runCommit([op], interested=interested)
    result, error = wait_for_commit(g.database, interested)
    if error:
        raise error

    paymentId = result[0]
    with CommitContext(g.database) as ctx:
        op = CallToi(paymentId, 'sendConfirmationEmail', [])
        interested = 'send-sim-payment-confirmation-%s' % ObjectId()
        ctx.runCommit([op], interested=interested)
    result, error = wait_for_commit(g.database, interested=interested)
    if error:
        raise error

    return redirect(request.values['returnurl'])
Ejemplo n.º 12
0
def invoice_credit(toid):
    interested = 'rest-invoice-credit-%s' % ObjectId()
    op = CallBlm('members', 'createCreditInvoice', [[toid]])
    with CommitContext(g.database, g.user) as ctx:
        ctx.runCommit([op], interested=interested)
    result, error = wait_for_commit(g.database, interested)
    if error:
        if isinstance(error, (PermissionError, AttrPermError)):
            raise Forbidden
        else:
            raise error
    toid = result[0][0]
    return {'id': toid}
Ejemplo n.º 13
0
def product_delete(toid):
    interested = 'rest-product-delete-%s' % ObjectId()
    with CommitContext(g.database, g.user) as ctx:
        toi, = blm.members.Product._query(id=toid).run()
        op = DeleteToi(toi)
        ctx.runCommit([op], interested=interested)
    result, error = wait_for_commit(g.database, interested)
    if error:
        if isinstance(error, (PermissionError, AttrPermError)):
            raise Forbidden
        else:
            raise error
    return {'id': toi.id[0]}
Ejemplo n.º 14
0
 def do_destroy(self, blmname, tocname, params):
     assert len(params) == 1
     deleteops = params[0]
     if isinstance(deleteops, dict):
         deleteops = [deleteops]
     ids = sum((attrdata['id'] for attrdata in deleteops), [])
     with CommitContext(self.database, self.user) as ctx:
         ops = []
         for toi in blm.TO._query(id=ids).run():
             ops.append(DeleteToi(toi))
         interested = 'direct-destroy-%s' % ObjectId()
         ctx.runCommit(ops, interested=interested)
     result, error = wait_for_commit(self.database, interested)
     return {'success': not error}
Ejemplo n.º 15
0
def authorized_handler():
    baseurl = config.config.get('accounting', 'baseurl')

    if 'oauth_random' in session and \
           request.args['state'] != hashlib.sha256(
        current_app.secret_key +
        session.pop('oauth_random', '')).hexdigest():
        log.info('Connect authorization failed: bad state. %s', request.args)

        return redirect(baseurl)

    resp = stripe_oauth.authorized_response()
    if resp is None:
        # XXX Hack to minimze changes
        log.info('Connect authorization failed: %s', request.args)
        return redirect(baseurl)

    access_token = resp['access_token']
    publishable_key = resp['stripe_publishable_key']
    refresh_token = resp['refresh_token']

    account = stripe.Account.retrieve(api_key=access_token)
    print(account)

    with CommitContext(g.database, g.user) as ctx:
        org, accno, series = session.pop('stripe_accounting_info')
        display_name = account['display_name']

        attrData = {
            'org': [org],
            'account': [accno] if accno else [],
            'series': [series] if series else [],
            'access_token': [access_token],
            'display_name': [display_name] if display_name else [],
            'stripe_id': [account['id']],
            'stripe_email': [account['email']],
            'stripe_publishable_key': [publishable_key],
            'refresh_token': [refresh_token],
        }

        op = CreateToi('accounting.StripeProvider', None, attrData)
        interested = 'stripe-%s' % ObjectId()
        ctx.runCommit([op], interested=interested)

    result, error = wait_for_commit(g.database, interested)
    if error:
        return render_template('error.html', error=error)

    return redirect(baseurl)
Ejemplo n.º 16
0
    def do_call(self, blmname, methodname, params):
        interested = 'direct-call-%s' % ObjectId()
        with CommitContext(self.database, self.user) as ctx:
            if params is None:
                params = []
            for i, param in enumerate(params):
                if not isinstance(param, list):
                    params[i] = [param]
            op = CallBlm(blmname, methodname, params)
            ctx.runCommit([op], interested=interested)

        with ReadonlyContext(self.database, self.user) as ctx:
            result, error = wait_for_commit(self.database, interested)
            assert not error, error
            return result[0]
Ejemplo n.º 17
0
def product_update(toid):
    attrData = getAttrData(flask.request, blm.members.Product,
                           product_whitelist)
    interested = 'rest-product-update-%s' % ObjectId()
    with CommitContext(g.database, g.user) as ctx:
        toi, = blm.members.Product._query(id=toid).run()
        op = ChangeToi(toi, attrData)
        ctx.runCommit([op], interested=interested)
    result, error = wait_for_commit(g.database, interested)
    if error:
        print(error)
        if isinstance(error, (PermissionError, AttrPermError)):
            raise Forbidden
        else:
            raise error
    return {'id': toi.id[0]}
Ejemplo n.º 18
0
def invite():
    # xxx this shares a lot of code with accountingImport - think about generalising
    orgId = request.form['org']

    interested = ObjectId()
    with CommitContext(g.database, g.user) as ctx:
        org, = blm.accounting.Org._query(id=orgId).run()
        ctx.setMayChange(True)
        email = request.form['email']
        roles = request.form.getlist('roles')
        op = CallToi(ObjectId(orgId), 'invite', [[email], roles])
        ctx.runCommit([op], interested=interested)
    result, errors = wait_for_commit(g.database, interested=interested)
    assert not errors, errors

    result = {'success': True}
    return jsonify(**result)
Ejemplo n.º 19
0
def invoice_create():
    interested = 'rest-invoice-create-%s' % ObjectId()
    try:
        data = flask.request.data.decode('utf-8')
    except AttributeError:
        data = flask.request.data
    op = CallBlm('members', 'invoice', [[json.loads(data)]])
    with CommitContext(g.database, g.user) as ctx:
        ctx.runCommit([op], interested=interested)
    result, error = wait_for_commit(g.database, interested)
    if error:
        if isinstance(error, (PermissionError, AttrPermError)):
            raise Forbidden
        else:
            raise error
    toid = result[0][0]['invoice']
    return {'id': toid}
Ejemplo n.º 20
0
    def bootstrap_products(self, intervals=INTERVALS, prices=PRICES):
        option = '\x1f'.join(['Period', '', 'text', '0', ''])
        with CommitContext(self.db) as ctx:
            openend, = blm.accounting.Org._query(orgnum=self.OE_ORGNUM).run()

            if not blm.members.Product._query(notes='subscription').run():
                ops = [
                    CreateToi(
                        'members.Product', None, {
                            'org': [openend],
                            'notes': ['subscription'],
                            'name': [u'Grundtjänst'],
                            'optionFields': [option],
                            'accountingRules': {
                                '1000': decimal.Decimal(200)
                            }
                        })
                ]
                for limit, price in zip(intervals, prices):
                    ops.append(
                        CreateToi(
                            'members.Product', None, {
                                'org': [openend],
                                'notes': ['plusgiro %s' % limit],
                                'name': [u'Upp till %s inbetalningar' % limit],
                                'optionFields': [option],
                                'accountingRules': {
                                    '1000': decimal.Decimal(price)
                                }
                            }))

                ops.append(
                    CreateToi(
                        'members.Product', None, {
                            'org': [openend],
                            'notes': ['plusgiro Infinity'],
                            'name': [u'Massa inbetalningar'],
                            'optionFields': [option]
                        }))

                interested = ObjectId()
                ctx.runCommit(ops, interested=interested)
                result, error = wait_for_commit(self.db, interested)
                if error:
                    raise error
Ejemplo n.º 21
0
def addocr(database, orgnum, pgnum_real, pgnum):
    orgnum = blm.accounting.normalize_orgnum(orgnum)
    pgnum = blm.accounting.normalize_pgnum(pgnum)
    pgnum_real = blm.accounting.normalize_pgnum(pgnum_real)

    if accounting.luhn.luhn_checksum(pgnum):
        raise ValueError('Checksum mismatch: %s' % pgnum)

    with CommitContext(database) as ctx:
        interested = 'addocrgpg-%s' % ObjectId()
        org, = blm.accounting.Org._query(orgnum=orgnum).run()
        pgp, = blm.accounting.PlusgiroProvider._query(
            org=org, pgnum_real=pgnum_real).run()
        op = ChangeToi(pgp, {'pgnum': [pgnum]})
        ctx.runCommit([op], interested=interested)
    result, error = wait_for_commit(database, interested)
    if error:
        raise error
Ejemplo n.º 22
0
def product_create():
    interested = 'rest-product-create-%s' % ObjectId()
    with ReadonlyContext(g.database, g.user):
        org, = blm.accounting.Org._query().run()
    attrData = getAttrData(flask.request, blm.members.Product,
                           product_whitelist)
    attrData['org'] = [org]
    op = CreateToi('members.Product', None, attrData)
    with CommitContext(g.database, g.user) as ctx:
        ctx.runCommit([op], interested=interested)
    result, error = wait_for_commit(g.database, interested)
    if error:
        if isinstance(error, (PermissionError, AttrPermError)):
            raise Forbidden
        else:
            raise error
    toid, = result
    return {'id': toid}
Ejemplo n.º 23
0
def getTickets(purchase, random=None):
    database = g.database.client.get_database(
        g.database.name,
        read_preference=pymongo.ReadPreference.PRIMARY)

    interested = 'get-tickets-%s' % ObjectId()
    with CommitContext(database) as ctx:
        toi, = blm.members.BasePurchase._query(id=purchase, random=random).run()
        op = CallToi(toi.id[0], 'maketickets', [])
        ctx.runCommit([op], interested=interested)
    result, error = wait_for_commit(database, interested)
    if error:
        raise error
    pdf = io.BytesIO()
    with ReadonlyContext(database) as ctx:
        tickets = blm.members.Ticket._query(id=result[0]).run()
        members.ticket.generate(pdf, tickets)

    return Response(response=pdf.getvalue(), mimetype='application/pdf')
Ejemplo n.º 24
0
def imageUpload():
    ownerId = request.form['owner']

    interested = ObjectId()
    with CommitContext(g.database, g.user) as ctx:
        toi, = blm.TO._query(id=ownerId).run()
        ctx.setMayChange(True)
        if request.form['delete']:
            val = []
        else:
            imgfile = request.files['image']
            val = [BlobVal(imgfile, imgfile.mimetype)]
        op = ChangeToi(toi, {'image': val})
        ctx.runCommit([op], interested=interested)
    result, errors = wait_for_commit(g.database, interested=interested)
    assert not errors, errors

    result = {'success': True}
    return jsonify(**result)
Ejemplo n.º 25
0
def create_profile():
    error = ''

    if request.method == 'POST':
        name = request.values['name']
        email = request.values['email']
        op = CallBlm('accounting', 'registerUser',
                     [[name], [email], [session['openid']]])

        interested = ObjectId()
        with CommitContext(g.database) as ctx:
            ctx.setMayChange(True)
            ctx.runCommit([op], interested=interested)

        result, error = wait_for_commit(g.database, interested)
        session['userid'] = result[0][0]
        del session['openid']
        return redirect(session.pop('login_next', request.url_root))

    return render_template('create_profile.html', error=error)
Ejemplo n.º 26
0
def charge(provider, purchase):
    card_token = request.values['stripeToken']
    with ReadonlyContext(g.database) as ctx:
        provider, = blm.accounting.StripeProvider._query(id=provider).run()
        purchase, = blm.members.BasePurchase._query(id=purchase).run()
        amount = int((purchase.total[0] * 100).quantize(1))
        currency = provider.currency[0]
        access_token = provider.access_token[0]
        invoiceUrl = purchase.invoiceUrl[0]

        try:
            charge = stripe.Charge.create(
                amount=amount,
                currency=currency,
                card=card_token,
                description=invoiceUrl,
                api_key=access_token)
        except stripe.error.StripeError as e:
            return flask.redirect(invoiceUrl + '?status=fail')

    if charge.paid:
        with CommitContext(g.database) as ctx:
            op = CreateToi('members.StripePayment', None, dict(
                paymentProvider=[provider],
                matchedPurchase=[purchase],
                amount=[decimal.Decimal(charge.amount) / 100],
                paymentDate=[charge.created],
                transaction_date=[time.strftime('%Y-%m-%d',
                                                time.localtime(charge.created))], # xxx
                charge_id=[charge.id],
                currency=[charge.currency.upper()],
                json_data=[json.dumps(charge)]
            ))
            interested = 'stripe-%s' % ObjectId()
            commit = ctx.runCommit([op], interested=interested)

        result, error = wait_for_commit(g.database, interested=interested)
        if error:
            raise error

    return flask.redirect(invoiceUrl)
Ejemplo n.º 27
0
def accountingImport():
    orgId = request.form['org']

    interested = ObjectId()

    try:
        with CommitContext(g.database, g.user) as ctx:
            org, = blm.accounting.Org._query(id=orgId).run()
            ctx.setMayChange(True)
            data = BlobVal(request.files['siefile'])
            op = CallBlm('accounting', 'accountingImport', [[org], [data]])
            ctx.runCommit([op], interested=interested)
        result, errors = wait_for_commit(g.database, interested=interested)
        if errors:
            result = {'success': False}
            log.error('Error while importing SIE file: %s', errors)
        else:
            result = {'success': True, 'id': str(result[0][0])}
    except Exception:
        result = {'success': False}
        log.error('Error while importing SIE file', exc_info=True)
    return jsonify(**result)
Ejemplo n.º 28
0
    def handle_org(self, orgid, year):
        with CommitContext(self.db) as ctx:
            org, = blm.accounting.Org._query(id=orgid).run()
            subscriptionLevel = org.subscriptionLevel[:]
            invoiceAttrs = {
                'buyerName': org.name[:],
                'buyerEmail': org.email[:],
                'buyerPhone': org.phone[:],
                'buyerAddress': org.address[:],
                'buyerOrg': [orgid]
            }

            openend, = blm.accounting.Org._query(orgnum=self.OE_ORGNUM).run()
            providers = blm.accounting.PaymentProvider._query(org=org).run()
            providers = [
                toi for toi in providers
                if not isinstance(toi, self.ignored_providers)
            ]  #filter(lambda toi: not isinstance(toi, self.ignored_providers), providers)
            start, end = (s % year for s in ('%s-01-01', '%s-12-31'))
            payments = blm.members.Payment._query(paymentProvider=providers,
                                                  transaction_date=q.Between(
                                                      start, end)).run()
            supplierinvoices = blm.accounting.SupplierInvoice._query(
                org=org,
                automated=True,
                accounted=True,
                transaction_date=q.Between(start, end)).run()
            chargeables = len(payments) + len(supplierinvoices)

            toInvoice = [self.subscription]
            if providers:
                for limit, product in self.products:
                    toInvoice.append(product)
                    if chargeables <= limit:
                        break

            for invoice in blm.members.Invoice._query(org=openend,
                                                      buyerOrg=[orgid],
                                                      _attrList=['items'
                                                                 ]).run():
                for item in invoice.items:
                    if dict(item.optionsWithValue).get('Period') == year:
                        try:
                            toInvoice.remove(item.product[0])
                        except ValueError:
                            log.warn(
                                "We have alreaedy invoiced for %s (%s) "
                                "when we shouldn't have.",
                                item.product[0].name[0], item.product[0].id[0])

            if toInvoice:
                invoiceId = ObjectId()
                invoiceAttrs['org'] = [openend]
                ops = [CreateToi('members.Invoice', invoiceId, invoiceAttrs)]
                for productId in toInvoice:
                    product, = blm.members.Product._query(id=productId).run()
                    options = []
                    for optionField in product.optionFields:
                        if optionField.split('\x1f')[0] == 'Period':
                            options.append(year)
                        else:
                            options.append('')

                    ops.append(
                        CreateToi(
                            'members.PurchaseItem', None, {
                                'purchase': [invoiceId],
                                'product': [product],
                                'options': options
                            }))

                interested = ObjectId()
                ctx.runCommit(ops, interested=interested)
                result, error = wait_for_commit(ctx.database,
                                                interested=interested)
                if error:
                    raise error
Ejemplo n.º 29
0
def commit():
    CB.context.runCommit([])
    CB.popContext()
    CB.pushContext(CommitContext(database))
    CB.context.setMayChange(True)
Ejemplo n.º 30
0
    def send_invoice(self, toid):
        from email.mime.multipart import MIMEMultipart
        from email.mime.text import MIMEText
        from email.mime.application import MIMEApplication

        fromaddr = accounting.config.config.get('billing', 'fromaddr')

        with CommitContext(self.db) as ctx:
            invoice, = blm.members.Invoice._query(id=toid).run()
            name = ''
            if invoice.buyerName:
                name = invoice.buyerName[0]
            if invoice.buyerEmail:
                to = parseaddr(invoice.buyerEmail[0])[1]
            else:
                buyer = invoice.buyerOrg
                if buyer:
                    buyer = buyer[0]
                else:
                    buyer = 'unknown'
                log.warn('Org %s (%s) has no email! No invoice sent!', name,
                         buyer)
                return
            url = invoice.invoiceUrl[0]
            try:
                pdf = BytesIO()  #py3
            except NameError:
                pdf = StringIO()  #py2
            org = invoice.org[0]

            pgprovider = blm.accounting.PlusgiroProvider._query(
                org=org, pgnum=q.NotEmpty()).run()

            pgnum = pgprovider[0].pgnum[0] if pgprovider else ''
            #import pdb;pdb.set_trace()
            make_invoice(pdf, invoice, org, pgnum, None)

            body, headers = templating.as_mail_data('subscription', url=url)

            message = MIMEMultipart()
            for header, value in headers.items():
                message[header] = value
            message['From'] = accounting.mail.makeAddressHeader(
                'From', [(org.name[0], org.email[0])])
            message['To'] = accounting.mail.makeAddressHeader(
                'To', [(name, to)])
            message.attach(MIMEText(body, _charset='utf-8'))
            attachment = MIMEApplication(pdf.getvalue(), 'pdf')
            attachment.add_header('Content-Disposition',
                                  'attachment',
                                  filename='faktura.pdf')
            message.attach(attachment)

            log.info('Sending invoice to %s', to)
            accounting.mail.sendmail(fromaddr, [to], message.as_string())

            op = ChangeToi(invoice, {'sent': [True]})
            interested = ObjectId()
            ctx.runCommit([op], interested=interested)
            result, error = wait_for_commit(ctx.database,
                                            interested=interested)
            if error:
                raise error