Example #1
0
    def write(cls, *args):
        pool = Pool()
        Purchase = pool.get('purchase.purchase')
        PurchaseLine = pool.get('purchase.line')
        Sale = pool.get('sale.sale')
        SaleLine = pool.get('sale.line')

        super(ShipmentDrop, cls).write(*args)
        cls._set_move_planned_date(sum(args[::2], []))

        actions = iter(args)
        for shipments, values in zip(actions, actions):
            if values.get('state', '') not in ('done', 'cancel'):
                continue
            with Transaction().set_context(_check_access=False):
                move_ids = [m.id for s in shipments for m in s.customer_moves]
                sale_lines = []
                for sub_moves in grouped_slice(move_ids):
                    sale_lines += SaleLine.search([
                        ('moves', 'in', list(sub_moves)),
                    ])
                sales = list(set(l.sale for l in sale_lines or []))
                Sale.process(sales)

                move_ids = [m.id for s in shipments for m in s.supplier_moves]
                purchase_lines = []
                for sub_moves in grouped_slice(move_ids):
                    purchase_lines += PurchaseLine.search([
                        ('moves', 'in', move_ids),
                    ])
                purchases = list(set(l.purchase for l in purchase_lines or []))
                Purchase.process(purchases)
Example #2
0
    def write(cls, *args):
        pool = Pool()
        Purchase = pool.get('purchase.purchase')
        PurchaseLine = pool.get('purchase.line')
        Sale = pool.get('sale.sale')
        SaleLine = pool.get('sale.line')

        super(ShipmentDrop, cls).write(*args)
        cls._set_move_planned_date(sum(args[::2], []))

        actions = iter(args)
        for shipments, values in zip(actions, actions):
            if values.get('state', '') not in ('done', 'cancel'):
                continue
            with Transaction().set_context(_check_access=False):
                move_ids = [m.id for s in shipments for m in s.customer_moves]
                sale_lines = []
                for sub_moves in grouped_slice(move_ids):
                    sale_lines += SaleLine.search([
                            ('moves', 'in', list(sub_moves)),
                            ])
                sales = list(set(l.sale for l in sale_lines or []))
                Sale.process(sales)

                move_ids = [m.id for s in shipments for m in s.supplier_moves]
                purchase_lines = []
                for sub_moves in grouped_slice(move_ids):
                    purchase_lines += PurchaseLine.search([
                            ('moves', 'in', move_ids),
                            ])
                purchases = list(set(l.purchase for l in purchase_lines or []))
                Purchase.process(purchases)
Example #3
0
    def validate_move(cls, moves):
        '''
        Validate balanced move
        '''
        pool = Pool()
        MoveLine = pool.get('tmi.move.line')
        line = MoveLine.__table__()

        cursor = Transaction().connection.cursor()

        amounts = {}
        move2draft_lines = {}
        for sub_move_ids in grouped_slice([m.id for m in moves]):
            red_sql = reduce_ids(line.move, sub_move_ids)

            #cursor.execute(*line.select(line.move,
                    #Sum(line.debit - line.credit),
            #        where=red_sql,
            #        group_by=line.move))
            #amounts.update(dict(cursor.fetchall()))

            cursor.execute(*line.select(line.move, line.id,
                    where=red_sql & (line.state == 'draft'),
                    order_by=line.move))
            move2draft_lines.update(dict((k, [j[1] for j in g])
                    for k, g in groupby(cursor.fetchall(), itemgetter(0))))

        valid_moves = []
        draft_moves = []
        for move in moves:
            #if move.id not in amounts:
            #    continue
            #amount = amounts[move.id]
            # SQLite uses float for SUM
            #if not isinstance(amount, Decimal):
            #    amount = Decimal(amount)
            draft_lines = MoveLine.browse(move2draft_lines.get(move.id, []))
            #if not move.company.currency.is_zero(amount):
            #    draft_moves.append(move.id)
            #    continue
            if not draft_lines:
                continue
            valid_moves.append(move.id)
            
        for move_ids, state in (
                (valid_moves, 'valid'),
                (draft_moves, 'draft'),
                ):
            if move_ids:
                for sub_ids in grouped_slice(move_ids):
                    red_sql = reduce_ids(line.move, sub_ids)
                    # Use SQL to prevent double validate loop
                    cursor.execute(*line.update(
                            columns=[line.state],
                            values=[state],
                            where=red_sql))
Example #4
0
    def default_start(self, fields):
        pool = Pool()
        Move = pool.get('stock.move')
        Product = pool.get('product.product')

        if self.model.__name__ == 'product.product':
            products = self.records
        elif self.model.__name__ == 'product.template':
            templates = self.records
            products = sum((t.products for t in templates), ())
        else:
            products = []

        from_ = None
        for sub_products in grouped_slice(products):
            moves = Move.search([
                ('unit_price_updated', '=', True),
                Product._domain_moves_cost(),
                ('product', 'in', [p.id for p in sub_products]),
            ],
                                order=[('effective_date', 'ASC')],
                                limit=1)
            if moves:
                move, = moves
                from_ = min(from_ or datetime.date.max, move.effective_date)
        return {'from_': from_}
Example #5
0
 def get_pending_payments(parties):
     """
     Return a dictionary with party as key and the list of pending payments
     as value.
     """
     pool = Pool()
     Line = pool.get('account.move.line')
     payments = []
     for sub_parties in grouped_slice(parties):
         payments.append(
             Line.search([
                 ('account.kind', '=', 'receivable'),
                 [
                     'OR',
                     ('debit', '<', 0),
                     ('credit', '>', 0),
                 ],
                 ('party', 'in', [p.id for p in sub_parties]),
                 ('reconciliation', '=', None),
             ],
                         order=[('party', 'ASC'), ('id', 'ASC')]))
     payments = list(chain(*payments))
     return dict(
         (party, list(payments))
         for party, payments in groupby(payments, attrgetter('party')))
Example #6
0
    def write(cls, *args):
        pool = Pool()
        Lines = pool.get('timesheet.line')

        actions = iter(args)
        childs = []
        for works, values in zip(actions, actions):
            if not values.get('timesheet_available', True):
                for sub_works in grouped_slice(works):
                    lines = Lines.search([
                            ('work', 'in', [x.id for x in sub_works]),
                            ], limit=1)
                    if lines:
                        cls.raise_user_error('change_timesheet_available',
                            lines[0].work.rec_name)
            if not values.get('active', True):
                childs += cls.search([
                        ('parent', 'child_of', [w.id for w in works]),
                        ])

        super(Work, cls).write(*args)

        if childs:
            cls.write(childs, {
                    'active': False,
                    })
Example #7
0
 def get_lastmodified(cls, uri, cache=None):
     pool = Pool()
     object_name, object_id = cls._uri2object(uri, cache=cache)
     if object_name == 'ir.attachment':
         Model = pool.get(object_name)
         if object_id:
             if cache is not None:
                 cache.setdefault(Model.__name__, {})
                 ids = cache[Model.__name__].keys()
                 if object_id not in ids:
                     ids.append(object_id)
                 elif 'lastmodified' in cache[Model.__name__][object_id]:
                     return cache[Model.__name__][object_id][
                         'lastmodified']
             else:
                 ids = [object_id]
             res = None
             cursor = Transaction().cursor
             table = Model.__table__()
             for sub_ids in grouped_slice(ids):
                 red_sql = reduce_ids(table.id, sub_ids)
                 cursor.execute(*table.select(table.id,
                         Extract('EPOCH',
                             Coalesce(table.write_date, table.create_date)),
                         where=red_sql))
                 for object_id2, date in cursor.fetchall():
                     if object_id2 == object_id:
                         res = date
                     if cache is not None:
                         cache[Model.__name__].setdefault(object_id2, {})
                         cache[Model.__name__][object_id2][
                             'lastmodified'] = date
             if res is not None:
                 return res
     return time.time()
