def make_wsgi_app(dbcontext, auth_decorator, jinja_env, dbapi, actionlogged): w = Bottle() # bind apis bind_dbapi_rest('/app/api/client', dbapi, Client, w) bind_dbapi_rest('/app/api/user', dbapi, User, w) @w.get('/app/cliente/<id>') @dbcontext @auth_decorator def modificar_cliente_form(id, message=None): client = dbapi.get(id, Client) if client is None: message = 'Cliente {} no encontrado'.format(id) temp = jinja_env.get_template('crear_cliente.html') return temp.render(client=client, message=message, action='/app/modificar_cliente', button_text='Modificar') @w.post('/app/modificar_cliente') @dbcontext @auth_decorator def modificar_cliente(): clientid = request.forms.codigo client = Client(codigo=clientid) dbapi.update(client, request.forms) redirect('/app/cliente/{}'.format(clientid)) @w.get('/app/cliente') @dbcontext @auth_decorator def search_cliente_result(): prefix = request.query.prefijo clientes = list(dbapi.search(Client, **{'apellidos-prefix': prefix})) temp = jinja_env.get_template('search_cliente_result.html') return temp.render(clientes=clientes) @w.post('/app/crear_cliente') @dbcontext @auth_decorator def crear_cliente(): cliente = Client.deserialize(request.forms) cliente.cliente_desde = datetime.date.today() try: dbapi.create(cliente) dbapi.db_session.commit() except ItemAlreadyExists: return crear_cliente_form('Cliente con codigo {} ya existe'.format( cliente.codigo)) return crear_cliente_form('Cliente {} {} creado'.format( cliente.apellidos, cliente.nombres)) @w.get('/app/secuencia') @dbcontext @auth_decorator def get_secuencia(): users = dbapi.search(User) temp = jinja_env.get_template('secuencia.html') store_dict = {s.almacen_id: s.nombre for s in dbapi.search(Store)} store_dict[-1] = 'Ninguno' return temp.render(users=users, stores=store_dict) @w.post('/app/secuencia') @dbcontext @auth_decorator @actionlogged def post_secuencia(): username = request.forms.usuario seq = request.forms.secuencia user = User(username=username) dbapi.update(user, {'last_factura': seq}) redirect('/app/secuencia') @w.get('/app/ver_cliente') @dbcontext @auth_decorator def ver_cliente(): temp = jinja_env.get_template('ver_item.html') return temp.render(title='Ver Cliente', baseurl='/app/cliente', apiurl='/api/cliente') @w.get('/app/crear_cliente') @dbcontext @auth_decorator def crear_cliente_form(message=None): temp = jinja_env.get_template('crear_cliente.html') return temp.render(client=None, message=message, action='/app/crear_cliente', button_text='Crear') bind_dbapi_rest('/app/api/client', dbapi, Client, w) return w
def make_import_apis(prefix, auth_decorator, dbapi, jinja_env): app = Bottle() dbcontext = DBContext(dbapi.session) bind_dbapi_rest(prefix + '/purchase', dbapi, Purchase, app) bind_dbapi_rest(prefix + '/purchase_item', dbapi, PurchaseItem, app) bind_dbapi_rest(prefix + '/universal_prod', dbapi, UniversalProd, app) bind_dbapi_rest(prefix + '/declaredgood', dbapi, DeclaredGood, app) bind_dbapi_rest(prefix + '/custom_item', dbapi, CustomItem, app) @app.get(prefix + '/universal_prod_with_declared') @dbcontext @auth_decorator(0) def get_universal_prod_with_declared(): all_prod = dbapi.search(UniversalProd) all_declared = dbapi.search(DeclaredGood) return json_dumps({ 'prod': all_prod, 'declared': all_declared }) @app.get(prefix + '/purchase_filtered/<uid>') @dbcontext @auth_decorator def purchase_fitered(uid): purchase = get_purchase_full(dbapi, uid) map(normal_filter, purchase.items) total = sum(i.item.price_rmb * i.item.quantity for i in purchase.items) purchase.meta.total_rmb = total res = purchase.serialize() res['units'] = {x.uid: x for x in dbapi.search(Unit)} return json_dumps(res) @app.get(prefix + '/purchase_full/<uid>') @dbcontext @auth_decorator(0) def get_purchase_full_http(uid): res = get_purchase_full(dbapi, uid).serialize() res['units'] = {x.uid: x for x in dbapi.search(Unit)} return json_dumps(res) @app.post(prefix + '/purchase_full') @dbcontext @auth_decorator(0) def create_full_purchase(): rows = json.loads(request.body.read()) purchase = Purchase() purchase.timestamp = datetime.datetime.now() pid = dbapi.create(purchase) def make_item(r): return PurchaseItem( upi=r['prod']['upi'], quantity=Decimal(r['cant']), price_rmb=Decimal(r['price']), purchase_id=pid) items = map(make_item, rows) total = sum((r.price_rmb * r.quantity for r in items)) dbapi.update(purchase, {'total_rmb': total}) map(dbapi.create, items) return {'uid': pid} @app.put(prefix + '/purchase_full/<uid>') @dbcontext def update_purchase_full(uid): data = json.loads(request.body.read()) print data # update meta updated = Purchase.deserialize(data['meta']) print updated.timestamp updated.last_edit_timestamp = datetime.datetime.now() dbapi.update_full(updated) to_create_item = map(PurchaseItem.deserialize, data.get('create_items', [])) for pi in to_create_item: pi.purchase_id = uid dbapi.create(pi) to_delete_item = map(PurchaseItem.deserialize, data.get('delete_items', [])) for pi in to_delete_item: dbapi.delete(pi) to_edit_item = map(PurchaseItem.deserialize, data.get('edit_items', [])) for pi in to_edit_item: dbapi.update_full(pi) return {'status': 'success'} @app.get(prefix + '/custom_full/<uid>') @dbcontext @auth_decorator(0) def post_sale(): content = Sale.deserialize(json.loads(request.body.read())) if list(dbapi.search( Sale, seller_codename=content.seller_codename, seller_inv_uid=content.seller_inv_uid)): return {'status': 'failed', 'reason': 'sale with the id already exists'} dbapi.create(content) return {'status': 'success'} @app.put(prefix + '/custom_full/<uid>') @dbcontext @auth_decorator(0) def get_sales(): start, end = parse_start_end_date(request.query) result = list(get_sales_by_date_and_user(dbapi, start, end)) return json_dumps(result) @app.post(prefix + '/split_custom_items') @dbcontext @auth_decorator(0) def delete_sale(): content = Sale.deserialize(json.loads(request.body.read())) deleted = dbapi.db_session.query(NSale).filter_by( seller_codename=content.seller_codename, seller_inv_uid=content.seller_inv_uid ).update({'status': Status.DELETED}) return {'deleted': deleted} @app.post(prefix + '/custom_full/purchase/<uid>') @dbcontext @auth_decorator(0) def post_inv_movement_set(): raw_inv = request.body.read() inv_movement = InvMovementFull.deserialize(json.loads(raw_inv)) meta = inv_movement.meta meta.origin = get_or_create_inventory_id(dbapi, meta.inventory_codename, meta.origin) meta.dest = get_or_create_inventory_id(dbapi, meta.inventory_codename, meta.dest) if list(dbapi.search(InvMovementMeta, inventory_codename=meta.inventory_codename, inventory_docid=meta.inventory_docid, trans_type=meta.trans_type)): # already exists return {'created': 0, 'reason': 'already exists'} for igcant in inv_movement.items: prod_id = igcant.itemgroup.prod_id ig_real = dbapi.getone(ProdItemGroup, prod_id=prod_id) # itemgroup does not exist, create if not ig_real: dbapi.create(igcant.itemgroup) else: # replace itemgroup as the itemgroup id might be distinct igcant.itemgroup = ig_real inv_movement = invmomanager.create(inv_movement) return {'created': inv_movement.meta.uid} @app.get(prefix + '/inv_movement/<day>') @dbcontext def last_inv_movements(day): today = parse_iso_date(day) tomorrow = today + datetime.timedelta(days=1) print today, tomorrow movements = list(dbapi.search(InvMovementMeta, **{'timestamp-gte': today, 'timestamp-lte': tomorrow})) return json_dumps({'result': movements}) @app.get(prefix + '/sales_report') @dbcontext def get_sales_report(): start, end = parse_start_end_date(request.query) sales_by_date = list(client_sale_report(dbapi, start, end)) return json_dumps({'result': sales_by_date}) # @app.post(prefix + '/raw_inv_movement') @dbcontext def post_raw_inv_movement(): raw_data = json.loads(request.body.read()) ig = ProdItemGroup.deserialize(raw_data[0]) trans = map(InventoryMovement.deserialize, raw_data[1]) codename = raw_data[2] if dbapi.getone(ProdItemGroup, prod_id=ig.prod_id) is None: if dbapi.get(ig.uid, ProdItemGroup) is not None: # prod_id does not exist but uid is used so we cannot create # using the same uid ig.uid = None dbapi.create(ig) for i in trans: i.itemgroup_id = ig.uid if dbapi.getone(Inventory, entity_codename=codename, external_id=i.from_inv_id) is None: # create new Inventory if none i.from_inv_id = get_or_create_inventory_id(dbapi, codename, i.from_inv_id) i.to_inv_id = get_or_create_inventory_id(dbapi, codename, i.to_inv_id) i.reference_id = codename + (i.reference_id or '') inventoryapi.save(i) return app
def make_wsgi_app(dbcontext, auth_decorator, jinja_env, dbapi, actionlogged): w = Bottle() # bind apis bind_dbapi_rest('/app/api/client', dbapi, Client, w) bind_dbapi_rest('/app/api/user', dbapi, User, w) @w.get('/app/cliente/<id>') @dbcontext @auth_decorator(0) def modificar_cliente_form(id, message=None): client = dbapi.get(id, Client) if client is None: message = 'Cliente {} no encontrado'.format(id) temp = jinja_env.get_template('crear_cliente.html') return temp.render(client=client, message=message, action='/app/modificar_cliente', button_text='Modificar') @w.post('/app/modificar_cliente') @dbcontext @auth_decorator(0) def modificar_cliente(): clientid = request.forms.codigo client = Client(codigo=clientid) dbapi.update(client, request.forms) redirect('/app/cliente/{}'.format(clientid)) @w.get('/app/cliente') @dbcontext @auth_decorator(0) def search_cliente_result(): prefix = request.query.prefijo clientes = list(dbapi.search(Client, **{'apellidos-prefix': prefix})) temp = jinja_env.get_template('search_cliente_result.html') return temp.render(clientes=clientes) @w.post('/app/crear_cliente') @dbcontext @auth_decorator(0) def crear_cliente(): cliente = Client.deserialize(request.forms) cliente.cliente_desde = datetime.date.today() try: dbapi.create(cliente) dbapi.db_session.commit() except ItemAlreadyExists: return crear_cliente_form('Cliente con codigo {} ya existe'.format(cliente.codigo)) return crear_cliente_form('Cliente {} {} creado'.format(cliente.apellidos, cliente.nombres)) @w.get('/app/secuencia') @dbcontext @auth_decorator(1) def get_secuencia(): users = dbapi.search(User) temp = jinja_env.get_template('secuencia.html') store_dict = {s.almacen_id: s.nombre for s in dbapi.search(Store)} store_dict[-1] = 'Ninguno' return temp.render(users=users, stores=store_dict) @w.post('/app/secuencia') @dbcontext @auth_decorator(1) @actionlogged def post_secuencia(): username = request.forms.usuario seq = request.forms.secuencia user = User(username=username) dbapi.update(user, {'last_factura': seq}) redirect('/app/secuencia') @w.get('/app/ver_cliente') @dbcontext @auth_decorator(0) def ver_cliente(): temp = jinja_env.get_template('ver_item.html') return temp.render(title='Ver Cliente', baseurl='/app/cliente', apiurl='/api/cliente') @w.get('/app/crear_cliente') @dbcontext @auth_decorator(0) def crear_cliente_form(message=None): temp = jinja_env.get_template('crear_cliente.html') return temp.render(client=None, message=message, action='/app/crear_cliente', button_text='Crear') bind_dbapi_rest('/app/api/client', dbapi, Client, w) return w
def make_wsgi_api(prefix, sessionmanager, dbcontext, auth_decorator, dbapi): app = Bottle() @app.post(prefix + '/item_full') @dbcontext @auth_decorator def create_item_full(): """ input format: { "prod" : {prod_id, name, desc, base_unit}< - information on item group "items": [{multiplier}, {unit}<- information on items requires multiplier be distinct "prices": [{unit, almacen_id, display_name, price1, price2, cant}] "new_unit": [] } """ content = request.body.read() content = json.loads(content) valid, message = validate_full_item(content, dbapi) if not valid: return {'status': 'failure', 'msg': message} create_full_item_from_dict(dbapi, content) sessionmanager.session.commit() return {'status': 'success'} @app.get(prefix + '/item_full/<item_id>') @dbcontext def get_item_full(item_id): itemgroup = dbapi.get(item_id, ProdItemGroup) items = dbapi.search(ProdItem, itemgroupid=itemgroup.uid) prices_by_item = {} for x in items: prices_by_item[x.prod_id] = dbapi.search(PriceList, prod_id=x.prod_id) return json_dumps(make_full_items(itemgroup, items, prices_by_item)) @app.post(prefix + '/item_with_price') @dbcontext def save_item_with_price(): # TODO: VALIDATION item_with_price = json.loads(request.body.read()) item = ProdItem.deserialize(item_with_price) prod_id = item_with_price['prod_id'] if int(item_with_price['multiplier']) > 1: prod_id += '+' item.prod_id = prod_id uid = dbapi.create(item) for aid, x in item_with_price['price'].items(): p = PriceList() p.almacen_id = aid p.prod_id = prod_id p.precio1 = int(Decimal(x['price1']) * 100) p.precio2 = int(Decimal(x['price2']) * 100) p.nombre = x['display_name'] p.cant_mayorista = x['cant'] p.unidad = item.unit p.multiplicador = item.multiplier dbapi.create(p) dbapi.db_session.commit() return {'status': 'success', 'uid': uid} bind_dbapi_rest(prefix + '/pricelist', dbapi, PriceList, app) bind_dbapi_rest(prefix + '/itemgroup', dbapi, ProdItemGroup, app) bind_dbapi_rest(prefix + '/item', dbapi, ProdItem, app) return app
def make_wsgi_api(dbapi, invapi, dbcontext, auth_decorator, paymentapi, imgserver): w = Bottle() @w.get('/app/api/sales') @dbcontext def get_sales(): """ start=<start>&end=<end> """ start_date, end_date = parse_start_end_date(request.query) if not end_date: end_date = datetime.date.today() end_date = end_date + datetime.timedelta(hours=23) query = dbapi.db_session.query( NNota.almacen_id, func.sum(NNota.total)).filter( NNota.timestamp >= start_date).filter( NNota.timestamp <= end_date).filter( NNota.status != Status.DELETED).group_by(NNota.almacen_id) result = [] for aid, total in query: result.append((aid, Decimal(total) / 100)) return json_dumps({'result': result}) @w.get('/app/api/payment') @dbcontext def get_all_payments(): start, end = parse_start_end_date(request.query) result = list(paymentapi.list_payments(start, end)) return json_dumps({'result': result}) @w.get('/app/api/gasto') @dbcontext def get_all_gastos(): day = parse_iso(request.query.get('date')) result = dbapi.search(Spent, inputdate=day) return json_dumps(result) @w.get('/app/api/account_transaction') @dbcontext def get_account_transactions_mult_days(): start, end = parse_start_end_date(request.query) result = get_transactions(dbapi, paymentapi, invapi, imgserver, start, end) return json_dumps(result) @w.get('/app/api/check') @dbcontext def get_checks(): save_date = request.query.get('save_date') save_date_end = request.query.get('save_date_end') deposit_date = request.query.get('deposit_date') deposit_date_end = request.query.get('deposit_date_end') if save_date: save_date = (save_date, save_date_end) if deposit_date: deposit_date = (deposit_date, deposit_date_end) checks = paymentapi.list_checks(save_date, deposit_date) for x in checks: x.imgdeposit = imgserver.get_url_path(x.imgdeposit) x.imgcheck = imgserver.get_url_path(x.imgcheck) x.value = Decimal(x.value) / 100 return json_dumps({'result': checks}) @w.post('/app/api/acct_transaction') @dbcontext def post_acct_transaction(): data = request.body.read() acct = AccountTransaction.deserialize(json.loads(data)) acct.input_timestamp = datetime.datetime.now() acct.deleted = False pkey = dbapi.create(acct) return {'pkey': pkey} @w.put('/app/api/acct_transaction/<uid>') @dbcontext def put_acct_transaction(uid): data = json.loads(request.body.read()) acct = AccountTransaction(uid=uid) count = dbapi.update(acct, data) return {'updated': count} @w.get('/app/api/noncash_sales_with_payments') @dbcontext @auth_decorator def ver_ventas_no_efectivos(): start, end = parse_start_end_date(request.query) end += datetime.timedelta(hours=23) sales = dbapi.db_session.query(NNota).filter( NNota.timestamp >= start).filter(NNota.timestamp <= end).filter( NNota.payment_format != PaymentFormat.CASH) sales = map(InvMetadata.from_db_instance, sales) payments = list(paymentapi.list_payments(start, end)) result = {} for x in sales: if x.client.codigo not in result: result[x.client.codigo] = {} result[x.client.codigo]['sales'] = [] result[x.client.codigo]['payments'] = [] result[x.client.codigo]['sales'].append(x) unused_payments = [] for x in payments: if x.client_id in result: result[x.client_id]['payments'].append(x) else: unused_payments.append(x) result['unused_payments'] = unused_payments return json_dumps({ 'unused_payments': unused_payments, 'sales': result.items() }) @w.get('/app/api/account_deposit_with_img') @dbcontext @auth_decorator def get_account_deposit_with_img(): today = datetime.datetime.today() thisyear = today - datetime.timedelta(days=365) turned_in = sorted(get_turned_in_cash(dbapi, thisyear, today, imgserver), key=lambda x: x.date, reverse=True) result = defaultdict(list) for x in turned_in: if getattr(x, 'img', None): if len(result['with_deposit']) < 10: result['with_deposit'].append(x) else: result['without_deposit'].append(x) return json_dumps(result) # account stat bind_dbapi_rest('/app/api/account_stat', dbapi, AccountStat, w) bind_dbapi_rest('/app/api/bank_account', dbapi, DepositAccount, w) bind_dbapi_rest('/app/api/account_deposit', dbapi, AccountTransaction, w) bind_dbapi_rest('/app/api/spent', dbapi, Spent, w, skips_method=('DELETE', )) @w.get('/app/api/pago/<uid>') @dbcontext def get_pago_with_id(uid): elm = dbapi.db_session.query(NPayment).filter_by(uid=uid).first() if elm is None: response.status = 404 return '' return json_dumps(Payment().merge_from(elm).serialize()) @w.delete('/app/api/pago/<uid>') @dbcontext def mark_pago_deleted(uid): success = dbapi.db_session.query(NPayment).filter_by(uid=uid).update({'deleted': True}) dbapi.db_session.commit() return {'success': success > 0} @w.put('/app/api/pago/<uid>') @dbcontext def modify_payment(uid): data = json.loads(request.body.read()) success = dbapi.db_session.query(NPayment).filter_by(uid=uid).update(data) dbapi.db_session.commit() return {'success': success > 0} @w.delete('/app/api/spent/<uid>') @dbcontext def mark_pago_deleted(uid): spent = Spent(uid=uid) sucess = dbapi.update(spent, {'deleted': True}) dbapi.db_session.commit() return {'success': sucess > 0} return w
def make_sale_records_api(prefix, auth_decorator, dbapi, invmomanager, inventoryapi): app = Bottle() dbcontext = DBContext(dbapi.session) bind_dbapi_rest(prefix + '/entity', dbapi, Entity, app) @app.post(prefix + '/client_sale') @dbcontext @auth_decorator def post_sale(): content = Sale.deserialize(json.loads(request.body.read())) if list(dbapi.search( Sale, seller_codename=content.seller_codename, seller_inv_uid=content.seller_inv_uid)): return {'status': 'failed', 'reason': 'sale with the id already exists'} dbapi.create(content) return {'status': 'success'} @app.get(prefix + '/client_sale') @dbcontext @auth_decorator def get_sales(): start, end = parse_start_end_date(request.query) result = list(get_sales_by_date_and_user(dbapi, start, end)) return json_dumps(result) @app.delete(prefix + '/client_sale') @dbcontext @auth_decorator def delete_sale(): content = Sale.deserialize(json.loads(request.body.read())) deleted = dbapi.db_session.query(NSale).filter_by( seller_codename=content.seller_codename, seller_inv_uid=content.seller_inv_uid ).update({'status': Status.DELETED}) return {'deleted': deleted} @app.post(prefix + '/inv_movement_set') @dbcontext @auth_decorator def post_inv_movement_set(): raw_inv = request.body.read() inv_movement = InvMovementFull.deserialize(json.loads(raw_inv)) meta = inv_movement.meta meta.origin = get_or_create_inventory_id(dbapi, meta.inventory_codename, meta.origin) meta.dest = get_or_create_inventory_id(dbapi, meta.inventory_codename, meta.dest) if list(dbapi.search(InvMovementMeta, inventory_codename=meta.inventory_codename, inventory_docid=meta.inventory_docid, trans_type=meta.trans_type)): # already exists return {'created': 0, 'reason': 'already exists'} for igcant in inv_movement.items: prod_id = igcant.itemgroup.prod_id ig_real = dbapi.getone(ProdItemGroup, prod_id=prod_id) # itemgroup does not exist, create if not ig_real: dbapi.create(igcant.itemgroup) else: # replace itemgroup as the itemgroup id might be distinct igcant.itemgroup = ig_real inv_movement = invmomanager.create(inv_movement) return {'created': inv_movement.meta.uid} @app.get(prefix + '/inv_movement/<day>') @dbcontext def last_inv_movements(day): today = parse_iso_date(day) tomorrow = today + datetime.timedelta(days=1) print today, tomorrow movements = list(dbapi.search(InvMovementMeta, **{'timestamp-gte': today, 'timestamp-lte': tomorrow})) return json_dumps({'result': movements}) @app.get(prefix + '/sales_report') @dbcontext def get_sales_report(): start, end = parse_start_end_date(request.query) sales_by_date = list(client_sale_report(dbapi, start, end)) return json_dumps({'result': sales_by_date}) # @app.post(prefix + '/raw_inv_movement') # expects [proditemgroup, inventoryMovement, codename] @dbcontext def post_raw_inv_movement(): raw_data = json.loads(request.body.read()) ig = ProdItemGroup.deserialize(raw_data[0]) trans = map(InventoryMovement.deserialize, raw_data[1]) codename = raw_data[2] if dbapi.getone(ProdItemGroup, prod_id=ig.prod_id) is None: if dbapi.get(ig.uid, ProdItemGroup) is not None: # prod_id does not exist but uid is used so we cannot create # using the same uid ig.uid = None dbapi.create(ig) for i in trans: i.itemgroup_id = ig.uid if dbapi.getone(Inventory, entity_codename=codename, external_id=i.from_inv_id) is None: # create new Inventory if none i.from_inv_id = get_or_create_inventory_id(dbapi, codename, i.from_inv_id) i.to_inv_id = get_or_create_inventory_id(dbapi, codename, i.to_inv_id) i.reference_id = codename + (i.reference_id or '') inventoryapi.save(i) return app
def make_wsgi_api(dbapi, invapi, dbcontext, auth_decorator, paymentapi, imgserver): w = Bottle() @w.get('/app/api/sales') @dbcontext def get_sales(): """ start=<start>&end=<end> """ start_date, end_date = parse_start_end_date(request.query) if not end_date: end_date = datetime.date.today() end_date = end_date + datetime.timedelta(hours=23) query = dbapi.db_session.query(NNota.almacen_id, func.sum( NNota.total)).filter(NNota.timestamp >= start_date).filter( NNota.timestamp <= end_date).filter( NNota.status != Status.DELETED).group_by(NNota.almacen_id) result = [] for aid, total in query: result.append((aid, Decimal(total) / 100)) return json_dumps({'result': result}) @w.get('/app/api/payment') @dbcontext def get_all_payments(): start, end = parse_start_end_date(request.query) result = list(paymentapi.list_payments(start, end)) return json_dumps({'result': result}) @w.get('/app/api/gasto') @dbcontext def get_all_gastos(): day = parse_iso(request.query.get('date')) result = dbapi.search(Spent, inputdate=day) return json_dumps(result) @w.get('/app/api/account_transaction') @dbcontext def get_account_transactions_mult_days(): start, end = parse_start_end_date(request.query) result = get_transactions(dbapi, paymentapi, invapi, imgserver, start, end) return json_dumps(result) @w.get('/app/api/check') @dbcontext def get_checks(): save_date = request.query.get('save_date') save_date_end = request.query.get('save_date_end') deposit_date = request.query.get('deposit_date') deposit_date_end = request.query.get('deposit_date_end') if save_date: save_date = (save_date, save_date_end) if deposit_date: deposit_date = (deposit_date, deposit_date_end) checks = paymentapi.list_checks(save_date, deposit_date) for x in checks: x.imgdeposit = imgserver.get_url_path(x.imgdeposit) x.imgcheck = imgserver.get_url_path(x.imgcheck) x.value = Decimal(x.value) / 100 return json_dumps({'result': checks}) @w.post('/app/api/acct_transaction') @dbcontext def post_acct_transaction(): data = request.body.read() acct = AccountTransaction.deserialize(json.loads(data)) acct.input_timestamp = datetime.datetime.now() acct.deleted = False pkey = dbapi.create(acct) return {'pkey': pkey} @w.put('/app/api/acct_transaction/<uid>') @dbcontext def put_acct_transaction(uid): data = json.loads(request.body.read()) acct = AccountTransaction(uid=uid) count = dbapi.update(acct, data) return {'updated': count} @w.get('/app/api/noncash_sales_with_payments') @dbcontext @auth_decorator def ver_ventas_no_efectivos(): start, end = parse_start_end_date(request.query) end += datetime.timedelta(hours=23) sales = dbapi.db_session.query(NNota).filter( NNota.timestamp >= start).filter(NNota.timestamp <= end).filter( NNota.payment_format != PaymentFormat.CASH) sales = map(InvMetadata.from_db_instance, sales) payments = list(paymentapi.list_payments(start, end)) result = {} for x in sales: if x.client.codigo not in result: result[x.client.codigo] = {} result[x.client.codigo]['sales'] = [] result[x.client.codigo]['payments'] = [] result[x.client.codigo]['sales'].append(x) unused_payments = [] for x in payments: if x.client_id in result: result[x.client_id]['payments'].append(x) else: unused_payments.append(x) result['unused_payments'] = unused_payments return json_dumps({ 'unused_payments': unused_payments, 'sales': result.items() }) @w.get('/app/api/account_deposit_with_img') @dbcontext @auth_decorator def get_account_deposit_with_img(): today = datetime.datetime.today() thisyear = today - datetime.timedelta(days=365) turned_in = sorted(get_turned_in_cash(dbapi, thisyear, today, imgserver), key=lambda x: x.date, reverse=True) result = defaultdict(list) for x in turned_in: if getattr(x, 'img', None): if len(result['with_deposit']) < 10: result['with_deposit'].append(x) else: result['without_deposit'].append(x) return json_dumps(result) # account stat bind_dbapi_rest('/app/api/account_stat', dbapi, AccountStat, w) bind_dbapi_rest('/app/api/bank_account', dbapi, DepositAccount, w) bind_dbapi_rest('/app/api/account_deposit', dbapi, AccountTransaction, w) bind_dbapi_rest('/app/api/spent', dbapi, Spent, w, skips_method=('DELETE', )) @w.get('/app/api/pago/<uid>') @dbcontext def get_pago_with_id(uid): elm = dbapi.db_session.query(NPayment).filter_by(uid=uid).first() if elm is None: response.status = 404 return '' return json_dumps(Payment().merge_from(elm).serialize()) @w.delete('/app/api/pago/<uid>') @dbcontext def mark_pago_deleted(uid): success = dbapi.db_session.query(NPayment).filter_by(uid=uid).update( {'deleted': True}) dbapi.db_session.commit() return {'success': success > 0} @w.put('/app/api/pago/<uid>') @dbcontext def modify_payment(uid): data = json.loads(request.body.read()) success = dbapi.db_session.query(NPayment).filter_by( uid=uid).update(data) dbapi.db_session.commit() return {'success': success > 0} @w.delete('/app/api/spent/<uid>') @dbcontext def mark_pago_deleted(uid): spent = Spent(uid=uid) sucess = dbapi.update(spent, {'deleted': True}) dbapi.db_session.commit() return {'success': sucess > 0} return w
def make_wsgi_api(prefix, sessionmanager, dbcontext, auth_decorator, dbapi, inventoryapi): app = Bottle() @app.post(prefix + "/item_full") @dbcontext @auth_decorator def create_item_full(): """ input format: { "prod" : {prod_id, name, desc, base_unit}< - information on item group "items": [{multiplier}, {unit}<- information on items requires multiplier be distinct "prices": [{unit, almacen_id, display_name, price1, price2, cant}] "new_unit": [] } """ content = request.body.read() content = json.loads(content) valid, message = validate_full_item(content, dbapi) if not valid: return {"status": "failure", "msg": message} create_full_item_from_dict(dbapi, content) sessionmanager.session.commit() return {"status": "success"} @app.get(prefix + "/item_full/<item_id>") @dbcontext def get_item_full(item_id): itemgroup = dbapi.get(item_id, ProdItemGroup) items = dbapi.search(ProdItem, itemgroupid=itemgroup.uid) prices_by_item = {} for x in items: prices_by_item[x.prod_id] = dbapi.search(PriceList, prod_id=x.prod_id) return json_dumps(make_full_items(itemgroup, items, prices_by_item)) @app.post(prefix + "/item_with_price") @dbcontext def save_item_with_price(): # TODO: VALIDATION item_with_price = json.loads(request.body.read()) item = ProdItem.deserialize(item_with_price) prod_id = item_with_price["prod_id"] if int(item_with_price["multiplier"]) > 1: prod_id += "+" item.prod_id = prod_id uid = dbapi.create(item) for aid, x in item_with_price["price"].items(): p = PriceList() p.almacen_id = aid p.prod_id = prod_id p.precio1 = int(Decimal(x["price1"]) * 100) p.precio2 = int(Decimal(x["price2"]) * 100) p.nombre = x["display_name"] p.cant_mayorista = x["cant"] p.unidad = item.unit p.multiplicador = item.multiplier dbapi.create(p) dbapi.db_session.commit() return {"status": "success", "uid": uid} @app.get(prefix + "/prod_quantity/<uid>") @dbcontext def get_prod_quantity(uid): current_record = inventoryapi.get_current_quantity(uid) bodegas = dbapi.search(Bodega) return json_dumps({"inv": bodegas, "itemgroup_id": uid, "quantity": current_record}) @app.get(prefix + "/itemgroup/<uid>/transaction") @dbcontext def get_transactions_of_item_group(uid): start, end = parse_start_end_date(request.query) start = start.date() end = end.date() return json_dumps({"results": list(inventoryapi.list_transactions(uid, start, end))}) bind_dbapi_rest(prefix + "/pricelist", dbapi, PriceList, app) bind_dbapi_rest(prefix + "/itemgroup", dbapi, ProdItemGroup, app) bind_dbapi_rest(prefix + "/item", dbapi, ProdItem, app) return app
def make_wsgi_api(prefix, sessionmanager, dbcontext, auth_decorator, dbapi, inventoryapi, sync_api): app = Bottle() @app.post(prefix + '/item_full') @dbcontext @auth_decorator(0) def create_item_full(): """ input format: { "prod" : {prod_id, name, desc, base_unit}< - information on item group "items": [{multiplier}, {unit}<- information on items requires multiplier be distinct "prices": [{unit, almacen_id, display_name, price1, price2, cant}] "new_unit": [] } """ content = request.body.read() content = json.loads(content) valid, message = validate_full_item(content, dbapi) if not valid: return {'status': 'failure', 'msg': message} create_full_item_from_dict(dbapi, content) # write new prod to log sync_api.write_new_prod(content) sessionmanager.session.commit() return {'status': 'success'} @app.get(prefix + '/item_full/<item_id>') @dbcontext def get_item_full(item_id): itemgroup = dbapi.get(item_id, ProdItemGroup) items = dbapi.search(ProdItem, itemgroupid=itemgroup.uid) prices_by_item = {} for x in items: prices_by_item[x.prod_id] = dbapi.search(PriceList, prod_id=x.prod_id) return json_dumps(make_full_items(itemgroup, items, prices_by_item)) @app.post(prefix + '/item_with_price') @dbcontext def save_item_with_price(): # TODO: VALIDATION item_with_price = json.loads(request.body.read()) item = ProdItem.deserialize(item_with_price) prod_id = item_with_price['prod_id'] if int(item_with_price['multiplier']) > 1: prod_id += '+' item.prod_id = prod_id uid = dbapi.create(item) for aid, x in item_with_price['price'].items(): p = PriceList() p.almacen_id = aid p.prod_id = prod_id p.precio1 = int(Decimal(x['price1']) * 100) p.precio2 = int(Decimal(x['price2']) * 100) p.nombre = x['display_name'] p.cant_mayorista = x['cant'] p.unidad = item.unit p.multiplicador = item.multiplier dbapi.create(p) dbapi.db_session.commit() return {'status': 'success', 'uid': uid} @app.get(prefix + '/prod_quantity/<uid>') @dbcontext def get_prod_quantity(uid): current_record = inventoryapi.get_current_quantity(uid) bodegas = dbapi.search(Bodega) return json_dumps({ 'inv': bodegas, 'itemgroup_id': uid, 'quantity': current_record }) @app.get(prefix + '/itemgroup/<uid>/transaction') @dbcontext def get_transactions_of_item_group(uid): start, end = parse_start_end_date(request.query) start = start.date() end = end.date() return json_dumps({'results': list(inventoryapi.list_transactions(uid, start, end))}) bind_restapi(prefix + '/pricelist', RestApi(dbapi, PriceList, logging=sync_api.log_price_list_change), app) bind_dbapi_rest(prefix + '/itemgroup', dbapi, ProdItemGroup, app) bind_dbapi_rest(prefix + '/item', dbapi, ProdItem, app) return app