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
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
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 })
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)
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 ''
def lookup_current_user(): result = None g.user = None if getattr(current_app, 'connection', None) is None: current_app.connection = accounting.db.get_connection() current_app.dbname = config.config.get('accounting', 'mongodb_dbname') g.database = current_app.connection[current_app.dbname] auth = request.headers.get('Authorization') userid = session.get('userid') with ReadonlyContext(g.database): if auth: _, key = auth.split() try: g.user = blm.accounting.APIUser._query( key=key, _attrList={'lastAccess'}).run()[0] except IndexError: raise werkzeug.exceptions.Forbidden() elif userid: try: g.user = blm.accounting.User._query( id=session['userid'], _attrList={'lastAccess'} ).run()[0] except IndexError: del session['userid'] else: invitation = session.pop('invitation', None) if invitation: result = acceptInvitation(g.user, invitation) if g.user: if g.user.lastAccess[0] + USER_ACCESS_RESOLUTION < time.time(): op = ChangeToi(g.user, {'lastAccess': [time.time()]}) with CommitContext.clone() as ctx: ctx.runCommit([op]) # not interested return result
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}
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}
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
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
def process(database): with ReadonlyContext(database): for order in blm.accounting.PGOrder._query(sent=[False]).run(): with CommitContext.clone() as ctx: op = CallToi(order.id[0], 'send', []) interested = 'sendpg-%s' % ObjectId() ctx.runCommit([op], interested) result, error = wait_for_commit(database, interested) if error: raise error
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
def acceptInvitation(user, code): with ReadonlyContext(g.database): q = blm.accounting.Invitation._query(inviteCode=code) for invitation in q.run(): user, = blm.accounting.User._query(id=user.id).run() op = CallToi(invitation.id[0], 'accept', [[user]]) interested = ObjectId() with CommitContext.clone() as ctx: ctx.runCommit([op], interested=interested) result, error = wait_for_commit(g.database, interested) if error: return redirect(url_for('invitation_expired'))
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'])
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}
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]}
def createOrders(database): with ReadonlyContext(database): for org in blm.accounting.identifyOrgsWithDueTransfers(): supInvList = blm.accounting.identifyDueTransfers(org=org) with CommitContext.clone() as ctx: op = CallBlm('accounting', 'createSignedBgcOrder', [[org], supInvList]) interested = 'createSignedBgcOrder_org-%s_%s' % (org.id[0], ObjectId()) ctx.runCommit([op], interested) result, error = wait_for_commit(database, interested) if error: raise error
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}
def sendOrders(database, out): with ReadonlyContext(database): for order in blm.accounting.BgcOrder._query( order_signed=NotEmpty(), sent=Empty()).run(): with CommitContext.clone() as ctx: op = CallBlm('accounting', 'sendBgcOrder', [[order]]) interested = 'sendBgcOrder_order-%s_%s' % (order.id[0], ObjectId()) ctx.runCommit([op], interested) result, error = wait_for_commit(database, interested) if error: raise error for r in result: out.write('Sent {}\n'.format(r))
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)
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]
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]}
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)
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}
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
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
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}
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)
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')
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)