Example #8
0
    def get_creationdate(cls, uri, cache=None):
        Party = Pool().get('party.party')
        party = Party.__table__()
        party_id = cls.vcard(uri)

        cursor = Transaction().connection.cursor()

        if party_id is None:
            raise DAV_NotFound
        if party_id:
            if cache is not None:
                cache.setdefault('_contact', {})
                ids = cache['_contact'].keys()
                if party_id not in ids:
                    ids.append(party_id)
                elif 'creationdate' in cache['_contact'][party_id]:
                    return cache['_contact'][party_id]['creationdate']
            else:
                ids = [party_id]
            res = None
            for sub_ids in grouped_slice(ids):
                red_sql = reduce_ids(party.id, sub_ids)
                cursor.execute(*party.select(party.id,
                        Extract('EPOCH', party.create_date),
                        where=red_sql))
                for party_id2, date in cursor.fetchall():
                    if party_id2 == party_id:
                        res = date
                    if cache is not None:
                        cache['_contact'].setdefault(party_id2, {})
                        cache['_contact'][party_id2]['creationdate'] = date
            if res is not None:
                return res
        return super(Collection, cls).get_creationdate(uri, cache=cache)
Example #9
0
    def write(cls, *args):
        pool = Pool()
        Lines = pool.get('timesheet.line')

        actions = iter(args)
        childs = []
        for works, values in zip(actions, actions):
            if not values.get('timesheet_available', True):
                for sub_works in grouped_slice(works):
                    lines = Lines.search([
                        ('work', 'in', [x.id for x in sub_works]),
                    ],
                                         limit=1)
                    if lines:
                        cls.raise_user_error('change_timesheet_available',
                                             lines[0].work.rec_name)
            if not values.get('active', True):
                childs += cls.search([
                    ('parent', 'child_of', [w.id for w in works]),
                ])

        super(Work, cls).write(*args)

        if childs:
            cls.write(childs, {
                'active': False,
            })
Example #10
0
    def generate(cls, pains):
        pool = Pool()
        Payment = pool.get('condo.payment')
        payment = Payment.__table__()
        cursor = Transaction().connection.cursor()

        for pain in pains:
            pids = [p.id for group in pain.groups for p in group.payments]
            for sub_ids in grouped_slice(pids):
                red_sql = reduce_ids(payment.id, sub_ids)

                cursor.execute(*payment.update(columns=[payment.state], values=['approved'], where=red_sql))
            try:
                tmpl = pain.get_sepa_template()
                message = (
                    tmpl.generate(pain=pain, datetime=datetime, normalize=sepadecode.sepa_conversion)
                    .filter(remove_comment)
                    .render()
                )
                pain.message = message

                pain.save()
            except:
                Transaction().rollback()
                cls.raise_user_error('generate_error', (pain.reference, pain.company.party.name))
            else:
                Transaction().commit()
Example #11
0
    def delete(cls, requests):
        pool = Pool()
        Sale = pool.get('sale.sale')
        SaleLine = pool.get('sale.line')

        sale_ids = list(
            set(r.origin.id for r in requests if isinstance(r.origin, Sale)))

        with Transaction().set_context(_check_access=False):
            sale_lines = []
            for sub_requests in grouped_slice(requests):
                sale_lines.append(
                    SaleLine.search([
                        ('purchase_request', 'in',
                         [r.id for r in sub_requests]),
                    ]))
            sale_lines = list(chain(*sale_lines))
            if sale_lines:
                SaleLine.write(sale_lines, {
                    'purchase_request': None,
                })

        super(PurchaseRequest, cls).delete(requests)

        if sale_ids:
            with Transaction().set_context(_check_access=False):
                Sale.process(Sale.browse(sale_ids))
Example #12
0
    def _get_duration_timesheet(works, invoiced):
        pool = Pool()
        TimesheetLine = pool.get('timesheet.line')
        cursor = Transaction().cursor
        line = TimesheetLine.__table__()

        durations = {}
        twork2work = dict((w.work.id, w.id) for w in works if w.work)
        ids = twork2work.keys()
        for sub_ids in grouped_slice(ids):
            red_sql = reduce_ids(line.work, sub_ids)
            if invoiced:
                where = line.invoice_line != Null
            else:
                where = line.invoice_line == Null
            cursor.execute(*line.select(line.work, Sum(line.duration),
                    where=red_sql & where,
                    group_by=line.work))
            for twork_id, duration in cursor.fetchall():
                if duration:
                    # SQLite uses float for SUM
                    if not isinstance(duration, datetime.timedelta):
                        duration = datetime.timedelta(seconds=duration)
                    durations[twork2work[twork_id]] = duration
        return durations
Example #13
0
    def get_pending_amount(cls, agents, name):
        pool = Pool()
        Commission = pool.get('commission')
        commission = Commission.__table__()
        cursor = Transaction().connection.cursor()

        ids = [a.id for a in agents]
        amounts = dict.fromkeys(ids, None)
        for sub_ids in grouped_slice(ids):
            where = reduce_ids(commission.agent, sub_ids)
            where &= commission.invoice_line == Null
            query = commission.select(commission.agent,
                                      Sum(commission.amount),
                                      where=where,
                                      group_by=commission.agent)
            cursor.execute(*query)
            amounts.update(dict(cursor.fetchall()))
        digits = cls.pending_amount.digits
        exp = Decimal(str(10.0**-digits[1]))
        for agent_id, amount in amounts.iteritems():
            if amount:
                # SQLite uses float for SUM
                if not isinstance(amount, Decimal):
                    amount = Decimal(str(amount))
                amounts[agent_id] = amount.quantize(exp)
        return amounts
Example #14
0
    def __register__(cls, module_name):
        pool = Pool()
        StatementLine = pool.get('account.statement.line')
        cursor = Transaction().connection.cursor()
        sql_table = cls.__table__()

        super(Move, cls).__register__(module_name)

        # Migration from 3.4:
        # account.statement.line origin changed to account.statement
        statement_line = StatementLine.__table__()
        cursor.execute(*sql_table.join(statement_line,
                condition=(
                    Concat(StatementLine.__name__ + ',', statement_line.id)
                    == sql_table.origin
                    )
                ).select(sql_table.id, statement_line.statement,
                order_by=(sql_table.id, statement_line.statement)))
        for statement_id, values in groupby(cursor.fetchall(), itemgetter(1)):
            ids = [x[0] for x in values]
            for sub_ids in grouped_slice(ids):
                red_sql = reduce_ids(sql_table.id, sub_ids)
                cursor.execute(*sql_table.update(
                        columns=[sql_table.origin],
                        values=['account.statement,%s' % statement_id],
                        where=red_sql))
Example #15
0
 def check_sled_period_closed(cls, lots):
     Period = Pool().get('stock.period')
     Move = Pool().get('stock.move')
     periods = Period.search([
             ('state', '=', 'closed'),
             ], order=[('date', 'DESC')], limit=1)
     if not periods:
         return
     period, = periods
     for lots in grouped_slice(lots):
         lot_ids = [l.id for l in lots]
         moves = Move.search([
                 ('lot', 'in', lot_ids),
                 ['OR', [
                         ('effective_date', '=', None),
                         ('planned_date', '<=', period.date),
                         ],
                     ('effective_date', '<=', period.date),
                     ]], limit=1)
         if moves:
             move, = moves
             cls.raise_user_error('period_closed_expiration_dates', {
                     'lot': move.lot.rec_name,
                     'move': move.rec_name,
                     })
Example #16
0
    def get_duration(cls, works, name):
        pool = Pool()
        Line = pool.get('timesheet.line')
        transaction = Transaction()
        cursor = transaction.connection.cursor()
        context = transaction.context

        table_w = cls.__table__()
        line = Line.__table__()
        ids = [w.id for w in works]
        durations = dict.fromkeys(ids, None)
        where = Literal(True)
        if context.get('from_date'):
            where &= line.date >= context['from_date']
        if context.get('to_date'):
            where &= line.date <= context['to_date']
        if context.get('employees'):
            where &= line.employee.in_(context['employees'])

        query_table = table_w.join(line,
                                   'LEFT',
                                   condition=line.work == table_w.id)

        for sub_ids in grouped_slice(ids):
            red_sql = reduce_ids(table_w.id, sub_ids)
            cursor.execute(*query_table.select(table_w.id,
                                               Sum(line.duration),
                                               where=red_sql & where,
                                               group_by=table_w.id))
            for work_id, duration in cursor.fetchall():
                # SQLite uses float for SUM
                if duration and not isinstance(duration, datetime.timedelta):
                    duration = datetime.timedelta(seconds=duration)
                durations[work_id] = duration
        return durations
