def get_deposit_balance(self, deposit_account): 'Return the deposit account balance (debit - credit) for the party' pool = Pool() MoveLine = pool.get('account.move.line') transaction = Transaction() cursor = transaction.connection.cursor() line = MoveLine.__table__() assert deposit_account.type.deposit where = ((line.account == deposit_account.id) & (line.party == self.id) & (line.reconciliation == Null)) if transaction.database.has_select_for(): cursor.execute(*line.select( Literal(1), where=where, for_=For('UPDATE', nowait=True))) else: MoveLine.lock() cursor.execute(*line.select(Sum( Coalesce(line.debit, 0) - Coalesce(line.credit, 0)), where=where)) amount, = cursor.fetchone() if amount and not isinstance(amount, Decimal): currency = deposit_account.company.currency amount = currency.round(Decimal(str(amount))) return amount or Decimal(0)
def get_id(cls, domain, _lock=False): ''' Return sequence value for the domain ''' if isinstance(domain, cls): domain = domain.id if isinstance(domain, (int, long)): domain = [('id', '=', domain)] # bypass rules on sequences with Transaction().set_context(user=False, _check_access=False): with Transaction().set_user(0): try: sequence, = cls.search(domain, limit=1) except TypeError: cls.raise_user_error('missing') if _lock: transaction = Transaction() database = transaction.database connection = transaction.connection if not database.has_select_for(): database.lock(connection, cls._table) else: table = cls.__table__() query = table.select(Literal(1), where=table.id == sequence.id, for_=For('UPDATE', nowait=True)) cursor = connection.cursor() cursor.execute(*query) date = Transaction().context.get('date') return '%s%s%s' % ( cls._process(sequence.prefix, date=date), cls._get_sequence(sequence), cls._process(sequence.suffix, date=date), )
def get(self, _lock=False): ''' Return the next sequence value ''' cls = self.__class__ # bypass rules on sequences with Transaction().set_context(user=False, _check_access=False): with Transaction().set_user(0): try: sequence = cls(self.id) except TypeError: raise MissingError(gettext('ir.msg_sequence_missing')) if _lock: transaction = Transaction() database = transaction.database connection = transaction.connection if not database.has_select_for(): database.lock(connection, cls._table) else: table = cls.__table__() query = table.select(Literal(1), where=table.id == sequence.id, for_=For('UPDATE', nowait=True)) cursor = connection.cursor() cursor.execute(*query) date = Transaction().context.get('date') return '%s%s%s' % ( cls._process(sequence.prefix, date=date), cls._get_sequence(sequence), cls._process(sequence.suffix, date=date), )
def close(cls, periods): pool = Pool() Product = pool.get('product.product') Location = pool.get('stock.location') Move = pool.get('stock.move') Date = pool.get('ir.date') transaction = Transaction() connection = transaction.connection database = transaction.database # XXX: A move in the period could be inserted before the lock # from a different transaction. It will not be taken in the pbl # computation but it is quite rare because only past periods are # closed. database.lock(connection, Move._table) if database.has_select_for(): move = Move.__table__() query = move.select(Literal(1), for_=For('UPDATE', nowait=True)) with connection.cursor() as cursor: cursor.execute(*query) locations = Location.search([ ('type', 'not in', ['warehouse', 'view']), ], order=[]) today = Date.today() recent_date = max(period.date for period in periods) if recent_date >= today: raise PeriodCloseError(gettext('stock.msg_period_close_date')) if Move.search([('state', '=', 'assigned'), [ 'OR', [ ('effective_date', '=', None), ('planned_date', '<=', recent_date), ], ('effective_date', '<=', recent_date), ]]): raise PeriodCloseError( gettext('stock.msg_period_close_assigned_move')) for grouping in cls.groupings(): Cache = cls.get_cache(grouping) to_create = [] for period in periods: with Transaction().set_context( stock_date_end=period.date, stock_date_start=None, stock_assign=False, forecast=False, stock_destinations=None, ): pbl = Product.products_by_location( [l.id for l in locations], grouping=grouping) for key, quantity in pbl.items(): values = { 'location': key[0], 'period': period.id, 'internal_quantity': quantity, } for i, field in enumerate(grouping, 1): values[field] = key[i] to_create.append(values) if to_create: Cache.create(to_create)
def test_select_for(self): c = self.table.c query = self.table.select(c, for_=For('UPDATE')) self.assertEqual(str(query), 'SELECT "a"."c" FROM "t" AS "a" FOR UPDATE') self.assertEqual(query.params, ())
def test_for(self): for_ = For('UPDATE', Table('t1'), Table('t2'), nowait=True) self.assertEqual(str(for_), 'FOR UPDATE OF "t1", "t2" NOWAIT')
def test_for_single_table(self): for_ = For('UPDATE') for_.tables = Table('t1') self.assertEqual(str(for_), 'FOR UPDATE OF "t1"')