def get_userinfo(self, user, password, command=''): path = urlparse.urlparse(self.path).path dbname = urllib.unquote_plus(path.split('/', 2)[1]) database = backend.get('Database')().connect() cursor = database.cursor() databases = database.list(cursor) cursor.close() if not dbname or dbname not in databases: return True if user: user = int(login(dbname, user, password, cache=False)) if not user: return None else: url = urlparse.urlparse(self.path) query = urlparse.parse_qs(url.query) path = url.path[len(dbname) + 2:] if 'key' in query: key, = query['key'] with Transaction().start(dbname, 0) as transaction: database_list = Pool.database_list() pool = Pool(dbname) if dbname not in database_list: pool.init() Share = pool.get('webdav.share') user = Share.get_login(key, command, path) transaction.cursor.commit() if not user: return None Transaction().start(dbname, user, context={ '_check_access': True, }) Cache.clean(dbname) return user
def _dispatch(request, pool, *args, **kwargs): DatabaseOperationalError = backend.get('DatabaseOperationalError') obj, method = get_object_method(request, pool) if method in obj.__rpc__: rpc = obj.__rpc__[method] else: raise UserError('Calling method %s on %s is not allowed' % (method, obj)) log_message = '%s.%s(*%s, **%s) from %s@%s/%s' log_args = (obj, method, args, kwargs, request.authorization.username, request.remote_addr, request.path) logger.info(log_message, *log_args) user = request.user_id for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start(pool.database_name, user, readonly=rpc.readonly) as transaction: Cache.clean(pool.database_name) try: c_args, c_kwargs, transaction.context, transaction.timestamp \ = rpc.convert(obj, *args, **kwargs) meth = getattr(obj, method) if (rpc.instantiate is None or not is_instance_method(obj, method)): result = rpc.result(meth(*c_args, **c_kwargs)) else: assert rpc.instantiate == 0 inst = c_args.pop(0) if hasattr(inst, method): result = rpc.result(meth(inst, *c_args, **c_kwargs)) else: result = [rpc.result(meth(i, *c_args, **c_kwargs)) for i in inst] except DatabaseOperationalError: if count and not rpc.readonly: transaction.rollback() continue logger.error(log_message, *log_args, exc_info=True) raise except (ConcurrencyException, UserError, UserWarning): logger.debug(log_message, *log_args, exc_info=True) raise except Exception: logger.error(log_message, *log_args, exc_info=True) raise # Need to commit to unlock SQLite database transaction.commit() Cache.resets(pool.database_name) if request.authorization.type == 'session': try: with Transaction().start(pool.database_name, 0) as transaction: Session = pool.get('ir.session') Session.reset(request.authorization.get('session')) except DatabaseOperationalError: logger.debug('Reset session failed', exc_info=True) logger.debug('Result: %s', result) return result
def get_userinfo(self, user, password, command=''): path = urlparse.urlparse(self.path).path dbname = urllib.unquote_plus(path.split('/', 2)[1]) database = Database().connect() cursor = database.cursor() databases = database.list(cursor) cursor.close() if not dbname or dbname not in databases: return True if user: user = int(login(dbname, user, password, cache=False)) if not user: return None else: url = urlparse.urlparse(self.path) query = urlparse.parse_qs(url.query) path = url.path[len(dbname) + 2:] if 'key' in query: key, = query['key'] with Transaction().start(dbname, 0) as transaction: database_list = Pool.database_list() pool = Pool(dbname) if not dbname in database_list: pool.init() Share = pool.get('webdav.share') user = Share.get_login(key, command, path) transaction.cursor.commit() if not user: return None Transaction().start(dbname, user) Cache.clean(dbname) return user
def __call__(self, *args): from trytond.cache import Cache from trytond.transaction import Transaction from trytond.rpc import RPC if self._name in self._object.__rpc__: rpc = self._object.__rpc__[self._name] elif self._name in getattr(self._object, '_buttons', {}): rpc = RPC(readonly=False, instantiate=0) else: raise TypeError('%s is not callable' % self._name) with Transaction().start(self._config.database_name, self._config.user, readonly=rpc.readonly) as transaction: Cache.clean(self._config.database_name) args, kwargs, transaction.context, transaction.timestamp = \ rpc.convert(self._object, *args) meth = getattr(self._object, self._name) if not hasattr(meth, 'im_self') or meth.im_self: result = rpc.result(meth(*args, **kwargs)) else: assert rpc.instantiate == 0 inst = args.pop(0) if hasattr(inst, self._name): result = rpc.result(meth(inst, *args, **kwargs)) else: result = [rpc.result(meth(i, *args, **kwargs)) for i in inst] if not rpc.readonly: transaction.commit() Cache.resets(self._config.database_name) return result
def wrapper(request, pool, *args, **kwargs): DatabaseOperationalError = backend.get('DatabaseOperationalError') readonly_ = readonly # can not modify non local if readonly_ is None: if request.method in {'POST', 'PUT', 'DELETE', 'PATCH'}: readonly_ = False else: readonly_ = True for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start( pool.database_name, 0, readonly=readonly_ ) as transaction: try: Cache.clean(pool.database_name) result = func(request, pool, *args, **kwargs) return result except DatabaseOperationalError: if count and not readonly_: transaction.rollback() continue logger.error('%s', request, exc_info=True) raise except Exception: logger.error('%s', request, exc_info=True) raise # Need to commit to unlock SQLite database transaction.commit() Cache.resets(pool.database_name)
def dispatch_request(self): """ Does the request dispatching. Matches the URL and returns the return value of the view or error handler. This does not have to be a response object. """ DatabaseOperationalError = backend.get('DatabaseOperationalError') req = _request_ctx_stack.top.request if req.routing_exception is not None: self.raise_routing_exception(req) rule = req.url_rule # if we provide automatic options for this URL and the # request came with the OPTIONS method, reply automatically if getattr(rule, 'provide_automatic_options', False) \ and req.method == 'OPTIONS': return self.make_default_options_response() with Transaction().start(self.database_name, 0): Cache.clean(self.database_name) Cache.resets(self.database_name) with Transaction().start(self.database_name, 0, readonly=True): Website = Pool().get('nereid.website') website = Website.get_from_host(req.host) user, company = website.application_user.id, website.company.id for count in range(int(config.get('database', 'retry')), -1, -1): with Transaction().start( self.database_name, user, context={'company': company}, readonly=rule.is_readonly) as txn: try: transaction_start.send(self) rv = self._dispatch_request(req) txn.cursor.commit() except DatabaseOperationalError: # Strict transaction handling may cause this. # Rollback and Retry the whole transaction if within # max retries, or raise exception and quit. txn.cursor.rollback() if count: continue raise except Exception: # Rollback and raise any other exception txn.cursor.rollback() raise else: return rv finally: transaction_stop.send(self)
def login(request, database_name, user, password): Database = backend.get('Database') DatabaseOperationalError = backend.get('DatabaseOperationalError') try: Database(database_name).connect() except DatabaseOperationalError: logger.error('fail to connect to %s', database_name, exc_info=True) return False session = security.login(database_name, user, password) with Transaction().start(database_name, 0): Cache.clean(database_name) Cache.resets(database_name) msg = 'successful login' if session else 'bad login or password' logger.info('%s \'%s\' from %s using %s on database \'%s\'', msg, user, request.remote_addr, request.scheme, database_name) return session
def login(request, database_name, user, password): Database = backend.get('Database') DatabaseOperationalError = backend.get('DatabaseOperationalError') try: Database(database_name).connect() except DatabaseOperationalError: logger.error('fail to connect to %s', database_name, exc_info=True) return False session = security.login(database_name, user, password) with Transaction().start(database_name, 0): Cache.clean(database_name) Cache.resets(database_name) msg = 'successful login' if session else 'bad login or password' logger.info('%s \'%s\' from %s using %s on database \'%s\'', msg, user, request.remote_addr, request.scheme, database_name) return session
def __init__(self, database_name=None, user='******', database_type=None, language='en_US', password='', config_file=None): super(TrytondConfig, self).__init__() from trytond.config import CONFIG CONFIG.update_etc(config_file) CONFIG.set_timezone() if database_type is not None: CONFIG['db_type'] = database_type from trytond.pool import Pool from trytond import backend from trytond.protocols.dispatcher import create from trytond.cache import Cache from trytond.transaction import Transaction self.database_type = CONFIG['db_type'] if database_name is None: if self.database_type == 'sqlite': database_name = ':memory:' else: database_name = 'test_%s' % int(time.time()) self.database_name = database_name self._user = user self.config_file = config_file Pool.start() with Transaction().start(None, 0) as transaction: cursor = transaction.cursor databases = backend.get('Database').list(cursor) if database_name not in databases: create(database_name, CONFIG['admin_passwd'], language, password) database_list = Pool.database_list() self.pool = Pool(database_name) if database_name not in database_list: self.pool.init() with Transaction().start(self.database_name, 0) as transaction: Cache.clean(database_name) User = self.pool.get('res.user') transaction.context = self.context self.user = User.search([ ('login', '=', user), ], limit=1)[0].id with transaction.set_user(self.user): self._context = User.get_preferences(context_only=True) Cache.resets(database_name)
def wrapper(database, *args, **kwargs): DatabaseOperationalError = backend.get('DatabaseOperationalError') Cache.clean(database) # Intialise the pool. The init method is smart enough not to # reinitialise if it is already initialised. Pool(database).init() # get the context from the currently logged in user with Transaction().start(database, g.current_user, readonly=True): User = Pool().get('res.user') context = User.get_preferences(context_only=True) readonly = request.method == 'GET' for count in range(int(CONFIG['retry']), -1, -1): with Transaction().start(database, g.current_user, readonly=readonly, context=context) as transaction: cursor = transaction.cursor try: result = function(*args, **kwargs) if not readonly: cursor.commit() except DatabaseOperationalError, exc: cursor.rollback() if count and not readonly: continue result = jsonify(error=unicode(exc)), 500 except UserError, exc: cursor.rollback() result = jsonify( error={ 'type': 'UserError', 'message': exc.message, 'description': exc.description, 'code': exc.code, }), 500 current_app.logger.error(traceback.format_exc()) except Exception, exc: cursor.rollback() result = jsonify(error=unicode(exc)), 500 current_app.logger.error(traceback.format_exc())
def wrapper(database, *args, **kwargs): DatabaseOperationalError = backend.get('DatabaseOperationalError') Cache.clean(database) # Intialise the pool. The init method is smart enough not to # reinitialise if it is already initialised. Pool(database).init() # get the context from the currently logged in user with Transaction().start(database, g.current_user, readonly=True): User = Pool().get('res.user') context = User.get_preferences(context_only=True) readonly = request.method == 'GET' for count in range(int(CONFIG['retry']), -1, -1): with Transaction().start( database, g.current_user, readonly=readonly, context=context) as transaction: cursor = transaction.cursor try: result = function(*args, **kwargs) if not readonly: cursor.commit() except DatabaseOperationalError, exc: cursor.rollback() if count and not readonly: continue result = jsonify(error=unicode(exc)), 500 except UserError, exc: cursor.rollback() result = jsonify(error={ 'type': 'UserError', 'message': exc.message, 'description': exc.description, 'code': exc.code, }), 500 current_app.logger.error(traceback.format_exc()) except Exception, exc: cursor.rollback() result = jsonify(error=unicode(exc)), 500 current_app.logger.error(traceback.format_exc())
def start(self, database_name, user, readonly=False, context=None, close=False, autocommit=False, _nocache=False): ''' Start transaction ''' Database = backend.get('Database') assert self.user is None assert self.database is None assert self.close is None assert self.context is None if not database_name: database = Database().connect() else: database = Database(database_name).connect() Flavor.set(Database.flavor) self.connection = database.get_connection(readonly=readonly, autocommit=autocommit) self.user = user self.database = database self.readonly = readonly self.close = close self.context = context or {} self.create_records = {} self.delete_records = {} self.delete = {} self.timestamp = {} self.counter = 0 self._datamanagers = [] self._sub_transactions = [] self._nocache = _nocache if not _nocache: from trytond.cache import Cache try: Cache.clean(database.name) except BaseException: self.stop(False) raise return self
def wrapper(*args, **kwargs): _db = Tdb._db _readonly = True if readonly is not None: _readonly = readonly elif 'request' in kwargs: _readonly = not (kwargs['request'].method in ('PUT', 'POST', 'DELETE', 'PATCH')) _user = user or 0 _context = {} _retry = Tdb._retry or 0 _is_open = (Transaction().cursor) if not _is_open: with Transaction().start(_db, 0): Cache.clean(_db) _context.update(default_context()) else: # Transaction().new_cursor(readonly=_readonly) pass _context.update(context or {}) # _context.update({'company': Tdb._company}) for count in range(_retry, -1, -1): with NoTransaction() if _is_open else Transaction().start( _db, _user, readonly=_readonly, context=_context): cursor = Transaction().cursor if withhold: cursor.cursor.withhold = True try: result = func(*args, **kwargs) if not _readonly: cursor.commit() except DatabaseOperationalError: cursor.rollback() if count and not _readonly: continue raise except Exception: cursor.rollback() raise Cache.resets(_db) return result
class CategoryOfProduct(): """ Manages the category of the products """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Category = pool.get('product.category') def __init__(self): logger.info('Inside CategoryOfProduct') def create_category(self, name): """ creates a new category :param name: category name :return: boolean values True if the category was saved """ logger.info('CategoryOfProduct create category initiated') try: newname = name with Transaction().start(DBNAME, 1) as transaction: categories = self.Category.search([('name', '=', newname), ('parent', '=', 'Dish')]) parent = self.Category.search(['name', '=', 'Dish'])[0] if categories: return False category = self.Category() # call api for creation todo category.parent = parent category.name = newname try: category.save() transaction.cursor.commit() return True except Exception: # print sys.exc_info() return False except Exception: if settings.level == 10: logger.exception('raised exception') return False def search_categories(self): """ lists all the categories :return:list of all category names """ with Transaction().start(DBNAME, 1): categorieslist = self.Category.search(['parent', '=', 'Dish']) return [i.name for i in categorieslist]
def get_userinfo(self, user, password, command=''): path = urllib.parse.urlparse(self.path).path dbname = urllib.parse.unquote_plus(path.split('/', 2)[1]) with Transaction().start(dbname, 0, close=True) as transaction: databases = transaction.database.list() if not dbname or dbname not in databases: return True if user: user = str(user) parameters = {'password': password} user = login(dbname, user, parameters, cache=False) if not user: return None user = int(user) else: url = urllib.parse.urlparse(self.path) query = urllib.parse.parse_qs(url.query) path = url.path[len(dbname) + 2:] if 'key' in query: key, = query['key'] with Transaction().start(dbname, 0) as transaction: database_list = Pool.database_list() pool = Pool(dbname) if dbname not in database_list: pool.init() Share = pool.get('webdav.share') user = Share.get_login(key, command, path) transaction.commit() if not user: return None Transaction().start(dbname, user, context={ '_check_access': True, }, autocommit=True) Cache.clean(dbname) return user
def __init__(self, database=None, user='******', config_file=None): super(TrytondConfig, self).__init__() if not database: database = os.environ.get('TRYTOND_DATABASE_URI') else: os.environ['TRYTOND_DATABASE_URI'] = database if not config_file: config_file = os.environ.get('TRYTOND_CONFIG') from trytond.config import config config.update_etc(config_file) from trytond.pool import Pool from trytond.cache import Cache from trytond.transaction import Transaction self.database = database database_name = None if database: uri = urlparse.urlparse(database) database_name = uri.path.strip('/') if not database_name: database_name = os.environ['DB_NAME'] self.database_name = database_name self._user = user self.config_file = config_file Pool.start() self.pool = Pool(database_name) self.pool.init() with Transaction().start(self.database_name, 0) as transaction: Cache.clean(database_name) User = self.pool.get('res.user') transaction.context = self.context self.user = User.search([ ('login', '=', user), ], limit=1)[0].id with transaction.set_user(self.user): self._context = User.get_preferences(context_only=True) Cache.resets(database_name)
def execute(app, database, user, payload_json): """ Execute the task identified by the given payload in the given database as `user`. """ if database not in Pool.database_list(): # Initialise the database if this is the first time we see the # database being used. with Transaction().start(database, 0, readonly=True): Pool(database).init() with Transaction().start(database, 0): Cache.clean(database) with Transaction().start(database, user) as transaction: Async = Pool().get('async.async') DatabaseOperationalError = backend.get('DatabaseOperationalError') # De-serialize the payload in the transaction context so that # active records are constructed in the same transaction cache and # context. payload = Async.deserialize_payload(payload_json) try: with Transaction().set_context(payload['context']): results = Async.execute_payload(payload) except RetryWithDelay, exc: # A special error that would be raised by Tryton models to # retry the task after a certain delay. Useful when the task # got triggered before the record is ready and similar cases. transaction.cursor.rollback() raise app.retry(exc=exc, delay=exc.delay) except DatabaseOperationalError, exc: # Strict transaction handling may cause this. # Rollback and Retry the whole transaction if within # max retries, or raise exception and quit. transaction.cursor.rollback() raise app.retry(exc=exc)
class Water(Pest): """ Manages the Water Reports """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Water = pool.get('health_and_hygiene.water_control_test') Pest = Water
class ShiftList(): """ provides a list of shifts """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Shift = pool.get('attendance.shiftdetails') def __init__(self): logger.info('Inside ShiftList') def load_shifts(self): """ loads a list of shifts :return:list of dictionary consisting details of a shift """ with Transaction().start(DBNAME, 1): shift = self.Shift.search([]) if shift: lines = [] for i in shift: data = {} data['slot'] = i.slot data['in_time'] = i.in_time.strftime('%H:%M %p') data['out_time'] = i.out_time.strftime('%H:%M %p') data['monday'] = i.monday data['tuesday'] = i.tuesday data['wednesday'] = i.wednesday data['thursday'] = i.thursday data['friday'] = i.friday data['saturday'] = i.saturday data['sunday'] = i.sunday lines.append(data) return lines return False
class SalarySettingList(): """ provides a list of salary settings """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() SalarySetting = pool.get('payroll.salarysettings') def __init__(self): logger.info('Inside SalarySettingList') def load_salary_setting(self): """ loads the list of salary settings :return:list of dictionary consisting of salary settings values """ lines = [] with Transaction().start(DBNAME, 1): salary_list = self.SalarySetting.search([]) for i in salary_list: for j in i.designation: data = {} data['designation'] = j.name if not i.da_percent: continue data['da'] = Decimal(i.da_percent).to_eng_string() data['hra'] = Decimal(i.hra_percent).to_eng_string() data['pf'] = Decimal(i.pf_percent).to_eng_string() data['esi'] = Decimal(i.esi_percent).to_eng_string() data['proftax'] = Decimal( i.professional_tax_percent).to_eng_string() lines.append(data) return lines
class WasteIngredients(): """ Manages the wasted Ingredients """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Move = pool.get('stock.move') def __init__(self): logger.info('Inside WasteIngredients') def find_itemdiscard(self, from_date, to_date): """ shows the ingredients discarded on those days :param from_date:start date :param to_date:end date :return:list of moves """ dataobj = [] with Transaction().start(DBNAME, 1): datalist = self.Move.search([('create_date', '>=', from_date), ('create_date', '<=', to_date)]) for i in datalist: if i.product.description == 'Stock' and i.reason_for_discard: dictionary = {} dictionary['code'] = i.product.code dictionary['item'] = i.product.template.name dictionary['category'] = i.product.template.category.name dictionary['quantity'] = i.quantity dictionary['units'] = i.uom.name dictionary['reason_for_discard'] = i.reason_for_discard dataobj.append(dictionary) return dataobj
class EmployeeManagementList(): """ Lists out the general registered employee list """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Employee = pool.get('company.employee') def __init__(self): logger.info('Inside EmployeeManagementList') def load_data(self): """ loads the employee details :return:list with the dictionary of employee data """ with Transaction().start(DBNAME, 1): employee = self.Employee.search([]) lines = [] for i in employee: data = {} data['employee_id'] = str(i.employee_id) data['department'] = i.department.name.title() data['designation'] = i.designation.name.title() data['name'] = i.name data['gender'] = i.gender.title() data['dob'] = i.dob.strftime("%d-%m-%Y") data['shift'] = i.shift.slot lines.append(data) return lines
class AccessUser(): """ Validate the user """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Tax = pool.get('account.tax') User = pool.get('res.user') Group = pool.get('res.group') def __init__(self): self.conf = config.get_config() self.userid = '' # self.tax = self.Tax.find([('name', '=', 'Restaurant Tax')])[0] def validate_user(self, user, password): """ :param user:username of the user :param password: password of the user :return: valid id if password is correct else 0 """ user = user password = password try: with Transaction().start(DBNAME, 1): self.userid = self.User.get_login(user, password) user = self.User(id=self.userid) groups = user.groups tabs = {} if groups: group = groups[0] tabs = group.tabs.copy() if group.tabs else tabs return self.userid, tabs except Exception: if settings.level == 10: logger.exception('raised exception') return 0 def get_user(self, id): # todo deprecate this. """ gets the user with the corresponding id. No need for the Transaction because it is called inside a transaction. :param id:the id of the user :return:the user """ try: user = self.User(id=id) return user except Exception: if settings.level == 10: logger.exception('raised exception') return None def get_details(self): """ :return: all the details of the user """ try: with Transaction().start(DBNAME, 1): tax_obj = self.Tax.search([('name', '=', 'Restaurant Tax')])[0] user = self.User(id=self.userid) company = user.main_company name = company.rec_name street = company.party.addresses[0].street city = company.party.addresses[0].city pin = company.party.addresses[0].zip longitude = company.longitude latitude = company.latitude apikey = company.api fssai = company.fssai if company.fssai else None tin = company.tin if company.tin else None tax = tax_obj.rate.multiply(100).to_eng() profileid = user.login password = user.password details = { 'name': name, 'street': street, 'city': city, 'pin': pin, 'longitude': longitude, 'latitude': latitude, 'apikey': apikey, 'tax': tax, 'profileid': profileid, 'password': password, 'fssai': fssai, 'tin': tin } return details except Exception: if settings.level == 10: logger.exception('raised exception') return {} def save_details(self, details): """ :param details: dict of details :return:boolean values """ try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = Context user = self.User(id=self.userid) tax = self.Tax.search([('name', '=', 'Restaurant Tax')])[0] details = details company = user.main_company party = company.party party.name = details['name'] settings.company = details['name'] settings.set_settings() address = party.addresses[0] address.street = details['street'] address.city = details['city'] address.zip = details['pin'] company.longitude = details['longitude'] company.latitude = details['latitude'] company.api = details['apikey'] company.fssai = details['fssai'] company.tin = details['tin'] tax.rate = Decimal(details['tax']).divide(100) user.login = details['profileid'] if details['password']: user.password = details['password'] user.save() address.save() party.save() company.save() tax.save() transaction.cursor.commit() return True except Exception: if settings.level == 10: logger.exception('raised exception') return False def get_group_list(self): """ gets the list of available groups :return:none """ try: with Transaction().start(DBNAME, 1): group_list = tuple( i.name for i in self.Group.search(['create_uid', '>', 0])) return group_list except Exception: if settings.level == 10: logger.exception('raised exception') return None def save_group(self, name): """ saves a group :param name: name of the group :return:boolean True and False for saved or not """ try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = Context group = self.Group() group.name = name group.save() transaction.cursor.commit() return True, 'Saved group successfully' except Exception: return False, 'Duplicate Entry' def get_roles(self, group_name): """ get the roles assigned to the group :param group_name: the name of the group :return:the role tuple """ try: with Transaction().start(DBNAME, 1): group = self.Group.search(['name', '=', group_name])[-1] roles = tuple(group.tabs.keys() if group.tabs else []) return roles except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Duplicate Entry' def delete_group(self, group_name): """ deletes a group :param group_name:the name of the group :return:boolean value Tru if successfully deleted """ try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = Context users = self.User.search(['groups', '=', group_name]) if users: return False, 'Users exits in this group' else: group = self.Group.search(['name', '=', group_name])[-1] group.delete((group, )) transaction.cursor.commit() return True, 'Deleted group successfully' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Error occurred' def add_role(self, group_name, role): """ adds role to the group :param group_name:the group_name :param role:the roles :return:boolean """ try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = Context group = self.Group.search(['name', '=', group_name])[-1] if group.tabs: group.tabs = dict( group.tabs, **{role: True} ) # some weird behaviour of trytond dict fields hence explicit assignment else: group.tabs = {role: True} group.save() transaction.cursor.commit() return True, 'Added role successfully!!' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Error occurred!!' def delete_role(self, group_name, role): """deletes a role of the user""" try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = Context group = self.Group.search(['name', '=', group_name])[-1] if group.tabs: tab = group.tabs _, group.tabs = tab.pop(role), tab group.save() transaction.cursor.commit() return True, 'Deleted role successfully!!' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Error occurred!!' def list_group_users(self, group_name): """ lists the users in the group :param group_name: group name :return:tuple of names of users """ try: with Transaction().start(DBNAME, 1): users = self.User.search(['groups', '=', group_name]) return tuple(i.name for i in users) except Exception: if settings.level == 10: logger.exception('raised exception') return None def add_user(self, group_name, user_name): """ adds a user to the group :param group_name:the name of the group :param user_name:the name of the user :return:boolean with the message as tuple """ try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = Context user = self.User.search(['name', '=', user_name])[-1] if user.groups: return False, 'User exists in group %s' % user.groups[ 0].name else: group = self.Group.search(['name', '=', group_name])[-1] user.groups = (group, ) user.save() transaction.cursor.commit() return True, 'User added successfully' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some Backend error.' def delete_table_user(self, username): """ deletes the user from the group :param username: the name of the user :return:boolean value with the message """ try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = Context user = self.User.search(['name', '=', username])[-1] user.groups = tuple() # each user can be assigned to only # a single group so pop will remove the only group user.save() transaction.cursor.commit() return True, 'Deleted user successfully!!' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Error occurred!!' def fill_users(self, group_name): """ get the name of the users not belonging the group :param group_name: the name of the group :return:the list of users """ try: with Transaction().start(DBNAME, 1): users = tuple(i.name for i in self.User.search([ 'OR', [('groups', '=', None)], [('groups', '!=', group_name)] ])) return users except Exception: if settings.level == 10: logger.exception('raised exception') return None def get_userlist(self): """ gets a list of users except the admin :return:tuple of user names """ try: with Transaction().start(DBNAME, 1): return tuple(i.name for i in self.User.search([]) if i.id != 1) except Exception: if settings.level == 10: logger.exception('raised exception') return None def delete_user(self, name): """ deletes a user. :param name: the name of the user :return:boolean value with the message """ try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = Context user = self.User.search(['name', '=', name]) if user: user_del = user[0] user_del.delete((user_del, )) transaction.cursor.commit() return True, 'Successfully deleted' return False, 'User Not Found' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Could not delete User' def get_user_details(self, name): """ gets the details of the user selected :param name:the name of the user :return:the detail tuple """ try: with Transaction().start(DBNAME, 1): user = self.User.search(['name', '=', name]) if user: user = user[-1] return user.name, user.login, user.password except Exception: if settings.level == 10: logger.exception('raised exception') return [] def save_user_details(self, name, username, password): """ save the details of the user :param name:the name of the user :param username:the login username :param password:the password :return:the boolean value with the message """ try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = Context user = self.User.search(['name', '=', name]) if user: user = user[-1] user.login = username if password: user.password = password user.save() transaction.cursor.commit() return True, 'Successfully saved the details' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some error occurred while saving details' def create_user(self, name, username, password): """ creates a new user :param name:the name of the user :param username:the login username :param password: the corresponding password :return:boolean value and the message """ try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = Context user = self.User.search(['name', '=', name]) if user: return False, 'User already exists' else: user = self.User() user.name = name user.login = username user.password = password user.save() transaction.cursor.commit() return True, 'Successfully created the user' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some error occurred'
def dispatch_request(self): """ Does the request dispatching. Matches the URL and returns the return value of the view or error handler. This does not have to be a response object. """ DatabaseOperationalError = backend.get('DatabaseOperationalError') req = _request_ctx_stack.top.request if req.routing_exception is not None: self.raise_routing_exception(req) rule = req.url_rule # if we provide automatic options for this URL and the # request came with the OPTIONS method, reply automatically if getattr(rule, 'provide_automatic_options', False) \ and req.method == 'OPTIONS': return self.make_default_options_response() with Transaction().start(self.database_name, 0): Cache.clean(self.database_name) Cache.resets(self.database_name) with Transaction().start(self.database_name, 0, readonly=True): user = current_website.application_user.id website_context = current_website.get_context() website_context.update({ 'company': current_website.company.id, }) language = current_locale.language.code # pop locale if specified in the view_args req.view_args.pop('locale', None) active_id = req.view_args.pop('active_id', None) for count in range(int(config.get('database', 'retry')), -1, -1): with Transaction().start(self.database_name, user, context=website_context, readonly=rule.is_readonly) as txn: try: transaction_start.send(self) rv = self._dispatch_request(req, language=language, active_id=active_id) txn.commit() transaction_commit.send(self) except DatabaseOperationalError: # Strict transaction handling may cause this. # Rollback and Retry the whole transaction if within # max retries, or raise exception and quit. txn.rollback() if count: continue raise except Exception: # Rollback and raise any other exception txn.rollback() raise else: return rv finally: transaction_stop.send(self)
class Customer(): """ Functions around customer and his details """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Invoice = pool.get('account.invoice') Party = pool.get('party.party') def __init__(self): logger.info('Inside Billing Customer') def search_customers(self): """ list all the customers and his dues :return: list of dictionary """ try: with Transaction().start(DBNAME, 1): party_list = self.Party.search([('categories', '=', 'Customer') ]) data = [] for member in party_list: invoice_list = self.Invoice.search([ ('party', '=', member.id), ('state', '=', 'draft') ]) customer = {} customer['code'] = member.pan customer['name'] = member.name due = Decimal(0) for invoice in invoice_list: due += invoice.total_amount customer['total'] = due.to_eng() data.append(customer) return data except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Failed crediting' def search_item(self, item): """ :model:the completer model :item:the text typed in the lineedit :return: searches each instance of the menu item number """ try: with Transaction().start(DBNAME, 1): menu = self.Party.search([('name', 'like', '%' + item + '%'), ('categories', '=', 'Customer')]) customers = tuple(i.pan + '-' + i.name for i in menu) return customers except Exception: if settings.level == 10: logger.exception('raised exception') return False def search_customer_id(self, code): """ searches the customer in according to the id :param code: the code of the customer to search :return: string """ try: with Transaction().start(DBNAME, 1): party_list = self.Party.search([('pan', '=', code), ('categories', '=', 'Customer') ]) if party_list: customer = party_list[0] return customer.pan + '-' + customer.name else: return None except Exception: if settings.level == 10: logger.exception('raised exception') return False
def dispatch(host, port, protocol, database_name, user, session, object_type, object_name, method, *args, **kwargs): Database = backend.get('Database') DatabaseOperationalError = backend.get('DatabaseOperationalError') if object_type == 'common': if method == 'login': try: database = Database(database_name).connect() cursor = database.cursor() cursor.close() except Exception: return False res = security.login(database_name, user, session) with Transaction().start(database_name, 0): Cache.clean(database_name) Cache.resets(database_name) msg = res and 'successful login' or 'bad login or password' logger.info('%s \'%s\' from %s:%d using %s on database \'%s\'', msg, user, host, port, protocol, database_name) return res or False elif method == 'logout': name = security.logout(database_name, user, session) logger.info('logout \'%s\' from %s:%d ' 'using %s on database \'%s\'', name, host, port, protocol, database_name) return True elif method == 'version': return __version__ elif method == 'list_lang': return [ ('bg_BG', 'Български'), ('ca_ES', 'Català'), ('cs_CZ', 'Čeština'), ('de_DE', 'Deutsch'), ('en_US', 'English'), ('es_AR', 'Español (Argentina)'), ('es_EC', 'Español (Ecuador)'), ('es_ES', 'Español (España)'), ('es_CO', 'Español (Colombia)'), ('fr_FR', 'Français'), ('lt_LT', 'Lietuvių'), ('nl_NL', 'Nederlands'), ('ru_RU', 'Russian'), ('sl_SI', 'Slovenščina'), ] elif method == 'db_exist': try: database = Database(*args, **kwargs).connect() cursor = database.cursor() cursor.close(close=True) return True except Exception: return False elif method == 'list': if not config.getboolean('database', 'list'): raise Exception('AccessDenied') with Transaction().start(None, 0, close=True) as transaction: return transaction.database.list(transaction.cursor) elif method == 'create': return create(*args, **kwargs) elif method == 'restore': return restore(*args, **kwargs) elif method == 'drop': return drop(*args, **kwargs) elif method == 'dump': return dump(*args, **kwargs) return elif object_type == 'system': database = Database(database_name).connect() database_list = Pool.database_list() pool = Pool(database_name) if database_name not in database_list: pool.init() if method == 'listMethods': res = [] for type in ('model', 'wizard', 'report'): for object_name, obj in pool.iterobject(type=type): for method in obj.__rpc__: res.append(type + '.' + object_name + '.' + method) return res elif method == 'methodSignature': return 'signatures not supported' elif method == 'methodHelp': res = [] args_list = args[0].split('.') object_type = args_list[0] object_name = '.'.join(args_list[1:-1]) method = args_list[-1] obj = pool.get(object_name, type=object_type) return pydoc.getdoc(getattr(obj, method)) for count in range(config.getint('database', 'retry'), -1, -1): try: user = security.check(database_name, user, session) except DatabaseOperationalError: if count: continue raise break database_list = Pool.database_list() pool = Pool(database_name) if database_name not in database_list: with Transaction().start(database_name, user, readonly=True) as transaction: pool.init() obj = pool.get(object_name, type=object_type) if method in obj.__rpc__: rpc = obj.__rpc__[method] else: raise UserError('Calling method %s on %s %s is not allowed!' % (method, object_type, object_name)) log_message = '%s.%s.%s(*%s, **%s) from %s@%s:%d/%s' log_args = (object_type, object_name, method, args, kwargs, user, host, port, database_name) logger.info(log_message, *log_args) for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start(database_name, user, readonly=rpc.readonly) as transaction: Cache.clean(database_name) try: c_args, c_kwargs, transaction.context, transaction.timestamp \ = rpc.convert(obj, *args, **kwargs) meth = getattr(obj, method) if (rpc.instantiate is None or not is_instance_method(obj, method)): result = rpc.result(meth(*c_args, **c_kwargs)) else: assert rpc.instantiate == 0 inst = c_args.pop(0) if hasattr(inst, method): result = rpc.result(meth(inst, *c_args, **c_kwargs)) else: result = [rpc.result(meth(i, *c_args, **c_kwargs)) for i in inst] if not rpc.readonly: transaction.cursor.commit() except DatabaseOperationalError: transaction.cursor.rollback() if count and not rpc.readonly: continue raise except (NotLogged, ConcurrencyException, UserError, UserWarning): logger.debug(log_message, *log_args, exc_info=True) transaction.cursor.rollback() raise except Exception: logger.error(log_message, *log_args, exc_info=True) transaction.cursor.rollback() raise Cache.resets(database_name) with Transaction().start(database_name, 0) as transaction: pool = Pool(database_name) Session = pool.get('ir.session') try: Session.reset(session) except DatabaseOperationalError: logger.debug('Reset session failed', exc_info=True) # Silently fail when reseting session transaction.cursor.rollback() else: transaction.cursor.commit() logger.debug('Result: %s', result) return result
class WeeklyMenu(): """ Provides a mechanism to manage menu per week """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Product = pool.get('product.product') Weekly = pool.get('weeklymenu.weeklymenu') Ingredient = pool.get('product.ingredientsofdish') def __init__(self, code=None, name=None, day=None, quantity=None): logger.info('Inside WeeklyMenu') self.code = code self.name = name self.day = day self.quantity = quantity self.manage_inventory = None self.process = None self.release = ReleaseDiscard() with Transaction().start(DBNAME, 1): self.process = CalculateDayIngredients() self.manage_inventory = ManageInventory(kitchen=True) def load_dish_per_Day(self): """ loads the menu of the day :param day: day of the week :return: list of dictionary of dishes and its corresponding data """ with Transaction().start(DBNAME, 1): weeklist = self.Weekly.search([('day', '=', self.day)]) return_list = [] for i in weeklist: dictionary = {} product = i.dish if date.today().strftime('%A').lower() == self.day: value = self.calculate_availability(product) else: value = 0 dictionary['item_no'] = str(product.code) dictionary['item'] = product.template.name dictionary['category'] = product.template.category.name dictionary['rate'] = product.list_price_uom.to_eng() dictionary['per_day'] = str(i.default_quantity) dictionary['available'] = str(value) if value else str(0) return_list.append(dictionary) return return_list def load_dish_notin_per_Day(self): """ loads rows not in the menu of the day :return: list of rows """ with Transaction().start(DBNAME, 1): weeklist = self.Weekly.search([('day', '=', self.day)]) menulist = self.Product.search( [('description', '=', 'Dish'), ('type', '=', 'goods'), ('id', 'not in', [i.dish.id for i in weeklist])]) return_list = [] for i in menulist: dictionary = {} dictionary['item_no'] = str(i.code) dictionary['item'] = i.template.name dictionary['category'] = i.template.category.name dictionary['rate'] = i.list_price_uom.to_eng() return_list.append(dictionary) return return_list def save_dish_per_day(self, args): """ saves the dish to the day of the week :param args: list of dictionary of dish details and day :return:boolean """ logger.info('WeeklyMenu save dish initiated') try: with Transaction().start(DBNAME, 1) as transaction: for i in args: week = self.Weekly() product = \ self.Product.search( [('code', '=', i['code']), ('description', '=', 'Dish'), ('type', '=', 'goods')])[ -1] week.dish = product week.day = i['day'] week.default_quantity = int(i['quantity']) week.save() transaction.cursor.commit() return True except Exception: if settings.level == 10: logger.exception('raised exception') return False def update_weekly_row(self): """ updates the weekly data info of the dish :return:boolean True if the process was successful """ logger.info('WeeklyMenu save weekly menu initiated') try: with Transaction().start(DBNAME, 1) as transaction: weekly = self.Weekly.search([('dish', '=', self.name), ('day', '=', self.day)]) week = weekly[-1] week.default_quantity = int(self.quantity) week.save() transaction.cursor.commit() return True except Exception: if settings.level == 10: logger.exception('raised exception') return False def remove_weekly_row(self): """ removes the entry form the day :return: boolean value True if the process was successful """ logger.info('WeeklyMenu remove weekly row initiated') try: with Transaction().start(DBNAME, 1) as transaction: weekly = self.Weekly.search([('dish', '=', self.name), ('day', '=', self.day)]) self.Weekly.delete(weekly) transaction.cursor.commit() return True except Exception: if settings.level == 10: logger.exception('raised exception') return False def remove_from_all_days(self): """ removes the menu entry from all the weekdays :return:boolean value True if the dish was deleted successfully """ logger.info('WeeklyMenu remove from all day initiated') try: with Transaction().start(DBNAME, 1) as transaction: weekly = self.Weekly.search([('dish', '=', self.name)]) self.Weekly.delete(weekly) transaction.cursor.commit() return True except Exception: if settings.level == 10: logger.exception('raised exception') return False def calculate_availability(self, product): # should be used inside transactions """calculate if the dish is available""" logger.info('WeeklyMenu calculating availability') required = {} counter_list = [] counter = 0 try: serve = product.serve ingredientslist = self.Ingredient.search(['dish', '=', product.id]) for ingredient_obj in ingredientslist: namekey = ingredient_obj.ingredient.template.name new_uom, new_quantity = self.process.convert_uom_to_higher(ingredient_obj.quantity_uom, ingredient_obj.quantity) required[namekey] = (new_uom, new_quantity) available = self.manage_inventory.get_stock() for i, j in required.iteritems(): if available.get(i): counter_list.append(Decimal(available[i][1]) / j[1]) else: return False counter = min(counter_list) if counter_list else Decimal(0) return counter.quantize(Decimal('0')) except Exception: if settings.level == 10: logger.exception('raised exception') return False def use_dish(self, product, quantity): # should be used inside transactions """releases the stock from the inventory for each time a dish is used""" logger.info('WeeklyMenu use_dish initiated') required = {} try: serve = product.serve ingredientslist = self.Ingredient.search(['dish', '=', product.id]) for j in ingredientslist: namekey = j.ingredient.template.name new_uom, new_quantity = self.process.convert_uom_to_higher(j.quantity_uom, j.quantity) required[namekey] = (new_uom, new_quantity) for _ in range(quantity): for i, j in required.iteritems(): status = self.release.ingredient_used(item=i, quantity=j[1]) if not status: return False return True except Exception: if settings.level == 10: logger.exception('raised exception') return False def cancel_dish(self, product, quantity): # should be used inside transactions """cancels the dish and restores the stock into the inventory""" logger.info('WeeklyMenu cancel_dish initiated') required = {} try: serve = product.serve ingredientslist = self.Ingredient.search(['dish', '=', product.id]) for j in ingredientslist: namekey = j.ingredient.template.name new_uom, new_quantity = self.process.convert_uom_to_higher(j.quantity_uom, j.quantity) required[namekey] = (new_uom, new_quantity) for _ in range(quantity): for i, j in required.iteritems(): status = self.release.ingredient_used_canceled(item=i, quantity=j[1]) if not status: return False return True except Exception: if settings.level == 10: logger.exception('raised exception') return False
class Search(): """ Searches through the bills """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Invoice = pool.get('account.invoice') Party = pool.get('party.party') invoice_list = object Ticket = pool.get('account.ticket') User = pool.get('res.user') def __init__(self): logger.info('Inside Search') def search_bills(self, from_date=None, to_date=None, bill_no=None, customercode=None): """ searches for the bill with the start and end date or the bill number :param from_date: start date :param to_date:end date :param bill_no:the bill number :return:the details """ return_list = [] try: with Transaction().start(DBNAME, 1): user = self.User(id=1) party = user.main_company.party if bill_no: self.invoice_list = self.Invoice.search([('id', '=', str(bill_no))]) if self.invoice_list: from_date, to_date = None, None if from_date and to_date: date = to_date to_date = datetime.strptime(date, '%Y-%m-%d') + timedelta( hours=23, minutes=59, seconds=59) # print "here at the search", datetime.strptime(from_date, '%Y-%m-%d'), to_date self.invoice_list = self.Invoice.search([ ('create_date', '>=', datetime.strptime(from_date, '%Y-%m-%d')), ('create_date', '<=', to_date) ]) if customercode: if customercode == 'All': self.invoice_list = self.Invoice.search([('state', '=', 'draft')]) else: party, = self.Party.search([('pan', '=', customercode), ('categories', '=', 'Customer')]) self.invoice_list = self.Invoice.search([ ('party', '=', party.id), ('state', '=', 'draft') ]) for i in self.invoice_list: if i.party.id != party.id: # to filter purchase bills continue dictionary = {} dictionary['bill_no'] = str(i.id) dictionary['date'] = i.create_date.strftime( "%d %b %y") if i.create_date else '' dictionary['total'] = i.total_amount.to_eng() dictionary['code'] = i.party.pan dictionary['name'] = i.party.name.title() return_list.append(dictionary) return return_list except Exception: if settings.level == 10: logger.exception('raised exception') return return_list def select_bill(self, id): """ shows the details of the bill of which the id is passed :param id:the id of the bill :return: """ lines = [] return_list = [] try: with Transaction().start(DBNAME, 1): invoice = self.Invoice.search([('id', '=', id)])[-1] for i in invoice.lines: dictionary = {} dictionary['item_no'] = str(i.product.code) dictionary['item'] = i.product.template.name dictionary['rate'] = i.product.list_price_uom.to_eng() dictionary['quantity'] = str(int(i.quantity)) dictionary['amount'] = i.amount.to_eng() lines.append(dictionary) return_list.append(lines) dictionary = {} dictionary['total'] = invoice.untaxed_amount.to_eng() dictionary['tax'] = str( self.percent(invoice.total_amount, invoice.untaxed_amount)) dictionary['tax_amount'] = invoice.tax_amount.to_eng() round_off_value = invoice.total_amount - int( invoice.total_amount) dictionary['roundoff'] = Decimal( Decimal(1) - round_off_value).to_eng() if round_off_value else Decimal( 0).to_eng() dictionary['grand'] = Decimal( invoice.total_amount + Decimal(dictionary['roundoff'])).quantize( Decimal('1.00')).to_eng() dictionary['state'] = invoice.state dictionary['customer'] = invoice.party.pan return_list.append(dictionary) return return_list except Exception: if settings.level == 10: logger.exception('raised exception') return return_list def percent(self, taxed, untaxed): """ returns the tax value for the corresponding values :param taxed:the taxed amount :param untaxed:the untaxed amount :return:the percentage value """ try: percent = (((taxed - untaxed) * 100) / untaxed) return round(percent, 2) except Exception: if settings.level == 10: logger.exception('raised exception') return 0 def search_tickets(self, from_date=None, to_date=None, ticket_no=None): """ searches for the bill with the start and end date or the bill number :param from_date: start date :param to_date:end date :param bill_no:the bill number :return:the details """ return_list = [] try: with Transaction().start(DBNAME, 1): if ticket_no: self.ticket_list = self.Ticket.search([('id', '=', str(ticket_no))]) if self.ticket_list: from_date, to_date = None, None if from_date and to_date: date = to_date to_date = datetime.strptime(date, '%Y-%m-%d') + timedelta( hours=23, minutes=59, seconds=59) # print "here at the search", datetime.strptime(from_date, '%Y-%m-%d'), to_date self.ticket_list = self.Ticket.search([ ('create_date', '>=', datetime.strptime(from_date, '%Y-%m-%d')), ('create_date', '<=', to_date) ]) for i in self.ticket_list: dictionary = {} dictionary['ticket_no'] = str(i.id) dictionary['date'] = i.create_date.strftime( "%d %b %y") if i.create_date else '' dictionary['table_no'] = str(i.table_no) return_list.append(dictionary) return return_list except Exception: if settings.level == 10: logger.exception('raised exception') return return_list def select_ticket(self, id): """ shows the details of the bill of which the id is passed :param id:the id of the bill :return: """ lines = [] try: with Transaction().start(DBNAME, 1): ticket = self.Ticket.search([('id', '=', id)])[-1] for i in ticket.lines: dictionary = {} dictionary['item_no'] = str(i.product.code) dictionary['item'] = i.product.template.name dictionary['quantity'] = str(int(i.quantity)) dictionary['state'] = i.state lines.append(dictionary) meta = { 'state': ticket.state, 'table_no': ticket.table_no, 'invoice': ticket.invoice.id if ticket.invoice else None } return lines, meta except Exception: if settings.level == 10: logger.exception('raised exception') return lines, False
class Pest(): """ Manages the Pest Reports """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Pest = pool.get('health_and_hygiene.pest_control_test') def __init__(self): logger.info('Inside WasteMenu') def load_report(self): """ loads the pest reports :return:True/False and list of dictionaries/string """ try: with Transaction().start(DBNAME, 1): pest_list = self.Pest.search([]) data_list = [] for pest in pest_list: data = {} data['code'] = str(pest.code) data['organization'] = pest.organization data['date'] = pest.date.strftime("%d/%m/%Y") data['test'] = pest.test data['description'] = pest.description # data['report'] = pest.report data_list.append(data) return True, data_list except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some Internal Error' def create_report(self, data): """ creates a pest report :return:True/False and string """ try: with Transaction().start(DBNAME, 1) as transaction: pest_list = self.Pest.search( ['code', '=', Decimal(data['code'])]) if not pest_list: pest = self.Pest() pest.code = data['code'] pest.organization = data['organization'] pest.date = datetime.strptime(data['date'], '%d/%m/%Y') pest.test = data['test'] pest.description = data['description'] pest.report = data['report'] pest.save() transaction.cursor.commit() return True, 'Submitted Successfully' else: return False, 'Duplicate Code' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some Internal Error' def update_report(self, data): """ updates a pest report :return:True/False and string """ try: with Transaction().start(DBNAME, 1) as transaction: pest_list = self.Pest.search( ['code', '=', Decimal(data['code'])]) if pest_list: pest, = pest_list pest.organization = data['organization'] pest.date = datetime.strptime(data['date'], '%d/%m/%Y') pest.test = data['test'] pest.description = data['description'] pest.report = data['report'] pest.save() transaction.cursor.commit() return True, 'Submitted Successfully' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some Internal Error' def read_report(self, code): """ reads pest reports :return:True/False and dictionary/string """ try: with Transaction().start(DBNAME, 1): pest_list = self.Pest.search(['code', '=', Decimal(code)]) if pest_list: pest, = pest_list data = {} data['code'] = str(pest.code) data['organization'] = pest.organization data['date'] = pest.date data['test'] = pest.test data['description'] = pest.description data['report'] = pest.report return True, data except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some Internal Error' def delete_report(self, code): """ deletes pest reports :return:True/False and string """ try: with Transaction().start(DBNAME, 1) as transaction: pest_list = self.Pest.search(['code', '=', Decimal(code)]) if pest_list: pest, = pest_list pest.delete((pest, )) transaction.cursor.commit() return True, 'Submitted Successfully' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some Internal Error'
def __init__(self, database_uri=None, user='******', language='en_US', admin_password='', super_pwd=None, config_file=None): OrigConfigModule.Config.__init__(self) # FixMe: straighten this mess out if config_file is None: config_file = os.environ.get('TRYTOND_CONFIG') assert config_file and os.path.isfile(config_file), \ "Set the environment variable TRYTOND_CONFIG to the path of TRYTOND CONFIG" if not database_uri: database_uri = os.environ.get('TRYTOND_DATABASE_URI') else: os.environ['TRYTOND_DATABASE_URI'] = database_uri assert os.path.isfile(config_file), \ "set os.environ.get('TRYTOND_CONFIG') to be the Tryton config file" from trytond.config import config config.update_etc(config_file) from trytond.pool import Pool from trytond import backend from trytond.protocols.dispatcher import create from trytond.cache import Cache from trytond.transaction import Transaction self.database = database_uri database_name = None if database_uri: uri = urlparse.urlparse(database_uri) database_name = uri.path.strip('/') if not database_name: assert 'DB_NAME' in os.environ, \ "Set os.environ['DB_NAME'] to be the database name" database_name = os.environ['DB_NAME'] self.database_name = database_name self._user = user self.config_file = config_file Pool.start() if False: # new in 3.4 self.pool = Pool(database_name) self.pool.init() else: # 3.2 code created the database if it did not exist with Transaction().start(None, 0) as transaction: cursor = transaction.cursor databases = backend.get('Database').list(cursor) if database_name not in databases: # trytond/protocols/dispatcher.py ''' Create a database :param database_name: the database name :param password: the server password :param lang: the default language for the database :param admin_password: the admin password :return: True if succeed ''' if not super_pwd: sys.stderr.write( "WARN: No super_pwd to create db %s\n" % (database_name,)) #! This is NOT the postgres server password #! This calls security.check_super(password) #! which is set in the conf file, [session]super_pwd #! using crypt to generate it from from the command line #! We default it to admin which may also be the #! of the user 'admin': admin_password super_pwd = 'admin' assert admin_password, "ERROR: No admin_password to create db " + database_name sys.stderr.write( "create %s %s %s %s\n" % (database_name, super_pwd, language, admin_password,)) create(database_name, super_pwd, language, admin_password) database_list = Pool.database_list() self.pool = Pool(database_name) if database_name not in database_list: self.pool.init() with Transaction().start(self.database_name, 0) as transaction: Cache.clean(database_name) User = self.pool.get('res.user') transaction.context = self.context self.user = User.search([ ('login', '=', user), ], limit=1)[0].id with transaction.set_user(self.user): self._context = User.get_preferences(context_only=True) Cache.resets(database_name)
from trytond.pool import Pool # from trytond.model import Cache from trytond.cache import Cache from trytond.transaction import Transaction # dbname contains the db you want to use dbname = 'testdb' CONTEXT = {} # Instantiate the pool with Transaction().start(dbname, 1, context=CONTEXT): Pool.start() pool = Pool(dbname) # Clean the global cache for multi-instance Cache.clean(dbname) pool.init() # User 0 is root user. We use it to get the admin id: with Transaction().start(dbname, 1) as transaction: user_obj = pool.get('res.user') user = user_obj(id=18) print user.id # user.name = 'raj' # user.login = '******' # user.password = '******' # user.save() # user_obj.delete([user]) # transaction.cursor.commit() # print 'success' # user = user.search([('login', '=', 'admin')], limit=1)[0]
class IngredientsInMenu(): """ Manages the ingredients in a dish """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Ingredient = pool.get('product.ingredientsofdish') Product = pool.get('product.product') ProductUom = pool.get('product.uom') Category = pool.get('product.category') def __init__(self, product_code): logger.info('Inside IngredientsInMenu') with Transaction().start(DBNAME, 1): # creation of object in a separate context prevents its modification but # can read the object in other functions of the instance, but if you try to edit it will show cursor error self.product = self.Product.search([('code', '=', product_code), ('description', '=', 'Dish'), ('type', '=', 'goods')])[-1] def load_ingredients(self): """ loads the ingredients of the product :return: the list of dictionary of ingredients and its corresponding values """ with Transaction().start(DBNAME, 1): ingredientlist = self.Ingredient.search([('dish', '=', self.product.id)]) dataobject = [] for i in ingredientlist: row = {} row['code'] = i.ingredient.code row['item'] = i.ingredient.template.name row['category'] = i.ingredient.template.category.name if i.ingredient.template.category else 'NA' row['units'] = i.quantity_uom.name row['quantity'] = i.quantity.to_eng() dataobject.append(row) return dataobject def remove_ingredient_item(self, code): """ removes an ingredient from the dish :param code: code of the ingredient :return:boolean value True is successfully deleted the dish """ logger.info('IngredientsInMenu remove ingredients initiated') try: with Transaction().start(DBNAME, 1) as transaction: ingredientlist = self.Ingredient.search(['dish', '=', self.product.id]) for i in ingredientlist: if i.ingredient.code == code: self.Ingredient.delete((i,)) transaction.cursor.commit() return True except Exception: if settings.level == 10: logger.exception('raised exception') return False def update_ingredients(self, dataobject): """ saves the ingredients of the product :param dataobject: the list of dictionaries of ingredients and it corresponding values :return: boolean value True if the ingredients was saved successfully """ logger.info('IngredientsInMenu update ingredients initiated') try: with Transaction().start(DBNAME, 1) as transaction: dataobject = dataobject ingredientlist = self.Ingredient.search(['dish', '=', self.product.id]) namelist = [i.ingredient.template.name for i in ingredientlist] for i in dataobject: for j in ingredientlist: if i['item'] == j.ingredient.template.name: quantity_uom, = self.ProductUom.search([('name', '=', i['units'])]) j.quantity_uom = quantity_uom j.quantity = Decimal(i['quantity']) j.save() if i['item'] not in namelist: product = self.Product.search([('code', '=', i['code']), ('description', '=', 'Stock'), ('type', '=', 'goods')])[-1] ingredient = self.Ingredient() ingredient.dish = self.product ingredient.ingredient = product ingredient.quantity = Decimal(i['quantity']) ingredient.quantity_uom, = self.ProductUom.search([('name', '=', i['units'])]) ingredient.save() transaction.cursor.commit() return True except Exception: if settings.level == 10: logger.exception('raised exception') return False def get_item(self): """ get the item(dish) list :return:list of item names """ with Transaction().start(DBNAME, 1): product = self.Product.search([('description', '=', 'Stock'), ('type', '=', 'goods')]) return [i.template.name for i in product] def get_quantity_uom(self): """ gets the measurement list :return:list of unit names """ with Transaction().start(DBNAME, 1): products = [] products.append('NA') products = [i.name for i in self.ProductUom.search([])] return products def get_categories(self): """ generates a list of categories :return:list of category names """ with Transaction().start(DBNAME, 1): categories = [] categories.append('NA') categories = [i.name for i in self.Category.search([])] return categories def get_details_of_code(self, code): """ returns the item, category and units based on the code :param code: code of the product :return: dictionary of item and its corresponding values """ with Transaction().start(DBNAME, 1): item = self.Product.search([('code', '=', code), ('description', '=', 'Stock'), ('type', '=', 'goods')]) if item != []: i = item[-1] row = {} row['item'] = i.template.name row['category'] = i.template.category.name row['units'] = i.template.default_uom.name return row def get_details_of_item(self, item): """ returns the item, category and units based on the code :param item: name of the product :return: dictionary of item and its corresponding values """ row = {} try: with Transaction().start(DBNAME, 1): product = self.Product.search([('name', '=', item), ('description', '=', 'Stock'), ('type', '=', 'goods')])[-1] row['code'] = product.code row['category'] = product.template.category.name row['units'] = product.template.default_uom.name return row except Exception: if settings.level == 10: logger.exception('raised exception') return row
class MenuProduct(): """ Manages menu items """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Category = pool.get('product.category') Product = pool.get('product.product') ProductUom = pool.get('product.uom') ProductTemplate = pool.get('product.template') ProductCategory = pool.get('product.category') Tax = pool.get('account.tax') def __init__(self): logger.info('Inside MenuProduct') self.productlist = object self.product = object def load_menus(self): """ loads the menu items :return: list of dictionary of menu items """ with Transaction().start(DBNAME, 1): self.productlist = self.Product.search([('description', '=', 'Dish'), ('type', '=', 'goods')]) return_list = [] for i in self.productlist: dictionary = {} dictionary['item_no'] = str(i.code) dictionary['item'] = i.template.name dictionary['category'] = i.template.category.name dictionary['rate'] = i.list_price_uom.to_eng() return_list.append(dictionary) return return_list def new_dish(self, obj): """ adds a new dish to the menu :param obj: the dictionary of dish and its corresponding data :return:boolean value True if the dish was saved """ logger.info('MenuProduct new dish initiated') try: with Transaction().start(DBNAME, 1) as transaction: unit, = self.ProductUom.search([('name', '=', 'Unit')]) try: _ = \ self.Product.search( [('code', '=', obj['id']), ('description', '=', 'Dish'), ('type', '=', 'goods')])[-1] return False except IndexError: pass try: template = \ self.ProductTemplate.search( [('name', '=', obj['name']), ('type', '=', 'goods')])[-1] except IndexError: template = self.ProductTemplate() template.category = self.ProductCategory.search([('name', '=', obj['category'])])[-1] template.default_uom = unit template.type = 'goods' rate = Decimal(obj['rate']) cost = rate / 2 template.name = obj['name'] template.list_price = Decimal(rate) template.cost_price = Decimal(cost) template.save() tax = self.Tax.search([('name', '=', 'Restaurant Tax')])[-1] template.customer_taxes = (tax,) template.save() product = self.Product() product.template = template product.code = obj['id'] product.description = 'Dish' product.serve = Decimal(obj['serve']) product.save() transaction.cursor.commit() return True except Exception: if settings.level == 10: logger.exception('raised exception') return False def update_dish(self, obj): """ updates a dish in the menu :param obj: the dictionary of dish and its corresponding data :return:boolean value True if the dish was saved """ logger.info('MenuProduct update dish initiated') try: with Transaction().start(DBNAME, 1) as transaction: product = \ self.Product.search( [('code', '=', obj['id']), ('description', '=', 'Dish'), ('type', '=', 'goods')])[-1] template = product.template template.category = self.ProductCategory.search([('name', '=', obj['category'])])[-1] rate = Decimal(obj['rate']) cost = rate / 2 template.name = obj['name'] template.list_price = Decimal(rate) template.cost_price = Decimal(cost) template.save() product.description = 'Dish' product.serve = Decimal(obj['serve']) product.save() transaction.cursor.commit() return True except Exception: # print sys.exc_info()[0].__name__, os.path.basename(sys.exc_info()[2].tb_frame.f_code.co_filename), \ # sys.exc_info()[2].tb_lineno # print sys.exc_info() if settings.level == 10: logger.exception('raised exception') return False def load_rows(self, id=None): """ loads the dish corresponding to the id of the dish :return: dictionary of the dish and its corresponding values """ with Transaction().start(DBNAME, 1): newid = id product = self.Product.search([('code', '=', newid), ('description', '=', 'Dish'), ('type', '=', 'goods')])[-1] data = {} data['name'] = product.template.name data['category'] = product.template.category.name \ if product.template.category is not None else 'No Category' data['rate'] = product.template.list_price.to_eng() data['serve'] = product.serve.to_eng() if product.serve else '1' return data def delete_rows(self, id=None): """ deletes a dish from the menu item :param id: id of the product :return: boolean value True if the dish was deleted """ logger.info('MenuProduct delete menu initiated') try: newid = id with Transaction().start(DBNAME, 1) as transaction: product = \ self.Product.search([('code', '=', newid), ('description', '=', 'Dish'), ('type', '=', 'goods')])[-1] template = \ self.ProductTemplate.search( [('name', '=', product.template.name), ('type', '=', 'goods')])[-1] template.active = False template.save() name = template.name product.active = False product.save() transaction.cursor.commit() week = WeeklyMenu(name=name) _ = week.remove_from_all_days() return True except Exception: # print sys.exc_info()[0].__name__, os.path.basename(sys.exc_info()[2].tb_frame.f_code.co_filename), \ # sys.exc_info()[2].tb_lineno # print sys.exc_info() if settings.level == 10: logger.exception('raised exception') return False
class WasteMenu(): """ Manages the wastes produced in the menu items """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Menu = pool.get('product.product') Location = pool.get('stock.location') Product = pool.get('product.product') Shipment = pool.get('stock.shipment.internal') ShipmentMoves = pool.get('stock.move') Move = pool.get('stock.move') def __init__(self): logger.info('Inside WasteMenu') with Transaction().start(DBNAME, 1): self.inventory = self.Location.search(['name', '=', 'MyInventory'])[-1] self.throw = self.Location.search(['name', '=', 'Lost and Found'])[-1] def populate_item(self, model): """ Populates the dish items :param model: the Qt model in which the item names are to be populated :return: returns a filled model """ with Transaction().start(DBNAME, 1): newmodel = model menu = self.Menu.search([('description', '=', 'Dish'), ('type', '=', 'goods')]) menulist = [i.template.name for i in menu] newmodel.addItems(menulist) def get_details_of_code(self, code): """ finds dish,category corresponding to the code :param code: dish code :return: dictionary of the dish and other details """ newid = code data = {} try: with Transaction().start(DBNAME, 1): menu = self.Menu.search([('code', '=', newid), ('description', '=', 'Dish'), ('type', '=', 'goods')])[-1] data['item'] = menu.template.name data['category'] = menu.template.category.name except Exception: if settings.level == 10: logger.exception('raised exception') return data def get_details_of_item(self, item): """ finds code,category of the item :param item: dish name :return: dictionary of the dish and other details """ newitem = item data = {} try: with Transaction().start(DBNAME, 1): menu = self.Menu.search([('name', '=', newitem), ('description', '=', 'Dish'), ('type', '=', 'goods')])[-1] data['code'] = menu.code data['category'] = menu.template.category.name except Exception: if settings.level == 10: logger.exception('raised exception') return data def discard(self, data): """ adds the dish to the wastes for the present day :param data:the dictionary of the dish and other details :return: boolean value True if the process was successful """ logger.info('WasteMenu discard initiated') try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = config.get_config().context item = data['item'] product = self.Product.search([('name', '=', item), ('description', '=', 'Dish'), ('type', '=', 'goods')])[-1] quantity = Decimal(data['quantity']) reason_for_discard = data['reason_for_discard'] state = self.move(from_location=self.inventory, to_location=self.throw, item=product, quantity=quantity, reason=reason_for_discard) transaction.cursor.commit() if state: return True else: return False except Exception: if settings.level == 10: logger.exception('raised exception') return False def move(self, from_location, to_location, item, quantity, reason=None): """ Moves an item to the waste :param from_location: the start location :param to_location: the end location :param item: the item to be sent to the waste :param quantity: the quantity :param reason: the reason optional :return: boolean value True if the item was moved """ try: shipment = self.Shipment() from_location = from_location to_location = to_location item = item quantity = quantity shipment.from_location = from_location shipment.to_location = to_location new_move = self.ShipmentMoves() new_move.from_location = from_location new_move.to_location = to_location new_move.product = item new_move.quantity = float(quantity) new_move.uom = item.template.default_uom shipment.moves = (new_move,) if reason: new_move.reason_for_discard = reason shipment.save() shipment.wait((shipment,)) shipment.done((shipment,)) shipment.assign_wizard((shipment,)) state = shipment.assign_try((shipment,)) if not state: shipment.assign_force((shipment,)) return True except Exception: if settings.level == 10: logger.exception('raised exception') return False def find_itemdiscard(self, from_date, to_date): """ shows the items discarded on those days :param from_date:start date :param to_date:end date :return:list of dictionary of the items in the waste category of the given dates """ dataobj = [] with Transaction().start(DBNAME, 1): datalist = self.Move.search([('write_date', '>=', from_date), ('write_date', '<=', to_date)]) for i in datalist: if i.product.description == 'Dish': dictionary = {} dictionary['code'] = i.product.code dictionary['item'] = i.product.template.name dictionary['category'] = i.product.template.category.name dictionary['quantity'] = i.quantity dictionary['reason_for_discard'] = i.reason_for_discard dataobj.append(dictionary) return dataobj
def dispatch(host, port, protocol, database_name, user, session, object_type, object_name, method, *args, **kargs): if object_type == 'common': if method == 'login': try: database = Database(database_name).connect() cursor = database.cursor() cursor.close() except Exception: return False res = security.login(database_name, user, session) Cache.clean(database_name) logger = logging.getLogger('dispatcher') msg = res and 'successful login' or 'bad login or password' logger.info('%s \'%s\' from %s:%d using %s on database \'%s\'' % \ (msg, user, host, port, protocol, database_name)) Cache.resets(database_name) return res or False elif method == 'logout': name = security.logout(database_name, user, session) logger = logging.getLogger('dispatcher') logger.info('logout \'%s\' from %s:%d ' \ 'using %s on database \'%s\'' % (name, host, port, protocol, database_name)) return True elif method == 'version': return VERSION elif method == 'timezone_get': return CONFIG['timezone'] elif method == 'list_lang': return [ ('bg_BG', 'Български'), ('ca_ES', 'Català'), ('cs_CZ', 'Čeština'), ('de_DE', 'Deutsch'), ('en_US', 'English'), ('es_AR', 'Español (Argentina)'), ('es_ES', 'Español (España)'), ('es_CO', 'Español (Colombia)'), ('fr_FR', 'Français'), ('nl_NL', 'Nederlands'), ('ru_RU', 'Russian'), ] elif method == 'db_exist': try: database = Database(*args, **kargs).connect() cursor = database.cursor() cursor.close(close=True) return True except Exception: return False elif method == 'list': if CONFIG['prevent_dblist']: raise Exception('AccessDenied') database = Database().connect() try: cursor = database.cursor() try: res = database.list(cursor) finally: cursor.close(close=True) except Exception: res = [] return res elif method == 'create': return create(*args, **kargs) elif method == 'restore': return restore(*args, **kargs) elif method == 'drop': return drop(*args, **kargs) elif method == 'dump': return dump(*args, **kargs) return elif object_type == 'system': database = Database(database_name).connect() database_list = Pool.database_list() pool = Pool(database_name) if not database_name in database_list: pool.init() if method == 'listMethods': res = [] for type in ('model', 'wizard', 'report'): for object_name, obj in pool.iterobject(type=type): for method in obj._rpc: res.append(type + '.' + object_name + '.' + method) return res elif method == 'methodSignature': return 'signatures not supported' elif method == 'methodHelp': res = [] args_list = args[0].split('.') object_type = args_list[0] object_name = '.'.join(args_list[1:-1]) method = args_list[-1] obj = pool.get(object_name, type=object_type) return pydoc.getdoc(getattr(obj, method)) user = security.check(database_name, user, session) Cache.clean(database_name) database_list = Pool.database_list() pool = Pool(database_name) if not database_name in database_list: with Transaction().start(database_name, user, readonly=True) as transaction: pool.init() obj = pool.get(object_name, type=object_type) if method in obj._rpc: readonly = not obj._rpc[method] elif method in getattr(obj, '_buttons', {}): readonly = False else: raise UserError('Calling method %s on %s %s is not allowed!' % (method, object_type, object_name)) for count in range(int(CONFIG['retry']), -1, -1): with Transaction().start(database_name, user, readonly=readonly) as transaction: try: args_without_context = list(args) if 'context' in kargs: context = kargs.pop('context') else: context = args_without_context.pop() if '_timestamp' in context: transaction.timestamp = context['_timestamp'] del context['_timestamp'] transaction.context = context res = getattr(obj, method)(*args_without_context, **kargs) if not readonly: transaction.cursor.commit() except DatabaseOperationalError, exception: transaction.cursor.rollback() if count and not readonly: continue raise except Exception, exception: if CONFIG['verbose'] and not isinstance(exception, ( NotLogged, ConcurrencyException, UserError, UserWarning)): tb_s = ''.join(traceback.format_exception(*sys.exc_info())) logger = logging.getLogger('dispatcher') logger.error('Exception calling method %s on ' '%s %s from %s@%s:%d/%s:\n' % (method, object_type, object_name, user, host, port, database_name) + tb_s) transaction.cursor.rollback() raise
def _dispatch(request, pool, *args, **kwargs): DatabaseOperationalError = backend.get('DatabaseOperationalError') obj, method = get_object_method(request, pool) if method in obj.__rpc__: rpc = obj.__rpc__[method] else: raise UserError('Calling method %s on %s is not allowed' % (method, obj)) log_message = '%s.%s(*%s, **%s) from %s@%s/%s' log_args = (obj, method, args, kwargs, request.authorization.username, request.remote_addr, request.path) logger.info(log_message, *log_args) user = request.user_id session = None if request.authorization.type == 'session': session = request.authorization.get('session') for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start(pool.database_name, user, readonly=rpc.readonly, context={'session': session}) as transaction: Cache.clean(pool.database_name) try: PerfLog().on_enter(user, session, request.method, args, kwargs) except: perf_logger.exception('on_enter failed') try: c_args, c_kwargs, transaction.context, transaction.timestamp \ = rpc.convert(obj, *args, **kwargs) meth = getattr(obj, method) try: wrapped_meth = profile(meth) except: perf_logger.exception('profile failed') else: meth = wrapped_meth if (rpc.instantiate is None or not is_instance_method(obj, method)): result = rpc.result(meth(*c_args, **c_kwargs)) else: assert rpc.instantiate == 0 inst = c_args.pop(0) if hasattr(inst, method): result = rpc.result(meth(inst, *c_args, **c_kwargs)) else: result = [rpc.result(meth(i, *c_args, **c_kwargs)) for i in inst] except DatabaseOperationalError: if count and not rpc.readonly: transaction.rollback() continue logger.error(log_message, *log_args, exc_info=True) raise except (ConcurrencyException, UserError, UserWarning): logger.debug(log_message, *log_args, exc_info=True) raise except Exception: logger.error(log_message, *log_args, exc_info=True) raise # Need to commit to unlock SQLite database transaction.commit() Cache.resets(pool.database_name) if request.authorization.type == 'session': try: with Transaction().start(pool.database_name, 0) as transaction: Session = pool.get('ir.session') Session.reset(request.authorization.get('session')) except DatabaseOperationalError: logger.debug('Reset session failed', exc_info=True) logger.debug('Result: %s', result) try: PerfLog().on_leave(result) except: perf_logger.exception('on_leave failed') return result
def dispatch_request(self): """ Does the request dispatching. Matches the URL and returns the return value of the view or error handler. This does not have to be a response object. """ DatabaseOperationalError = backend.get('DatabaseOperationalError') req = _request_ctx_stack.top.request if req.routing_exception is not None: self.raise_routing_exception(req) rule = req.url_rule # if we provide automatic options for this URL and the # request came with the OPTIONS method, reply automatically if getattr(rule, 'provide_automatic_options', False) \ and req.method == 'OPTIONS': return self.make_default_options_response() with Transaction().start(self.database_name, 0): Cache.clean(self.database_name) Cache.resets(self.database_name) with Transaction().start(self.database_name, 0, readonly=True): user = current_website.application_user.id website_context = current_website.get_context() website_context.update({ 'company': current_website.company.id, }) language = current_locale.language.code # pop locale if specified in the view_args req.view_args.pop('locale', None) active_id = req.view_args.pop('active_id', None) for count in range(int(config.get('database', 'retry')), -1, -1): with Transaction().start( self.database_name, user, context=website_context, readonly=rule.is_readonly) as txn: try: transaction_start.send(self) rv = self._dispatch_request( req, language=language, active_id=active_id ) txn.commit() transaction_commit.send(self) except DatabaseOperationalError: # Strict transaction handling may cause this. # Rollback and Retry the whole transaction if within # max retries, or raise exception and quit. txn.rollback() if count: continue raise except Exception: # Rollback and raise any other exception txn.rollback() raise else: return rv finally: transaction_stop.send(self)
class SearchMenu(): """ Search the dish to be billed """ global logger with Transaction().start(DBNAME, 1) as transaction: Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Menu = pool.get('product.product') Tax = pool.get('account.tax') def __init__(self): logger.info('Inside SearchMenu') def search_id(self, code): """ :param code: searches the menu based on the code :return: menu item """ newid = code try: with Transaction().start(DBNAME, 1): menu = self.Menu.search([('code', '=', newid), ('description', '=', 'Dish'), ('type', '=', 'goods')])[-1] return menu.template.name except Exception: if settings.level == 10: logger.exception('raised exception') def search_item(self, item): """ :model:the completer model :item:the text typed in the lineedit :return: searches each instance of the menu item number """ try: with Transaction().start(DBNAME, 1): menu = self.Menu.search([('name', 'like', '%' + item + '%'), ('description', '=', 'Dish'), ('type', '=', 'goods')]) return tuple(i.template.name for i in menu) except Exception: if settings.level == 10: logger.exception('raised exception') return False def search_rate(self, item): """ :param item:menu item :return: list price of the item """ newitem = item try: with Transaction().start(DBNAME, 1): menu = self.Menu.search([('name', '=', newitem), ('description', '=', 'Dish'), ('type', '=', 'goods')])[-1] rate = menu.list_price_uom.to_eng() id = menu.code return rate, id except Exception: if settings.level == 10: logger.exception('raised exception') def get_tax(self): """ :return: gets the restaurant tax value """ try: with Transaction().start(DBNAME, 1): tax = self.Tax.search([('name', '=', 'Restaurant Tax')])[0] tax = tax.rate.multiply(100) return tax except Exception: if settings.level == 10: logger.exception('raised exception') def search_dish(self, item): """ :param item:menu item :return: list price of the item """ try: with Transaction().start(DBNAME, 1): menu = self.Menu.search([('name', '=', item), ('description', '=', 'Dish'), ('type', '=', 'goods')])[-1] id = menu.code return id except Exception: if settings.level == 10: logger.exception('raised exception') return False
class Messaging(): """ provides a mechanism to manage messages """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Messages = pool.get('health_and_hygiene.messages') def __init__(self): logger.info('Inside notification_tryton') def load_message(self, msg_id=None, limit=None, from_date=None, to_date=None, msg_state=None, offset=0): """lodas messages from the backend""" return_list = [] limit = int(limit) if limit else 0 from_date = datetime.strptime(from_date, '%d/%m/%Y') if from_date else None to_date = datetime.strptime(to_date, '%d/%m/%Y') + timedelta( hours=23, minutes=59, seconds=59) if to_date else None try: with Transaction().start(DBNAME, 1): if msg_id: message_list = self.Messages.search([('message_id', '=', msg_id)]) elif msg_state == 'All': message_list = self.Messages.search( [('create_date', '>=', from_date), ('create_date', '<=', to_date)], offset=offset, limit=limit) else: message_list = self.Messages.search( [('create_date', '>=', from_date), ('create_date', '<=', to_date), ('message_state', '=', msg_state.lower())], offset=offset, limit=limit) for i in message_list: dictionary = {} dictionary['msg_id'] = str(i.message_id) dictionary['date'] = i.sent.strftime( "%d/%m/%Y") if i.sent else '' dictionary['name'] = i.from_name dictionary['designation'] = i.from_designation dictionary['address'] = i.from_address dictionary['msg_type'] = i.message_type dictionary['msg_body'] = i.message_body dictionary['msg_state'] = i.message_state return_list.append(dictionary) return return_list except Exception: if settings.level == 10: logger.exception('raised exception') return return_list def save_message(self, data): """method to save the messages to the backend""" try: with Transaction().start(DBNAME, 1) as transaction: for i in data: message_list = self.Messages.search([('message_id', '=', i['message_id'])]) if message_list: continue else: message = self.Messages() message.message_id = i['message_id'] message.sent = datetime.strptime(i['sent'], "%d/%m/%Y") message.from_name = i['name'] message.from_designation = i['from_designation'] message.from_address = i['from_address'] message.message_type = i['msg_type'] message.message_body = i['msg_body'] message.save() transaction.cursor.commit() except Exception: if settings.level == 10: logger.exception('raised exception') return False def update_message(self, data): """updats the message details""" try: with Transaction().start(DBNAME, 1) as transaction: message_list = self.Messages.search([('message_id', '=', data['message_id'])]) if message_list: message, = message_list message.message_state = data['msg_state'].lower() message.save() transaction.cursor.commit() return True except Exception: if settings.level == 10: logger.exception('raised exception') return False
def dispatch(host, port, protocol, database_name, user, session, object_type, object_name, method, *args, **kwargs): Database = backend.get('Database') DatabaseOperationalError = backend.get('DatabaseOperationalError') if object_type == 'common': if method == 'login': try: database = Database(database_name).connect() cursor = database.cursor() cursor.close() except Exception: return False res = security.login(database_name, user, session) with Transaction().start(database_name, 0): Cache.clean(database_name) Cache.resets(database_name) msg = res and 'successful login' or 'bad login or password' logger.info('%s \'%s\' from %s:%d using %s on database \'%s\'', msg, user, host, port, protocol, database_name) return res or False elif method == 'logout': name = security.logout(database_name, user, session) logger.info('logout \'%s\' from %s:%d ' 'using %s on database \'%s\'', name, host, port, protocol, database_name) return True elif method == 'version': return __version__ elif method == 'list_lang': return [ ('bg_BG', 'Български'), ('ca_ES', 'Català'), ('cs_CZ', 'Čeština'), ('de_DE', 'Deutsch'), ('en_US', 'English'), ('es_AR', 'Español (Argentina)'), ('es_EC', 'Español (Ecuador)'), ('es_ES', 'Español (España)'), ('es_CO', 'Español (Colombia)'), ('es_MX', 'Español (México)'), ('fr_FR', 'Français'), ('hu_HU', 'Magyar'), ('it_IT', 'Italiano'), ('lt_LT', 'Lietuvių'), ('nl_NL', 'Nederlands'), ('pt_BR', 'Português (Brasil)'), ('ru_RU', 'Russian'), ('sl_SI', 'Slovenščina'), ] elif method == 'db_exist': try: database = Database(*args, **kwargs).connect() cursor = database.cursor() cursor.close(close=True) return True except Exception: return False elif method == 'list': if not config.getboolean('database', 'list'): raise Exception('AccessDenied') with Transaction().start(None, 0, close=True) as transaction: return transaction.database.list(transaction.cursor) elif method == 'create': return create(*args, **kwargs) elif method == 'restore': return restore(*args, **kwargs) elif method == 'drop': return drop(*args, **kwargs) elif method == 'dump': return dump(*args, **kwargs) return elif object_type == 'system': database = Database(database_name).connect() database_list = Pool.database_list() pool = Pool(database_name) if database_name not in database_list: pool.init() if method == 'listMethods': res = [] for type in ('model', 'wizard', 'report'): for object_name, obj in pool.iterobject(type=type): for method in obj.__rpc__: res.append(type + '.' + object_name + '.' + method) return res elif method == 'methodSignature': return 'signatures not supported' elif method == 'methodHelp': res = [] args_list = args[0].split('.') object_type = args_list[0] object_name = '.'.join(args_list[1:-1]) method = args_list[-1] obj = pool.get(object_name, type=object_type) return pydoc.getdoc(getattr(obj, method)) for count in range(config.getint('database', 'retry'), -1, -1): try: user = security.check(database_name, user, session) except DatabaseOperationalError: if count: continue raise break database_list = Pool.database_list() pool = Pool(database_name) if database_name not in database_list: with Transaction().start(database_name, user, readonly=True) as transaction: pool.init() obj = pool.get(object_name, type=object_type) if method in obj.__rpc__: rpc = obj.__rpc__[method] else: raise UserError('Calling method %s on %s %s is not allowed!' % (method, object_type, object_name)) log_message = '%s.%s.%s(*%s, **%s) from %s@%s:%d/%s' log_args = (object_type, object_name, method, args, kwargs, user, host, port, database_name) logger.info(log_message, *log_args) for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start(database_name, user, readonly=rpc.readonly) as transaction: Cache.clean(database_name) try: c_args, c_kwargs, transaction.context, transaction.timestamp \ = rpc.convert(obj, *args, **kwargs) meth = getattr(obj, method) if (rpc.instantiate is None or not is_instance_method(obj, method)): result = rpc.result(meth(*c_args, **c_kwargs)) else: assert rpc.instantiate == 0 inst = c_args.pop(0) if hasattr(inst, method): result = rpc.result(meth(inst, *c_args, **c_kwargs)) else: result = [rpc.result(meth(i, *c_args, **c_kwargs)) for i in inst] if not rpc.readonly: transaction.cursor.commit() except DatabaseOperationalError: transaction.cursor.rollback() if count and not rpc.readonly: continue raise except (NotLogged, ConcurrencyException, UserError, UserWarning): logger.debug(log_message, *log_args, exc_info=True) transaction.cursor.rollback() raise except Exception: logger.error(log_message, *log_args, exc_info=True) transaction.cursor.rollback() raise Cache.resets(database_name) with Transaction().start(database_name, 0) as transaction: pool = Pool(database_name) Session = pool.get('ir.session') try: Session.reset(session) except DatabaseOperationalError: logger.debug('Reset session failed', exc_info=True) # Silently fail when reseting session transaction.cursor.rollback() else: transaction.cursor.commit() logger.debug('Result: %s', result) return result
class Health(): """ Manages the Health Reports """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Health = pool.get('health_and_hygiene.health_report') Employee = pool.get('company.employee') def __init__(self, emp_id): logger.info('Inside WasteMenu') self.setup(emp_id=emp_id) def setup(self, emp_id): """ Retrives the DB-id for the employee :param emp_id:the employee id """ try: with Transaction().start(DBNAME, 1): employee = self.Employee.search(['employee_id', '=', emp_id]) if employee: self.emp_id = employee[0].id except Exception: if settings.level == 10: logger.exception('raised exception') def load_report(self): """ loads the employee health reports :return:boolean and list of dictionary """ try: with Transaction().start(DBNAME, 1): report_list = self.Health.search( ['employee', '=', self.emp_id]) data_list = [] for report in report_list: data = {} data['code'] = str(report.code) data['organization'] = report.organization data['date'] = report.date.strftime("%d/%m/%Y") data['test'] = report.test data['description'] = report.description data_list.append(data) return True, data_list except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some Internal Error' def create_report(self, data): """ creates a health test report :return:True/False and string """ try: with Transaction().start(DBNAME, 1) as transaction: report_list = self.Health.search([ ('code', '=', Decimal(data['code'])), ('employee', '=', self.emp_id) ]) if not report_list: health = self.Health() health.code = data['code'] health.organization = data['organization'] health.date = datetime.strptime(data['date'], '%d/%m/%Y') health.test = data['test'] health.description = data['description'] health.report = data['report'] health.employee = self.emp_id health.save() transaction.cursor.commit() return True, 'Submitted Successfully' else: return False, 'Duplicate Entry' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some Internal Error' def update_report(self, data): """ updates a health test report :return:True/False and string """ try: with Transaction().start(DBNAME, 1) as transaction: heatlth_list = self.Health.search([ ('code', '=', Decimal(data['code'])), ('employee', '=', self.emp_id) ]) if heatlth_list: health, = heatlth_list health.organization = data['organization'] health.date = datetime.strptime(data['date'], '%d/%m/%Y') health.test = data['test'] health.description = data['description'] health.report = data['report'] health.save() transaction.cursor.commit() return True, 'Submitted Successfully' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some Internal Error' def read_report(self, code): """ reads health reports :return:True/False and dictionary/string """ try: with Transaction().start(DBNAME, 1): health_list = self.Health.search([('code', '=', Decimal(code)), ('employee', '=', self.emp_id)]) if health_list: health, = health_list data = {} data['code'] = str(health.code) data['organization'] = health.organization data['date'] = health.date data['test'] = health.test data['description'] = health.description data['report'] = health.report return True, data except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some Internal Error' def delete_report(self, code): """ deletes health reports :return:True/False and string """ try: with Transaction().start(DBNAME, 1) as transaction: health_list = self.Health.search([('code', '=', Decimal(code)), ('employee', '=', self.emp_id)]) if health_list: pest, = health_list pest.delete((pest, )) transaction.cursor.commit() return True, 'Submitted Successfully' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Some Internal Error'
class SaveTicket(): """ Saves the Ticket """ global logger with Transaction().start(DBNAME, 1): Pool.start() pool = Pool(DBNAME) # Clean the global cache for multi-instance Cache.clean(DBNAME) pool.init() Product = pool.get('product.product') Ticket = pool.get('account.ticket') TicketLine = pool.get('account.ticket.lines') Invoice = pool.get('account.invoice') def __init__(self): logger.info('Inside SaveBill') self.dishes = WeeklyMenu() def save_ticket(self, dataobj, table_number=None, ticket_number=None): """ :param dataobj: product to be added into the invoice :return:id of the invoice and status """ logger.info('SaveTicket saving ticket initiated') try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = config.get_config().context if not ticket_number: ticket = self.Ticket() ticket.table_no = int(table_number) ticket.save() for i in dataobj: line = self.TicketLine() product = self.Product.search([('code', '=', i['id']), ('description', '=', 'Dish'), ('type', '=', 'goods')]) product = product[-1] quantity = int(i['quantity']) counter = self.dishes.calculate_availability( product=product) if counter: if counter >= quantity: status = self.dishes.use_dish( product=product, quantity=quantity) if not status: return False, 'Dish not used' line.remark = 'normal' else: excess = quantity - counter status = self.dishes.use_dish(product=product, quantity=counter) if not status: return False, 'Dish not used' line.remark = 'excess' line.excess_quantity = excess else: line.remark = 'excess' line.excess_quantity = quantity line.product = product line.quantity = quantity line.ticket = ticket line.save() else: ticket, = self.Ticket.search([('id', '=', ticket_number)]) if ticket.invoice: return False, 'The ticket is already billed and hence cannot be modified.' ticket.table_no = int(table_number) for i in dataobj: product = self.Product.search([('code', '=', i['id']), ('description', '=', 'Dish'), ('type', '=', 'goods')]) if product: product = product[0] quantity = int(i['quantity']) lines = self.TicketLine.search([ ('ticket', '=', ticket.id), ('product', '=', product.id) ]) for line in lines: if i['state'] == 'processing' or i[ 'state'] == 'rejected': counter = self.dishes.calculate_availability( product=product) if line.remark == 'excess': if counter: if counter >= line.excess_quantity: status = self.dishes.use_dish( product=product, quantity=line. excess_quantity) if not status: return False, 'Dish not used' line.state = 'processing' line.remark = 'normal' else: excess = line.excess_quantity - counter status = self.dishes.use_dish( product=product, quantity=counter) if not status: return False, 'Dish not used' line.remark = 'excess' line.excess_quantity = excess line.state = 'processing' else: line.remark = 'excess' line.excess_quantity = line.excess_quantity line.product = product line.quantity = quantity line.ticket = ticket if line.remark == 'normal': if line.quantity < quantity: excess = quantity - line.quantity if counter >= excess: status = self.dishes.use_dish( product=product, quantity=excess) if not status: return False, 'Dish not used' line.state = 'processing' line.remark = 'normal' else: excess = excess - counter status = self.dishes.use_dish( product=product, quantity=counter) if not status: return False, 'Dish not used' line.state = 'processing' line.remark = 'excess' line.excess_quantity = excess elif line.quantity > quantity: difference_quantity = line.quantity - quantity status = self.dishes.cancel_dish( product=product, quantity=difference_quantity) if not status: return False, 'Dish not reduced' line.state = 'processing' line.remark = 'normal' line.product = product line.quantity = quantity line.ticket = ticket elif i['state'] == 'cancel': state = self.cancel_ticketline( ticketline=line) if not state: return False, 'Could not cancel the Dish' line.state = i[ 'state'] # for state=='rejected' line.save() ticket.state = 'draft' ticket.save() data = [] data.append(str(ticket.id)) data.append(str(ticket.state)) data.append(str(ticket.invoice.id if ticket.invoice else None)) transaction.cursor.commit() return data except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Unknown Error' def save_invoice(self, tickets_list): """creates a new bill from the list of tickets""" logger.info('SaveTicket saving ticket initiated') data = [] rejected = [] try: with Transaction().start(DBNAME, 1) as transaction: tickets = [] for i in tickets_list: search = self.Ticket.search([('id', '=', i)]) if search: tickets.append(search[0]) for i in tickets: if i.invoice: return False, 'Ticket {0} was used in invoice {1}'.format( i.id, i.invoice.id) if i.state == 'cancel': return False, 'Ticket {0} was cancelled'.format(i.id) for j in i.lines: if j.state == 'rejected': rejected.append(j.id) continue if j.state == 'cancel': continue line_dict = {} if j.remark == 'excess': quantity = self.dishes.calculate_availability( product=j.product) if quantity: if quantity >= j.excess_quantity: status = self.dishes.use_dish( product=j.product, quantity=j.excess_quantity) j.remark = 'normal' if not status: return False, 'cannot reduce the dish' else: j.remark = 'malicious' else: j.remark = 'malicious' j.state = 'done' line_dict['id'] = j.product.code line_dict['item'] = j.product.template.name line_dict['quantity'] = j.quantity line_dict['remark'] = j.remark j.save() transaction.cursor.commit() data.append(line_dict) return_dat = self.aggregate_dishes(data) for i in rejected: status = self.reject_ticketline(ticket_id=i) if not status: return False, 'cannot reject the dish' bill = SaveBill() code, _ = bill.save_bill(return_dat) with Transaction().start(DBNAME, 1) as transaction: invoice = self.Invoice(id=code) try: for i in tickets_list: search = self.Ticket.search([('id', '=', i)]) if search: search[0].invoice = invoice search[0].state = 'done' search[0].save() transaction.cursor.commit() except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Ticket Invoicing failed' return True, code except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Failed to save the invoice' def cancel_ticketline(self, ticketline): """cancels a ticket list""" try: if ticketline.remark == 'excess' or ticketline.remark == 'malicious': to_drop = abs(ticketline.quantity - ticketline.excess_quantity) status = self.dishes.cancel_dish(product=ticketline.product, quantity=to_drop) if not status: return False else: status = self.dishes.cancel_dish(product=ticketline.product, quantity=ticketline.quantity) if not status: return False ticketline.state = 'cancel' ticketline.remark = 'normal' ticketline.quantity = int(0) ticketline.save() return ticketline.state except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Cannot be canceled. Backend Error.' def reject_ticketline(self, ticket_id): """rejects a ticket""" try: waste = WasteMenu() with Transaction().start(DBNAME, 1): data = {} ticketline = self.TicketLine(id=ticket_id) data['item'] = ticketline.product.template.name data['quantity'] = ticketline.quantity data['reason_for_discard'] = ticketline.state return waste.discard(data=data) except Exception: if settings.level == 10: logger.exception('raised exception') return False def cancel_ticket(self, ticket_number=None): """cancels a single ticket""" try: with Transaction().start(DBNAME, 1) as transaction: transaction.context = config.get_config().context ticket, = self.Ticket.search([('id', '=', ticket_number)]) if ticket.invoice: return False, 'Cannot cancel,Ticket is used in Invoice:{0}'.format( ticket.invoice.id) for i in ticket.lines: if i.remark == 'excess' or i.remark == 'malicious': to_drop = abs(i.quantity - i.excess_quantity) status = self.dishes.cancel_dish(product=i.product, quantity=to_drop) if not status: return False else: status = self.dishes.cancel_dish(product=i.product, quantity=i.quantity) i.excess_quantity = i.quantity if not status: return False i.state = 'cancel' i.remark = 'normal' i.quantity = int(0) i.save() ticket.state = 'cancel' ticket.save() transaction.cursor.commit() return ticket.state, 'Successfully canceled the Ticket' except Exception: if settings.level == 10: logger.exception('raised exception') return False, 'Cannot be canceled. Backend Error.' def get_details(self, ticket_number): """get details of the ticket from the ticket_number""" try: with Transaction().start(DBNAME, 1): ticket, = self.Ticket.search([('id', '=', ticket_number)]) return ticket.table_no, ticket.state except Exception: if settings.level == 10: logger.exception('raised exception') return False def aggregate_dishes(self, data): """ adds the quantity of the repeated dishes :param data:list of dictionary :return:list of dictionary """ try: data = data quantitydict = {} # quantitydict['id']=(item,quantity, remark) for i in data: if quantitydict.get(i['id']): qd = quantitydict[i['id']] item = qd[0] quantity = int(qd[1]) malicious = qd[2] remark = 1 if i['remark'] == 'malicious' else 0 quantitydict[i['id']] = (item, quantity + int(i['quantity']), malicious + remark) else: quantitydict[i['id']] = (i['item'], i['quantity'], 1 if i['remark'] == 'malicious' else 0) line = [] for i, j in quantitydict.iteritems(): dummydict = {} dummydict['id'] = i dummydict['item'] = j[0] dummydict['quantity'] = str(j[1]) dummydict['remark'] = 'malicious' if j[2] > 0 else 'normal' line.append(dummydict) return line except Exception as _: if settings.level == 10: logger.exception('raised exception') return [] def get_availability(self, dish): """checks if the dish is available""" try: with Transaction().start(DBNAME, 1): product = self.Product.search([('name', '=', dish), ('description', '=', 'Dish'), ('type', '=', 'goods')]) if product: product = product[0] return self.dishes.calculate_availability(product=product) except Exception: if settings.level == 10: logger.exception('raised exception') return False