Example #17
0
    def write(cls, recurrences, values, *args):

        events = Pool().get('recurrence.event').__table__()
        cursor = Transaction().connection.cursor()

        kwrd = {}
        actions = iter((recurrences, values) + args)
        for records, values in zip(actions, actions):
            for r in records:
                kwrd[r.id] = r.next_call

        super(Recurrence, cls).write(recurrences, values, *args)

        actions = iter((recurrences, values) + args)
        for records, values in zip(actions, actions):
            for r in records:
                if kwrd[r.id] != r.next_call:
                    ids = [e.id for e in r.events]

                    if len(ids):
                        for sub_ids in grouped_slice(ids):
                            red_sql = reduce_ids(events.id, sub_ids)
                            cursor.execute(
                                *events.update(columns=[events.rnext_call],
                                               values=[r.next_call],
                                               where=red_sql))
Example #18
0
    def create_moves(cls, assets, date):
        """
        Creates all account move on assets before a date.
        """
        pool = Pool()
        Move = pool.get('account.move')
        Line = pool.get('account.asset.line')

        cls.create_lines(assets)

        moves = []
        lines = []
        for asset_ids in grouped_slice(assets):
            lines += Line.search([
                ('asset', 'in', list(asset_ids)),
                ('date', '<=', date),
                ('move', '=', None),
            ])
        for line in lines:
            moves.append(line.asset.get_move(line))
        Move.save(moves)
        for move, line in zip(moves, lines):
            line.move = move
        Line.save(lines)
        Move.post(moves)
Example #19
0
 def check_sled_period_closed(cls, lots):
     Period = Pool().get('stock.period')
     Move = Pool().get('stock.move')
     periods = Period.search([
         ('state', '=', 'closed'),
     ],
                             order=[('date', 'DESC')],
                             limit=1)
     if not periods:
         return
     period, = periods
     for lots in grouped_slice(lots):
         lot_ids = [l.id for l in lots]
         moves = Move.search([('lot', 'in', lot_ids),
                              [
                                  'OR',
                                  [
                                      ('effective_date', '=', None),
                                      ('planned_date', '<=', period.date),
                                  ],
                                  ('effective_date', '<=', period.date),
                              ]],
                             limit=1)
         if moves:
             move, = moves
             cls.raise_user_error('period_closed_expiration_dates', {
                 'lot': move.lot.rec_name,
                 'move': move.rec_name,
             })
Example #20
0
def _invoices_to_process(reconciliations):
    pool = Pool()
    Reconciliation = pool.get('account.move.reconciliation')
    Invoice = pool.get('account.invoice')

    move_ids = set()
    others = set()
    for reconciliation in reconciliations:
        for line in reconciliation.lines:
            move_ids.add(line.move.id)
            others.update(line.reconciliations_delegated)

    invoices = set()
    for sub_ids in grouped_slice(move_ids):
        sub_ids = list(sub_ids)
        invoices.update(
            Invoice.search([
                'OR',
                ('move', 'in', sub_ids),
                ('additional_moves', 'in', sub_ids),
            ]))
    if others:
        invoices.update(_invoices_to_process(Reconciliation.browse(others)))

    return invoices
Example #21
0
    def search(cls,
               domain,
               offset=0,
               limit=None,
               order=None,
               count=False,
               query=False):
        menus = super(UIMenu, cls).search(domain,
                                          offset=offset,
                                          limit=limit,
                                          order=order,
                                          count=False,
                                          query=query)
        if query:
            return menus

        if menus:
            parent_ids = {x.parent.id for x in menus if x.parent}
            parents = set()
            for sub_parent_ids in grouped_slice(parent_ids):
                parents.update(
                    cls.search([
                        ('id', 'in', list(sub_parent_ids)),
                    ]))
            # Re-browse to avoid side-cache access
            menus = cls.browse([
                x.id for x in menus
                if (x.parent and x.parent in parents) or not x.parent
            ])

        if count:
            return len(menus)
        return menus
Example #22
0
    def get_pending_amount(cls, agents, name):
        pool = Pool()
        Commission = pool.get('commission')
        commission = Commission.__table__()
        cursor = Transaction().connection.cursor()

        ids = [a.id for a in agents]
        amounts = dict.fromkeys(ids, None)
        for sub_ids in grouped_slice(ids):
            where = reduce_ids(commission.agent, sub_ids)
            where &= commission.invoice_line == Null
            query = commission.select(commission.agent, Sum(commission.amount),
                where=where,
                group_by=commission.agent)
            cursor.execute(*query)
            amounts.update(dict(cursor.fetchall()))
        digits = cls.pending_amount.digits
        exp = Decimal(str(10.0 ** -digits[1]))
        for agent_id, amount in amounts.items():
            if amount:
                # SQLite uses float for SUM
                if not isinstance(amount, Decimal):
                    amount = Decimal(str(amount))
                amounts[agent_id] = amount.quantize(exp)
        return amounts
Example #23
0
    def get(self, ids, model, name, values=None):
        '''
        Return target records ordered.
        '''
        Target = self.get_target()
        field = Target._fields[self.field]
        res = {}
        for i in ids:
            res[i] = []

        targets = []
        for sub_ids in grouped_slice(ids):
            if field._type == 'reference':
                references = ['%s,%s' % (model.__name__, x) for x in sub_ids]
                clause = [(self.field, 'in', references)]
            else:
                clause = [(self.field, 'in', list(sub_ids))]
            if self.filter:
                clause.append(self.filter)
            targets.append(Target.search(clause, order=self.order))
        targets = list(chain(*targets))

        for target in targets:
            origin_id = getattr(target, self.field).id
            res[origin_id].append(target.id)
        return dict((key, tuple(value)) for key, value in res.items())
Example #24
0
    def get_creationdate(cls, uri, cache=None):
        Party = Pool().get('party.party')
        party = Party.__table__()
        party_id = cls.vcard(uri)

        cursor = Transaction().cursor

        if party_id is None:
            raise DAV_NotFound
        if party_id:
            if cache is not None:
                cache.setdefault('_contact', {})
                ids = cache['_contact'].keys()
                if party_id not in ids:
                    ids.append(party_id)
                elif 'creationdate' in cache['_contact'][party_id]:
                    return cache['_contact'][party_id]['creationdate']
            else:
                ids = [party_id]
            res = None
            for sub_ids in grouped_slice(ids):
                red_sql = reduce_ids(party.id, sub_ids)
                cursor.execute(*party.select(party.id,
                        Extract('EPOCH', party.create_date),
                        where=red_sql))
                for party_id2, date in cursor.fetchall():
                    if party_id2 == party_id:
                        res = date
                    if cache is not None:
                        cache['_contact'].setdefault(party_id2, {})
                        cache['_contact'][party_id2]['creationdate'] = date
            if res is not None:
                return res
        return super(Collection, cls).get_creationdate(uri, cache=cache)
Example #25
0
 def run(self):
     transaction = Transaction()
     Model = Pool().get(self.data['model'])
     with transaction.set_user(self.data['user']), \
             transaction.set_context(self.data['context']):
         instances = self.data['instances']
         # Ensure record ids still exist
         if isinstance(instances, int):
             with transaction.set_context(active_test=False):
                 if Model.search([('id', '=', instances)]):
                     instances = Model(instances)
                 else:
                     instances = None
         else:
             ids = set()
             with transaction.set_context(active_test=False):
                 for sub_ids in grouped_slice(instances):
                     records = Model.search([('id', 'in', list(sub_ids))])
                     ids.update(map(int, records))
             if ids:
                 instances = Model.browse(
                     [i for i in instances if i in ids])
             else:
                 instances = None
         if instances is not None:
             getattr(Model, self.data['method'])(
                 instances, *self.data['args'], **self.data['kwargs'])
     if not self.dequeued_at:
         self.dequeued_at = datetime.datetime.now()
     self.finished_at = datetime.datetime.now()
     self.save()
Example #26
0
    def __get__(self, inst, cls):
        if inst is None:
            return self
        pool = Pool()
        schema_model = getattr(cls, self.name).schema_model
        SchemaModel = pool.get(schema_model)

        value = getattr(inst, self.name)
        if not value:
            return value

        domain = []
        if self.type_ == 'values':
            domain = [('type_', '=', 'selection')]

        records = []
        for key_names in grouped_slice(value.keys()):
            records += SchemaModel.search([
                ('name', 'in', key_names),
            ] + domain)
        keys = SchemaModel.get_keys(records)

        if self.type_ == 'keys':
            return {k['name']: k['string'] for k in keys}

        elif self.type_ == 'values':
            trans = {k['name']: dict(k['selection']) for k in keys}
            return {
                k: v if k not in trans else trans[k].get(v, v)
                for k, v in value.items()
            }
Example #27
0
    def get_lines_to_pay(cls, invoices, name):
        pool = Pool()
        Move = pool.get('account.move')
        Line = pool.get('account.move.line')
        Account = pool.get('account.account')
        line = Line.__table__()
        account = Account.__table__()
        move = Move.__table__()
        invoice = cls.__table__()
        cursor = Transaction().connection.cursor()
        _, origin_type = Move.origin.sql_type()

        lines = super(Invoice, cls).get_lines_to_pay(invoices, name)
        for sub_ids in grouped_slice(invoices):
            red_sql = reduce_ids(invoice.id, sub_ids)
            query = invoice.join(move,
                condition=((move.origin == Concat('account.invoice,',
                                Cast(invoice.id, origin_type))))
                    ).join(line, condition=(line.move == move.id)
                    ).join(account, condition=(
                        (line.account == account.id) &
                        Case((invoice.type == 'out',
                            account.kind == 'receivable'),
                            else_=account.kind == 'payable'))).select(
                    invoice.id, line.id,
                    where=(line.maturity_date != None) & red_sql,
                    order_by=(invoice.id, line.maturity_date))
            cursor.execute(*query)
            for invoice_id, line_id in cursor.fetchall():
                if line_id not in lines[invoice_id]:
                    lines[invoice_id].append(line_id)
        return lines
Example #28
0
    def wait(cls, shipments):
        pool = Pool()
        PurchaseRequest = pool.get('purchase.request')
        SaleLine = pool.get('sale.line')
        Move = pool.get('stock.move')

        requests = []
        for sub_lines in grouped_slice([m.origin.id for s in shipments
                    for m in s.supplier_moves]):
            requests += PurchaseRequest.search([
                    ('purchase_line', 'in', list(sub_lines)),
                    ])
        pline2request = {r.purchase_line: r for r in requests}
        sale_lines = SaleLine.search([
                ('purchase_request', 'in', [r.id for r in requests]),
                ])
        request2sline = {sl.purchase_request: sl for sl in sale_lines}

        to_save = []
        for shipment in shipments:
            for move in shipment.supplier_moves:
                sale_line = request2sline[pline2request[move.origin]]
                for move in sale_line.moves:
                    if (move.state not in ('cancel', 'done')
                            and not move.shipment
                            and move.from_location.type == 'drop'):
                        move.shipment = shipment
                        to_save.append(move)
        Move.save(to_save)
        cls._synchronize_moves(shipments)
    def generate(cls, pains):
        pool = Pool()
        Payment = pool.get('condo.payment')
        payment = Payment.__table__()
        cursor = Transaction().connection.cursor()

        for pain in pains:
            pids = [p.id for group in pain.groups for p in group.payments]
            for sub_ids in grouped_slice(pids):
                red_sql = reduce_ids(payment.id, sub_ids)

                cursor.execute(*payment.update(
                        columns=[payment.state],
                        values=['approved'],
                        where=red_sql))
            try:
                tmpl = pain.get_sepa_template()
                message = tmpl.generate(pain=pain,
                    datetime=datetime, normalize=unicodedata.normalize,
                    ).filter(remove_comment).render()
                pain.message = message

                pain.save()
            except:
                Transaction().rollback()
                cls.raise_user_error('generate_error', (pain.reference,pain.company.party.name))
            else:
                Transaction().commit()
Example #30
0
    def delete(cls, requests):
        pool = Pool()
        Sale = pool.get('sale.sale')
        SaleLine = pool.get('sale.line')

        sale_ids = list(set(r.origin.id for r in requests
                if isinstance(r.origin, Sale)))

        with Transaction().set_context(_check_access=False):
            sale_lines = []
            for sub_requests in grouped_slice(requests):
                sale_lines.append(SaleLine.search([
                            ('purchase_request', 'in',
                                [r.id for r in sub_requests]),
                            ]))
            sale_lines = list(chain(*sale_lines))
            if sale_lines:
                SaleLine.write(sale_lines, {
                        'purchase_request': None,
                        })

        super(PurchaseRequest, cls).delete(requests)

        if sale_ids:
            with Transaction().set_context(_check_access=False):
                Sale.process(Sale.browse(sale_ids))
    def validate_active(self):
        #Deactivate mandate as unit mandate on canceled state
        if (self.id > 0) and self.state=='canceled':
            condoparties = Pool().get('condo.party').__table__()
            condopayments = Pool().get('condo.payment').__table__()
            cursor = Transaction().connection.cursor()

            cursor.execute(*condopayments.select(condopayments.id,
                                        where=(condopayments.sepa_mandate == self.id) & (
                                              (condopayments.state == 'draft') | (condopayments.state == 'approved')),
                                        ))
            ids = [ids for (ids,) in cursor.fetchall()]
            if len(ids):
                self.raise_user_error('Can\'t cancel mandate "%s".\nThere are %s payments in draft or approved state with this mandate!',
                                                              (self.identification, len(ids)))

            cursor.execute(*condoparties.select(condoparties.id,
                                        where=(condoparties.sepa_mandate == self.id)))
            ids = [ids for (ids,) in cursor.fetchall()]
            if len(ids):
                self.raise_user_warning('warn_canceled_mandate',
                    'Mandate "%s" will be canceled as mean of payment in %d unit(s)/apartment(s)!', (self.identification, len(ids)))

                for sub_ids in grouped_slice(ids):
                    red_sql = reduce_ids(condoparties.id, sub_ids)
                    # Use SQL to prevent double validate loop
                    cursor.execute(*condoparties.update(
                            columns=[condoparties.sepa_mandate],
                            values=[None],
                            where=red_sql))
Example #32
0
    def get_patient_status(cls, patients, name):
        cursor = Transaction().connection.cursor()
        pool = Pool()
        Registration = pool.get('gnuhealth.inpatient.registration')
        registration = Registration.__table__()

        # Will store statuses {patient: True/False, ...}
        ids = list(map(int, patients))
        result = dict.fromkeys(ids, False)

        for sub_ids in grouped_slice(ids):
            # SQL expression for relevant patient ids
            clause_ids = reduce_ids(registration.id, sub_ids)

            # Hospitalized patient ids
            query = registration.select(
                registration.patient,
                Literal(True),
                where=(registration.state == 'hospitalized') & clause_ids,
                group_by=registration.patient)

            # Update dictionary of patient ids with True statuses
            cursor.execute(*query)
            result.update(cursor.fetchall())

        return result
Example #33
0
    def wait(cls, shipments):
        pool = Pool()
        PurchaseRequest = pool.get('purchase.request')
        SaleLine = pool.get('sale.line')
        Move = pool.get('stock.move')

        requests = []
        for sub_lines in grouped_slice([
                m.origin.id for s in shipments for m in s.supplier_moves
                if m.origin
        ]):
            requests += PurchaseRequest.search([
                ('purchase_line', 'in', list(sub_lines)),
            ])
        pline2request = {r.purchase_line: r for r in requests}
        sale_lines = SaleLine.search([
            ('purchase_request', 'in', [r.id for r in requests]),
        ])
        request2sline = {sl.purchase_request: sl for sl in sale_lines}

        to_save = []
        for shipment in shipments:
            for move in shipment.supplier_moves:
                if not move.origin:
                    continue
                sale_line = request2sline[pline2request[move.origin]]
                for move in sale_line.moves:
                    if (move.state not in ('cancel', 'done')
                            and not move.shipment
                            and move.from_location.type == 'drop'):
                        move.shipment = shipment
                        to_save.append(move)
        Move.save(to_save)
        cls._synchronize_moves(shipments)
Example #34
0
    def get_total(cls, categories, names):
        pool = Pool()
        ReportingCategory = pool.get('sale.reporting.category')
        table = cls.__table__()
        reporting_category = ReportingCategory.__table__()
        cursor = Transaction().connection.cursor()

        categories = cls.search([
            ('parent', 'child_of', [c.id for c in categories]),
        ])
        ids = [c.id for c in categories]
        parents = {}
        reporting_categories = []
        for sub_ids in grouped_slice(ids):
            sub_ids = list(sub_ids)
            where = reduce_ids(table.id, sub_ids)
            cursor.execute(*table.select(table.id, table.parent, where=where))
            parents.update(cursor.fetchall())

            where = reduce_ids(reporting_category.id, sub_ids)
            cursor.execute(
                *reporting_category.select(reporting_category.id, where=where))
            reporting_categories.extend(r for r, in cursor.fetchall())

        result = {}
        reporting_categories = ReportingCategory.browse(reporting_categories)
        for name in names:
            values = dict.fromkeys(ids, 0)
            values.update(
                (c.id, getattr(c, name)) for c in reporting_categories)
            result[name] = cls._sum_tree(categories, values, parents)
        return result
Example #35
0
    def read(cls, ids, fields_names=None):
        Rule = Pool().get('ir.rule')
        cursor = Transaction().cursor
        table = cls.__table__()
        if len(set(ids)) != cls.search([('id', 'in', ids)], count=True):
            cls.raise_user_error('access_error', cls.__doc__)

        writable_ids = []
        domain = Rule.query_get(cls.__name__, mode='write')
        if domain:
            for sub_ids in grouped_slice(ids):
                red_sql = reduce_ids(table.id, sub_ids)
                cursor.execute(*table.select(
                    table.id, where=red_sql & table.id.in_(domain)))
                writable_ids.extend(x[0] for x in cursor.fetchall())
        else:
            writable_ids = ids
        writable_ids = set(writable_ids)

        if fields_names is None:
            fields_names = []
        fields_names = fields_names[:]
        to_remove = set()
        for field in ('classification', 'calendar', 'transp'):
            if field not in fields_names:
                fields_names.append(field)
                to_remove.add(field)
        res = super(Event, cls).read(ids, fields_names=fields_names)
        for record in res:
            if record['classification'] == 'confidential' \
                    and record['id'] not in writable_ids:
                cls._clean_confidential(record, record['transp'])
            for field in to_remove:
                del record[field]
        return res
Example #36
0
    def recompute_cost_price(cls, products, start=None):
        pool = Pool()
        Move = pool.get('stock.move')
        digits = cls.cost_price.digits
        costs = defaultdict(list)
        for product in products:
            if product.type == 'service':
                continue
            cost = getattr(
                product,
                'recompute_cost_price_%s' % product.cost_price_method)(start)
            cost = cost.quantize(Decimal(str(10.0**-digits[1])))
            costs[cost].append(product)

        updated = []
        for sub_products in grouped_slice(products):
            domain = [
                ('unit_price_updated', '=', True),
                cls._domain_moves_cost(),
                ('product', 'in', [p.id for p in sub_products]),
            ]
            if start:
                domain.append(('effective_date', '>=', start))
            updated += Move.search(domain, order=[])
        if updated:
            Move.write(updated, {'unit_price_updated': False})

        if costs:
            cls.update_cost_price(costs)
Example #37
0
    def default_start(self, fields):
        pool = Pool()
        Move = pool.get('stock.move')
        Product = pool.get('product.product')
        Template = pool.get('product.template')
        context = Transaction().context

        if context['active_model'] == 'product.product':
            products = Product.browse(context['active_ids'])
        elif context['active_model'] == 'product.template':
            templates = Template.browse(context['active_ids'])
            products = sum((t.products for t in templates), ())

        from_ = None
        for sub_products in grouped_slice(products):
            moves = Move.search([
                ('unit_price_updated', '=', True),
                Product._domain_moves_cost(),
                ('product', 'in', [p.id for p in sub_products]),
            ],
                                order=[('effective_date', 'ASC')],
                                limit=1)
            if moves:
                move, = moves
                from_ = min(from_ or datetime.date.max, move.effective_date)
        return {'from_': from_}
Example #38
0
 def get_lastmodified(cls, uri, cache=None):
     pool = Pool()
     object_name, object_id = cls._uri2object(uri, cache=cache)
     if object_name == 'ir.attachment':
         Model = pool.get(object_name)
         if object_id:
             if cache is not None:
                 cache.setdefault(Model.__name__, {})
                 ids = cache[Model.__name__].keys()
                 if object_id not in ids:
                     ids.append(object_id)
                 elif 'lastmodified' in cache[Model.__name__][object_id]:
                     return cache[Model.__name__][object_id]['lastmodified']
             else:
                 ids = [object_id]
             res = None
             cursor = Transaction().cursor
             table = Model.__table__()
             for sub_ids in grouped_slice(ids):
                 red_sql = reduce_ids(table.id, sub_ids)
                 cursor.execute(*table.select(
                     table.id,
                     Extract('EPOCH',
                             Coalesce(table.write_date, table.create_date)),
                     where=red_sql))
                 for object_id2, date in cursor.fetchall():
                     if object_id2 == object_id:
                         res = date
                     if cache is not None:
                         cache[Model.__name__].setdefault(object_id2, {})
                         cache[Model.
                               __name__][object_id2]['lastmodified'] = date
             if res is not None:
                 return res
     return time.time()
Example #39
0
    def __register__(cls, module_name):
        pool = Pool()
        StatementLine = pool.get('account.statement.line')
        cursor = Transaction().cursor
        sql_table = cls.__table__()

        super(Move, cls).__register__(module_name)

        # Migration from 3.4:
        # account.statement.line origin changed to account.statement
        statement_line = StatementLine.__table__()
        cursor.execute(*sql_table.join(statement_line,
                condition=(
                    Concat(StatementLine.__name__ + ',', statement_line.id)
                    == sql_table.origin
                    )
                ).select(sql_table.id, statement_line.statement,
                order_by=(sql_table.id, statement_line.statement)))
        for statement_id, values in groupby(cursor.fetchall(), itemgetter(1)):
            ids = [x[0] for x in values]
            for sub_ids in grouped_slice(ids):
                red_sql = reduce_ids(sql_table.id, sub_ids)
                cursor.execute(*sql_table.update(
                        columns=[sql_table.origin],
                        values=['account.statement,%s' % statement_id],
                        where=red_sql))
Example #40
0
    def _get_duration_timesheet(works, invoiced):
        pool = Pool()
        TimesheetLine = pool.get('timesheet.line')
        cursor = Transaction().connection.cursor()
        line = TimesheetLine.__table__()

        durations = defaultdict(datetime.timedelta)
        twork2work = {tw.id: w.id for w in works for tw in w.timesheet_works}
        ids = twork2work.keys()
        for sub_ids in grouped_slice(ids):
            red_sql = reduce_ids(line.work, sub_ids)
            if invoiced:
                where = line.invoice_line != Null
            else:
                where = line.invoice_line == Null
            cursor.execute(*line.select(line.work, Sum(line.duration),
                    where=red_sql & where,
                    group_by=line.work))
            for twork_id, duration in cursor.fetchall():
                if duration:
                    # SQLite uses float for SUM
                    if not isinstance(duration, datetime.timedelta):
                        duration = datetime.timedelta(seconds=duration)
                    durations[twork2work[twork_id]] += duration
        return durations
Example #41
0
    def get_measurements(cls, shipments, names):
        pool = Pool()
        Move = pool.get('stock.move')
        Location = pool.get('stock.location')

        cursor = Transaction().connection.cursor()
        table = cls.__table__()
        move = Move.__table__()
        location = Location.__table__()
        measurements = defaultdict(lambda: defaultdict(lambda: None))

        query = table.join(
            move,
            type_='LEFT',
            condition=cls._measurements_move_condition(table, move)).join(
                location,
                condition=cls._measurements_location_condition(
                    table, move, location)).select(table.id,
                                                   Sum(move.internal_weight),
                                                   Sum(move.internal_volume),
                                                   group_by=[table.id])

        for sub_shipments in grouped_slice(shipments):
            query.where = reduce_ids(table.id, [s.id for s in sub_shipments])
            cursor.execute(*query)
            for id_, weight, volume in cursor:
                if 'weight' in names:
                    measurements['weight'][id_] = weight
                if 'volume' in names:
                    measurements['volume'][id_] = volume
        return measurements
Example #42
0
 def get_empty_locations(cls, locations=None):
     pool = Pool()
     Move = pool.get('stock.move')
     if locations is None:
         locations = cls.search([])
     if not locations:
         return []
     location_ids = list(map(int, locations))
     # Use root to compute for all companies
     # and ensures inactive locations are in the query
     with Transaction().set_user(0), \
             Transaction().set_context(active_test=False):
         query = Move.compute_quantities_query(location_ids,
                                               with_childs=True)
         quantities = Move.compute_quantities(query,
                                              location_ids,
                                              with_childs=True)
         empty = set(location_ids)
         for (location_id, product), quantity in quantities.items():
             if quantity:
                 empty.discard(location_id)
         for sub_ids in grouped_slice(list(empty)):
             sub_ids = list(sub_ids)
             moves = Move.search([
                 ('state', 'not in', ['done', 'cancel']),
                 [
                     'OR',
                     ('from_location', 'in', sub_ids),
                     ('to_location', 'in', sub_ids),
                 ],
             ])
             for move in moves:
                 for location in [move.from_location, move.to_location]:
                     empty.discard(location.id)
     return cls.browse(empty)
Example #43
0
    def __register__(cls, module_name):
        pool = Pool()
        Move = pool.get('stock.move')
        PurchaseLine = pool.get('purchase.line')
        PurchaseRequest = pool.get('purchase.request')
        SaleLine = pool.get('sale.line')
        Location = pool.get('stock.location')
        move = Move.__table__()
        purchase_line = PurchaseLine.__table__()
        purchase_request = PurchaseRequest.__table__()
        sale_line = SaleLine.__table__()
        location = Location.__table__()
        cursor = Transaction().cursor

        super(ShipmentDrop, cls).__register__(module_name)

        # Migration from 3.6
        cursor.execute(*location.select(Count(location.id),
                where=(location.type == 'drop')))
        has_drop_shipment, = cursor.fetchone()

        if not has_drop_shipment:
            drop_shipment = Location(name='Migration Drop Shipment',
                type='drop', active=False)
            drop_shipment.save()
            drop_shipment_location = drop_shipment.id

            move_sale_query = move.join(purchase_line,
                condition=move.origin == Concat('purchase.line,',
                    purchase_line.id)
                ).join(purchase_request,
                condition=purchase_request.purchase_line == purchase_line.id
                ).join(sale_line,
                condition=sale_line.purchase_request == purchase_request.id
                ).select(
                    move.id, move.to_location, sale_line.id,
                    where=move.shipment.like('stock.shipment.drop,%'))
            cursor.execute(*move_sale_query)
            move_sales = cursor.fetchall()

            for sub_move in grouped_slice(move_sales):
                sub_ids = [s[0] for s in sub_move]
                cursor.execute(*move.update(
                        columns=[move.to_location],
                        values=[drop_shipment_location],
                        where=move.id.in_(sub_ids)))

            create_move = move.insert(values=move.select(
                    where=move.shipment.like('stock.shipment.drop,%')))
            cursor.execute(*create_move)

            for move_id, customer_location, line_id in move_sales:
                cursor.execute(move.update(
                        columns=[move.origin, move.from_location,
                            move.to_location],
                        values=[Concat('sale.line,', str(line_id)),
                            drop_shipment_location, customer_location],
                        where=(move.id == move_id)))
Example #44
0
    def transition_handle(self):
        pool = Pool()
        Sale = pool.get('sale.sale')
        SaleLine = pool.get('sale.line')
        Purchase = pool.get('purchase.purchase')
        PurchaseRequest = pool.get('purchase.request')
        Move = pool.get('stock.move')

        super(PurchaseHandleShipmentException, self).transition_handle()

        sales = set()
        moves = set()
        to_recreate = set(self.ask.recreate_moves)
        domain_moves = set(self.ask.domain_moves)
        purchase = Purchase(Transaction().context['active_id'])

        requests = []
        for sub_lines in grouped_slice([pl.id for pl in purchase.lines]):
            requests += PurchaseRequest.search([
                    ('purchase_line', 'in', list(sub_lines)),
                    ])
        pline2request = {r.purchase_line: r for r in requests}
        request2sline = {}
        for sub_requests in grouped_slice(requests):
            sale_lines = SaleLine.search([
                    ('purchase_request', 'in', [r.id for r in sub_requests]),
                    ])
            request2sline.update({sl.purchase_request: sl
                    for sl in sale_lines})

        for line in purchase.lines:
            if not set(line.moves) & domain_moves:
                continue
            if not any(m in to_recreate for m in line.moves):
                sale_line = request2sline[pline2request[line]]
                moves.update({m for m in sale_line.moves
                        if (m.state != 'done'
                            and m.from_location.type == 'drop')})
                sales.add(sale_line.sale)

        if moves:
            Move.cancel(list(moves))
        if sales:
            Sale.process(list(sales))
        return 'end'
Example #45
0
    def get_receivable_payable(cls, parties, names):
        '''
        Function to compute receivable, payable (today or not) for party ids.
        '''
        result = {}
        pool = Pool()
        MoveLine = pool.get('account.move.line')
        Account = pool.get('account.account')
        User = pool.get('res.user')
        Date = pool.get('ir.date')
        cursor = Transaction().cursor

        line = MoveLine.__table__()
        account = Account.__table__()

        for name in names:
            if name not in ('receivable', 'payable',
                    'receivable_today', 'payable_today'):
                raise Exception('Bad argument')
            result[name] = dict((p.id, Decimal('0.0')) for p in parties)

        user = User(Transaction().user)
        if not user.company:
            return result
        company_id = user.company.id

        line_query, _ = MoveLine.query_get(line)

        amount = Sum(Coalesce(line.debit, 0) - Coalesce(line.credit, 0))
        for name in names:
            code = name
            today_where = Literal(True)
            if name in ('receivable_today', 'payable_today'):
                code = name[:-6]
                today_where = ((line.maturity_date <= Date.today())
                    | (line.maturity_date == Null))
            for sub_parties in grouped_slice(parties):
                sub_ids = [p.id for p in sub_parties]
                party_where = reduce_ids(line.party, sub_ids)
                cursor.execute(*line.join(account,
                        condition=account.id == line.account
                        ).select(line.party, amount,
                        where=(account.active
                            & (account.kind == code)
                            & (line.reconciliation == Null)
                            & (account.company == company_id)
                            & line_query
                            & party_where
                            & today_where
                            & (account.kind == code)),
                        group_by=line.party))
                for party, value in cursor.fetchall():
                    # SQLite uses float for SUM
                    if not isinstance(value, Decimal):
                        value = Decimal(str(value))
                    result[name][party] = value
        return result
Example #46
0
 def check_no_move(cls, templates, error):
     Move = Pool().get('stock.move')
     for sub_templates in grouped_slice(templates):
         moves = Move.search([
                 ('product.template', 'in', [t.id for t in sub_templates]),
                 ],
             limit=1, order=[])
         if moves:
             cls.raise_user_error(error)
Example #47
0
    def _purchase_cost(cls, works):
        'Compute direct purchase cost'
        pool = Pool()
        Currency = pool.get('currency.currency')
        PurchaseLine = pool.get('purchase.line')
        InvoiceLine = pool.get('account.invoice.line')
        Invoice = pool.get('account.invoice')
        Company = pool.get('company.company')

        cursor = Transaction().cursor
        table = cls.__table__()
        purchase_line = PurchaseLine.__table__()
        invoice_line = InvoiceLine.__table__()
        invoice = Invoice.__table__()
        company = Company.__table__()

        amounts = defaultdict(Decimal)
        work_ids = [w.id for w in works]
        work2currency = {}
        iline2work = {}
        for sub_ids in grouped_slice(work_ids):
            where = reduce_ids(table.id, sub_ids)
            cursor.execute(*table.join(purchase_line,
                    condition=purchase_line.work == table.id
                    ).join(invoice_line,
                    condition=invoice_line.origin == Concat(
                        'purchase.line,', purchase_line.id)
                    ).join(invoice,
                    condition=invoice_line.invoice == invoice.id
                    ).select(invoice_line.id, table.id,
                    where=where & ~invoice.state.in_(['draft', 'cancel'])))
            iline2work.update(cursor.fetchall())

            cursor.execute(*table.join(company,
                    condition=table.company == company.id
                    ).select(table.id, company.currency,
                    where=where))
            work2currency.update(cursor.fetchall())

        currencies = Currency.browse(set(work2currency.itervalues()))
        id2currency = {c.id: c for c in currencies}

        invoice_lines = InvoiceLine.browse(iline2work.keys())
        for invoice_line in invoice_lines:
            invoice = invoice_line.invoice
            work_id = iline2work[invoice_line.id]
            currency_id = work2currency[work_id]
            currency = id2currency[currency_id]
            if currency != invoice.currency:
                with Transaction().set_context(date=invoice.currency_date):
                    amount = Currency.compute(invoice.currency,
                        invoice_line.amount, currency)
            else:
                amount = invoice_line.amount
            amounts[work_id] += amount
        return amounts
Example #48
0
 def draft(cls, periods):
     for grouping in cls.groupings():
         Cache = cls.get_cache(grouping)
         caches = []
         for sub_periods in grouped_slice(periods):
             caches.append(Cache.search([
                         ('period', 'in',
                             [p.id for p in sub_periods]),
                         ], order=[]))
         Cache.delete(list(chain(*caches)))
Example #49
0
    def get_invoice_payment(cls, lines, name):
        pool = Pool()
        InvoicePaymentLine = pool.get('account.invoice-account.move.line')

        ids = list(map(int, lines))
        result = dict.fromkeys(ids, None)
        for sub_ids in grouped_slice(ids):
            payment_lines = InvoicePaymentLine.search([
                    ('line', 'in', list(sub_ids)),
                    ])
            result.update({p.line.id: p.invoice.id for p in payment_lines})
        return result
Example #50
0
    def delete(cls, categories):
        pool = Pool()
        Product_TariffCode = pool.get('product-customs.tariff.code')
        products = [str(t) for t in categories]

        super(Category, cls).delete(categories)

        for products in grouped_slice(products):
            product_tariffcodes = Product_TariffCode.search([
                    'product', 'in', list(products),
                    ])
            Product_TariffCode.delete(product_tariffcodes)
    def cancel(cls, pains):
        pool = Pool()
        Payment = pool.get('condo.payment')
        payment = Payment.__table__()
        cursor = Transaction().connection.cursor()

        pids = [p.id for payments in [group.payments for pain in pains for group in pain.groups] for p in payments]
        for sub_ids in grouped_slice(pids):
            red_sql = reduce_ids(payment.id, sub_ids)
            cursor.execute(*payment.update(
                    columns=[payment.state],
                    values=['failed'],
                    where=red_sql))
Example #52
0
    def get_debit_credit_balance(cls, journals, names):
        pool = Pool()
        MoveLine = pool.get('account.move.line')
        Move = pool.get('account.move')
        context = Transaction().context
        cursor = Transaction().cursor

        result = {}
        ids = [j.id for j in journals]
        for name in ['debit', 'credit', 'balance']:
            result[name] = dict.fromkeys(ids, 0)

        line = MoveLine.__table__()
        move = Move.__table__()
        where = ((move.date >= context['start_date'])
            & (move.date <= context['end_date']))
        for sub_journals in grouped_slice(journals):
            sub_journals = list(sub_journals)
            red_sql = reduce_ids(move.journal, [j.id for j in sub_journals])
            accounts = None
            for journal in sub_journals:
                credit_account = (journal.credit_account.id
                    if journal.credit_account else None)
                debit_account = (journal.debit_account.id
                    if journal.debit_account else None)
                clause = ((move.journal == journal.id)
                    & (((line.credit != Null)
                            & (line.account == credit_account))
                        | ((line.debit != Null)
                            & (line.account == debit_account))))
                if accounts is None:
                    accounts = clause
                else:
                    accounts |= clause

            query = line.join(move, 'LEFT', condition=line.move == move.id
                ).select(move.journal, Sum(line.debit), Sum(line.credit),
                    where=where & red_sql & accounts,
                    group_by=move.journal)
            cursor.execute(*query)
            for journal_id, debit, credit in cursor.fetchall():
                # SQLite uses float for SUM
                if not isinstance(debit, Decimal):
                    debit = Decimal(str(debit))
                if not isinstance(credit, Decimal):
                    credit = Decimal(str(credit))
                result['debit'][journal_id] = debit
                result['credit'][journal_id] = credit
                result['balance'][journal_id] = debit - credit
        return result
Example #53
0
    def cancel(cls, purchases):
        pool = Pool()
        SaleLine = pool.get('sale.line')
        Move = pool.get('stock.move')

        super(Purchase, cls).cancel(purchases)
        sale_lines = []
        for sub_purchases in grouped_slice(purchases):
            sale_lines += SaleLine.search([
                    ('purchase_request.purchase_line.purchase', 'in',
                        [p.id for p in sub_purchases]),
                    ])
        Move.cancel([m for sl in sale_lines for m in sl.moves
                if m.state != 'done' and m.from_location.type == 'drop'])
Example #54
0
    def _get_invoiced_amount_progress(cls, works):
        pool = Pool()
        Progress = pool.get('project.work.invoiced_progress')
        InvoiceLine = pool.get('account.invoice.line')
        Company = pool.get('company.company')
        Currency = pool.get('currency.currency')

        cursor = Transaction().cursor
        table = cls.__table__()
        progress = Progress.__table__()
        invoice_line = InvoiceLine.__table__()
        company = Company.__table__()

        amounts = defaultdict(Decimal)
        work2currency = {}
        work_ids = [w.id for w in works]
        for sub_ids in grouped_slice(work_ids):
            where = reduce_ids(table.id, sub_ids)
            cursor.execute(*table.join(progress,
                    condition=progress.work == table.id
                    ).join(invoice_line,
                    condition=progress.invoice_line == invoice_line.id
                    ).select(table.id,
                    Sum(progress.effort_duration * invoice_line.unit_price),
                    where=where,
                    group_by=table.id))
            for work_id, amount in cursor.fetchall():
                if isinstance(amount, datetime.timedelta):
                    amount = amount.total_seconds()
                # Amount computed in second instead of hours
                if amount is not None:
                    amount /= 60 * 60
                else:
                    amount = 0
                amounts[work_id] = amount

            cursor.execute(*table.join(company,
                    condition=table.company == company.id
                    ).select(table.id, company.currency,
                    where=where))
            work2currency.update(cursor.fetchall())

        currencies = Currency.browse(set(work2currency.itervalues()))
        id2currency = {c.id: c for c in currencies}

        for work in works:
            currency = id2currency[work2currency[work.id]]
            amounts[work.id] = currency.round(Decimal(amounts[work.id]))
        return amounts
Example #55
0
    def _get_invoiced_amount_timesheet(cls, works):
        pool = Pool()
        TimesheetWork = pool.get('timesheet.work')
        TimesheetLine = pool.get('timesheet.line')
        InvoiceLine = pool.get('account.invoice.line')
        Company = pool.get('company.company')
        Currency = pool.get('currency.currency')

        cursor = Transaction().cursor
        table = cls.__table__()
        timesheet_work = TimesheetWork.__table__()
        timesheet_line = TimesheetLine.__table__()
        invoice_line = InvoiceLine.__table__()
        company = Company.__table__()

        amounts = {}
        work2currency = {}
        work_ids = [w.id for w in works]
        for sub_ids in grouped_slice(work_ids):
            where = reduce_ids(table.id, sub_ids)
            cursor.execute(*table.join(timesheet_work,
                    condition=table.work == timesheet_work.id
                    ).join(timesheet_line,
                    condition=timesheet_line.work == timesheet_work.id
                    ).join(invoice_line,
                    condition=timesheet_line.invoice_line == invoice_line.id
                    ).select(table.id,
                    Sum(timesheet_line.duration * invoice_line.unit_price),
                    where=where,
                    group_by=table.id))
            amounts.update(cursor.fetchall())

            cursor.execute(*table.join(company,
                    condition=table.company == company.id
                    ).select(table.id, company.currency,
                    where=where))
            work2currency.update(cursor.fetchall())

        currencies = Currency.browse(set(work2currency.itervalues()))
        id2currency = {c.id: c for c in currencies}

        for work in works:
            currency = id2currency[work2currency[work.id]]
            amount = amounts.get(work.id, 0)
            if isinstance(amount, datetime.timedelta):
                amount = amount.total_seconds()
            amount = amount / 60 / 60
            amounts[work.id] = currency.round(Decimal(str(amount)))
        return amounts
Example #56
0
    def get_lastmodified(cls, uri, cache=None):
        pool = Pool()
        Party = pool.get('party.party')
        Address = pool.get('party.address')
        ContactMechanism = pool.get('party.contact_mechanism')
        party = Party.__table__()
        address = Address.__table__()
        contact_mechanism = ContactMechanism.__table__()

        cursor = Transaction().cursor

        party_id = cls.vcard(uri)
        if party_id:
            if cache is not None:
                cache.setdefault('_contact', {})
                ids = cache['_contact'].keys()
                if party_id not in ids:
                    ids.append(party_id)
                elif 'lastmodified' in cache['_contact'][party_id]:
                    return cache['_contact'][party_id]['lastmodified']
            else:
                ids = [party_id]
            res = None
            for sub_ids in grouped_slice(ids):
                red_sql = reduce_ids(party.id, sub_ids)
                cursor.execute(*party.join(address, 'LEFT',
                        condition=party.id == address.party
                        ).join(contact_mechanism, 'LEFT',
                        condition=party.id == contact_mechanism.party
                        ).select(party.id,
                        Max(Extract('EPOCH', Coalesce(party.write_date,
                                    party.create_date))),
                        Max(Extract('EPOCH', Coalesce(address.write_date,
                                    address.create_date))),
                        Max(Extract('EPOCH', Coalesce(
                                    contact_mechanism.write_date,
                                    contact_mechanism.create_date))),
                        where=red_sql,
                        group_by=party.id))
                for party_id2, date_p, date_a, date_c in cursor.fetchall():
                    date = max(date_p, date_a, date_c)
                    if party_id2 == party_id:
                        res = date
                    if cache is not None:
                        cache['_contact'].setdefault(party_id2, {})
                        cache['_contact'][party_id2]['lastmodified'] = date
            if res is not None:
                return res
        return super(Collection, cls).get_lastmodified(uri, cache=cache)
Example #57
0
    def has_payments(self, mandates, name):
        pool = Pool()
        Payment = pool.get('account.payment')
        payment = Payment.__table__
        cursor = Transaction().cursor

        has_payments = dict.fromkeys([m.id for m in mandates], False)
        for sub_ids in grouped_slice(mandates):
            red_sql = reduce_ids(payment.sepa_mandate, sub_ids)
            cursor.execute(*payment.select(payment.sepa_mandate, Literal(True),
                    where=red_sql,
                    group_by=payment.sepa_mandate))
            has_payments.update(cursor.fetchall())

        return {'has_payments': has_payments}
Example #58
0
    def transition_cancel_request(self):
        pool = Pool()
        SaleLine = pool.get('sale.line')
        Move = pool.get('stock.move')

        next_state = super(HandlePurchaseCancellationException,
            self).transition_cancel_request()
        moves = []
        for sub_ids in grouped_slice(Transaction().context['active_ids']):
            sale_lines = SaleLine.search([
                    ('purchase_request', 'in', sub_ids),
                    ])
            moves += [m for line in sale_lines for m in line.moves]
        if moves:
            Move.cancel(moves)
        return next_state
Example #59
0
    def get_quantity_executed(cls, lines, name):
        cursor = Transaction().cursor
        pool = Pool()
        Move = pool.get('stock.move')
        Location = pool.get('stock.location')
        Uom = pool.get('product.uom')
        Forecast = pool.get('stock.forecast')
        LineMove = pool.get('stock.forecast.line-stock.move')

        move = Move.__table__()
        location_from = Location.__table__()
        location_to = Location.__table__()
        line_move = LineMove.__table__()

        result = dict((x.id, 0) for x in lines)
        key = lambda line: line.forecast.id
        lines.sort(key=key)
        for forecast_id, lines in itertools.groupby(lines, key):
            forecast = Forecast(forecast_id)
            product2line = dict((line.product.id, line) for line in lines)
            product_ids = product2line.keys()
            for sub_ids in grouped_slice(product_ids):
                red_sql = reduce_ids(move.product, sub_ids)
                cursor.execute(*move.join(location_from,
                        condition=move.from_location == location_from.id
                        ).join(location_to,
                        condition=move.to_location == location_to.id
                        ).join(line_move, 'LEFT',
                        condition=move.id == line_move.move
                        ).select(move.product, Sum(move.internal_quantity),
                        where=red_sql
                        & (location_from.left >= forecast.warehouse.left)
                        & (location_from.right <= forecast.warehouse.right)
                        & (location_to.left >= forecast.destination.left)
                        & (location_to.right <= forecast.destination.right)
                        & (move.state != 'cancel')
                        & (Coalesce(move.effective_date, move.planned_date)
                            >= forecast.from_date)
                        & (Coalesce(move.effective_date, move.planned_date)
                            <= forecast.to_date)
                        & (line_move.id == Null),
                        group_by=move.product))
                for product_id, quantity in cursor.fetchall():
                    line = product2line[product_id]
                    result[line.id] = Uom.compute_qty(line.product.default_uom,
                        quantity, line.uom)
        return result
    def validate(cls, paymentgroups):
        super(CondoPaymentGroup, cls).validate(paymentgroups)

        table = cls.__table__()
        payments = Pool().get('condo.payment').__table__()

        for paymentgroup in paymentgroups:
            if paymentgroup.readonly:
                with Transaction().new_transaction(readonly=True) as transaction,\
                    transaction.connection.cursor() as cursor:
                    cursor.execute(*table.select(table.date,
                                 where=(table.id == paymentgroup.id) &
                                       (table.date != paymentgroup.date)))
                    if cursor.fetchone():
                        cls.raise_user_error('readonly_paymentgroup', (paymentgroup.reference)
                            )
                return

            cursor = Transaction().connection.cursor()
            cursor.execute(*payments.select(payments.id,
                         where=(payments.group == paymentgroup.id) &
                               (payments.date < paymentgroup.date) &
                               (payments.state != 'draft')))
            if cursor.fetchall():
                cls.raise_user_error('payments_approved', (paymentgroup.reference)
                    )

            paymentgroup.check_today()
            paymentgroup.check_businessdate()
            paymentgroup.company_has_sepa_creditor_identifier()

            #if has drafted payments with due date before new date
            #update date field of payments
            cursor.execute(*payments.select(payments.id,
                         where=(payments.group == paymentgroup.id) &
                               (payments.date < paymentgroup.date) &
                               (payments.state == 'draft')))
            ids_draft = [ids for (ids,) in cursor.fetchall()]

            if len(ids_draft):
                for sub_ids in grouped_slice(ids_draft):
                    red_sql = reduce_ids(payments.id, sub_ids)
                    # Use SQL to prevent double validate loop
                    cursor.execute(*payments.update(
                            columns=[payments.date],
                            values=[paymentgroup.date],
                            where=red_sql))