diff --git a/invoice_speedup.diff b/invoice_speedup.diff new file mode 100644 index 0000000..3a11ae4 --- /dev/null +++ b/invoice_speedup.diff @@ -0,0 +1,514 @@ +diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py +--- a/trytond/trytond/modules/account_invoice/invoice.py Tue Jul 07 16:46:50 2015 +0200 ++++ b/trytond/trytond/modules/account_invoice/invoice.py Tue Jul 07 17:12:14 2015 +0200 +@@ -944,33 +944,35 @@ + ''' + Return move line + ''' +- Currency = Pool().get('currency.currency') +- res = {} ++ pool = Pool() ++ Currency = pool.get('currency.currency') ++ MoveLine = pool.get('account.move.line') ++ line = MoveLine() + if self.currency.id != self.company.currency.id: + with Transaction().set_context(date=self.currency_date): +- res['amount_second_currency'] = Currency.compute( ++ line.amount_second_currency = Currency.compute( + self.company.currency, amount, self.currency) +- res['amount_second_currency'] = abs(res['amount_second_currency']) +- res['second_currency'] = self.currency.id ++ line.amount_second_currency = abs(line.amount_second_currency) ++ line.second_currency = self.currency.id + else: +- res['amount_second_currency'] = None +- res['second_currency'] = None ++ line.amount_second_currency = None ++ line.second_currency = None + if amount >= Decimal('0.0'): +- res['debit'] = Decimal('0.0') +- res['credit'] = amount ++ line.debit = Decimal('0.0') ++ line.credit = amount + else: +- res['debit'] = - amount +- res['credit'] = Decimal('0.0') +- res['account'] = self.account.id ++ line.debit = - amount ++ line.credit = Decimal('0.0') ++ line.account = self.account.id + if self.account.party_required: +- res['party'] = self.party.id +- res['maturity_date'] = date +- res['description'] = self.description +- return res ++ line.party = self.party.id ++ line.maturity_date = date ++ line.description = self.description ++ return line + +- def create_move(self): ++ def get_move(self): + ''' +- Create account move for the invoice and return the created move ++ Compute account move for the invoice and return the created move + ''' + pool = Pool() + Move = pool.get('account.move') +@@ -986,10 +988,10 @@ + total = Decimal('0.0') + total_currency = Decimal('0.0') + for line in move_lines: +- total += line['debit'] - line['credit'] +- if line['amount_second_currency']: +- total_currency += line['amount_second_currency'].copy_sign( +- line['debit'] - line['credit']) ++ total += line.debit - line.credit ++ if line.amount_second_currency: ++ total_currency += line.amount_second_currency.copy_sign( ++ line.debit - line.credit) + + term_lines = self.payment_term.compute(total, self.company.currency, + self.invoice_date) +@@ -997,28 +999,23 @@ + if not term_lines: + term_lines = [(Date.today(), total)] + for date, amount in term_lines: +- val = self._get_move_line(date, amount) +- if val['amount_second_currency']: +- remainder_total_currency += val['amount_second_currency'] +- move_lines.append(val) ++ line = self._get_move_line(date, amount) ++ if line.amount_second_currency: ++ remainder_total_currency += line.amount_second_currency ++ move_lines.append(line) + if not self.currency.is_zero(remainder_total_currency): +- move_lines[-1]['amount_second_currency'] -= \ ++ move_lines[-1].amount_second_currency -= \ + remainder_total_currency +- + accounting_date = self.accounting_date or self.invoice_date + period_id = Period.find(self.company.id, date=accounting_date) + +- move, = Move.create([{ +- 'journal': self.journal.id, +- 'period': period_id, +- 'date': accounting_date, +- 'origin': str(self), +- 'company': self.company.id, +- 'lines': [('create', move_lines)], +- }]) +- self.write([self], { +- 'move': move.id, +- }) ++ move = Move() ++ move.journal = self.journal ++ move.period = period_id ++ move.date = accounting_date ++ move.origin = self ++ move.company = self.company ++ move.lines = move_lines + return move + + def set_number(self): +@@ -1050,11 +1047,10 @@ + with Transaction().set_context( + date=self.invoice_date or Date.today()): + number = Sequence.get_id(sequence.id) +- vals = {'number': number} ++ self.number = number + if (not self.invoice_date + and self.type in ('out_invoice', 'out_credit_note')): +- vals['invoice_date'] = Transaction().context['date'] +- self.write([self], vals) ++ self.invoice_date = Transaction().context['date'] + + @classmethod + def check_modify(cls, invoices): +@@ -1308,26 +1304,18 @@ + ''' + Return values to credit invoice. + ''' +- res = {} +- res['type'] = _CREDIT_TYPE[self.type] +- +- for field in ('description', 'comment'): +- res[field] = getattr(self, field) ++ credit = self.__class__() ++ credit.type = _CREDIT_TYPE[self.type] + + for field in ('company', 'party', 'invoice_address', 'currency', +- 'journal', 'account', 'payment_term'): +- res[field] = getattr(self, field).id ++ 'journal', 'account', 'payment_term', 'description', ++ 'comment'): ++ setattr(credit, field, getattr(self, field)) + +- res['lines'] = [] +- if self.lines: +- res['lines'].append(('create', +- [line._credit() for line in self.lines])) ++ credit.lines = [line._credit() for line in self.lines] + +- res['taxes'] = [] +- to_create = [tax._credit() for tax in self.taxes if tax.manual] +- if to_create: +- res['taxes'].append(('create', to_create)) +- return res ++ credit.taxes = [tax._credit() for tax in self.taxes if tax.manual] ++ return credit + + @classmethod + def credit(cls, invoices, refund=False): +@@ -1337,18 +1325,17 @@ + ''' + MoveLine = Pool().get('account.move.line') + +- new_invoices = [] +- for invoice in invoices: +- new_invoice, = cls.create([invoice._credit()]) +- new_invoices.append(new_invoice) +- if refund: +- cls.post([new_invoice]) ++ new_invoices = [i._credit() for i in invoices] ++ new_invoices = cls.create([i._save_values for i in new_invoices]) ++ cls.update_taxes(new_invoices) ++ if refund: ++ cls.post(new_invoices) ++ for invoice, new_invoice in itertools.izip(invoices, new_invoices): + if new_invoice.state == 'posted': + MoveLine.reconcile([l for l in invoice.lines_to_pay + if not l.reconciliation] + + [l for l in new_invoice.lines_to_pay + if not l.reconciliation]) +- cls.update_taxes(new_invoices) + return new_invoices + + @classmethod +@@ -1368,10 +1355,16 @@ + @ModelView.button + @Workflow.transition('validated') + def validate_invoice(cls, invoices): ++ to_write = [] + for invoice in invoices: + if invoice.type in ('in_invoice', 'in_credit_note'): + invoice.set_number() +- invoice.create_move() ++ move = invoice.get_move() ++ if move != invoice.move: ++ invoice.move = invoice.get_move() ++ to_write.extend(([invoice], invoice._save_values)) ++ if to_write: ++ cls.write(*to_write) + + @classmethod + @ModelView.button +@@ -1379,14 +1372,18 @@ + def post(cls, invoices): + Move = Pool().get('account.move') + +- moves = [] ++ to_write = [] + for invoice in invoices: + invoice.set_number() +- moves.append(invoice.create_move()) +- cls.write([i for i in invoices if i.state != 'posted'], { +- 'state': 'posted', +- }) +- Move.post([m for m in moves if m.state != 'posted']) ++ move = invoice.get_move() ++ if move != invoice.move: ++ invoice.move = move ++ to_write.extend(([invoice], invoice._save_values)) ++ ++ if to_write: ++ cls.write(*to_write) ++ cls.write(invoices, {'state': 'posted'}) ++ Move.post([i.move for i in invoices if i.move.state != 'posted']) + for invoice in invoices: + if invoice.type in ('out_invoice', 'out_credit_note'): + invoice.print_invoice() +@@ -1425,14 +1422,17 @@ + + cancel_moves = [] + delete_moves = [] ++ to_write = [] + for invoice in invoices: + if invoice.move: + if invoice.move.state == 'draft': + delete_moves.append(invoice.move) + elif not invoice.cancel_move: + invoice.cancel_move = invoice.move.cancel() +- invoice.save() + cancel_moves.append(invoice.cancel_move) ++ to_write.extend(([invoice], invoice._save_values)) ++ if to_write: ++ cls.write(*to_write) + if delete_moves: + Move.delete(delete_moves) + if cancel_moves: +@@ -2000,6 +2000,7 @@ + pool = Pool() + Tax = pool.get('account.tax') + Currency = pool.get('currency.currency') ++ TaxLine = pool.get('account.tax.line') + + context = self.invoice.get_tax_context() + res = [] +@@ -2022,79 +2023,76 @@ + date=self.invoice.currency_date): + amount = Currency.compute(self.invoice.currency, + amount, self.invoice.company.currency) +- res.append({ +- 'code': base_code_id, +- 'amount': amount, +- 'tax': tax['tax'].id if tax['tax'] else None, +- }) ++ tax_line = TaxLine() ++ tax_line.code = base_code_id ++ tax_line.amount = amount ++ tax_line.tax = tax['tax'] ++ res.append(tax_line) + return res + + def get_move_line(self): + ''' +- Return a list of move lines values for invoice line ++ Return a list of move lines instances for invoice line + ''' +- Currency = Pool().get('currency.currency') +- res = {} ++ pool = Pool() ++ Currency = pool.get('currency.currency') ++ MoveLine = pool.get('account.move.line') + if self.type != 'line': + return [] +- res['description'] = self.description ++ line = MoveLine() ++ line.description = self.description + if self.invoice.currency != self.invoice.company.currency: + with Transaction().set_context(date=self.invoice.currency_date): + amount = Currency.compute(self.invoice.currency, + self.amount, self.invoice.company.currency) +- res['amount_second_currency'] = self.amount +- res['second_currency'] = self.invoice.currency.id ++ line.amount_second_currency = self.amount ++ line.second_currency = self.invoice.currency.id + else: + amount = self.amount +- res['amount_second_currency'] = None +- res['second_currency'] = None ++ line.amount_second_currency = None ++ line.second_currency = None + if self.invoice.type in ('in_invoice', 'out_credit_note'): + if amount >= Decimal('0.0'): +- res['debit'] = amount +- res['credit'] = Decimal('0.0') ++ line.debit = amount ++ line.credit = Decimal('0.0') + else: +- res['debit'] = Decimal('0.0') +- res['credit'] = - amount +- if res['amount_second_currency']: +- res['amount_second_currency'] = \ +- - res['amount_second_currency'] ++ line.debit = Decimal('0.0') ++ line.credit = -amount ++ if line.amount_second_currency: ++ line.amount_second_currency = \ ++ - line.amount_second_currency + else: + if amount >= Decimal('0.0'): +- res['debit'] = Decimal('0.0') +- res['credit'] = amount +- if res['amount_second_currency']: +- res['amount_second_currency'] = \ +- - res['amount_second_currency'] ++ line.debit = Decimal('0.0') ++ line.credit = amount ++ if line.amount_second_currency: ++ line.amount_second_currency = \ ++ - line.amount_second_currency + else: +- res['debit'] = - amount +- res['credit'] = Decimal('0.0') +- res['account'] = self.account.id ++ line.debit = -amount ++ line.credit = Decimal('0.0') ++ line.account = self.account.id + if self.account.party_required: +- res['party'] = self.invoice.party.id ++ line.party = self.invoice.party.id + computed_taxes = self._compute_taxes() + if computed_taxes: +- res['tax_lines'] = [('create', [tax for tax in computed_taxes])] +- return [res] ++ line.tax_lines = computed_taxes ++ return [line] + + def _credit(self): + ''' + Return values to credit line. + ''' +- res = {} +- res['invoice_type'] = _CREDIT_TYPE[self.invoice_type] +- res['origin'] = str(self) ++ credit = self.__class__() ++ credit.invoice_type = _CREDIT_TYPE[self.invoice_type] ++ credit.origin = self + + for field in ('sequence', 'type', 'quantity', 'unit_price', +- 'description'): +- res[field] = getattr(self, field) ++ 'description', 'unit', 'product', 'account'): ++ setattr(credit, field, getattr(self, field)) + +- for field in ('unit', 'product', 'account'): +- res[field] = getattr(getattr(self, field), 'id', None) +- +- res['taxes'] = [] +- if self.taxes: +- res['taxes'].append(('add', [tax.id for tax in self.taxes])) +- return res ++ credit.taxes = self.taxes ++ return credit + + + class InvoiceLineTax(ModelSQL): +@@ -2290,67 +2288,67 @@ + + def get_move_line(self): + ''' +- Return a list of move lines values for invoice tax ++ Return a list of move lines instances for invoice tax + ''' +- Currency = Pool().get('currency.currency') +- res = {} ++ pool = Pool() ++ Currency = pool.get('currency.currency') ++ MoveLine = pool.get('account.move.line') ++ TaxLine = pool.get('account.tax.line') ++ line = MoveLine() + if not self.amount: + return [] +- res['description'] = self.description ++ line.description = self.description + if self.invoice.currency != self.invoice.company.currency: + with Transaction().set_context(date=self.invoice.currency_date): + amount = Currency.compute(self.invoice.currency, self.amount, + self.invoice.company.currency) +- res['amount_second_currency'] = self.amount +- res['second_currency'] = self.invoice.currency.id ++ line.amount_second_currency = self.amount ++ line.second_currency = self.invoice.currency.id + else: + amount = self.amount +- res['amount_second_currency'] = None +- res['second_currency'] = None ++ line.amount_second_currency = None ++ line.second_currency = None + if self.invoice.type in ('in_invoice', 'out_credit_note'): + if amount >= Decimal('0.0'): +- res['debit'] = amount +- res['credit'] = Decimal('0.0') ++ line.debit = amount ++ line.credit = Decimal('0.0') + else: +- res['debit'] = Decimal('0.0') +- res['credit'] = - amount +- if res['amount_second_currency']: +- res['amount_second_currency'] = \ +- - res['amount_second_currency'] ++ line.debit = Decimal('0.0') ++ line.credit = -amount ++ if line.amount_second_currency: ++ line.amount_second_currency = \ ++ - line.amount_second_currency + else: + if amount >= Decimal('0.0'): +- res['debit'] = Decimal('0.0') +- res['credit'] = amount +- if res['amount_second_currency']: +- res['amount_second_currency'] = \ +- - res['amount_second_currency'] ++ line.debit = Decimal('0.0') ++ line.credit = amount ++ if line.amount_second_currency: ++ line.amount_second_currency = \ ++ - line.amount_second_currency + else: +- res['debit'] = - amount +- res['credit'] = Decimal('0.0') +- res['account'] = self.account.id ++ line.debit = -amount ++ line.credit = Decimal('0.0') ++ line.account = self.account.id + if self.account.party_required: +- res['party'] = self.invoice.party.id ++ line.party = self.invoice.party.id + if self.tax_code: +- res['tax_lines'] = [('create', [{ +- 'code': self.tax_code.id, +- 'amount': amount * self.tax_sign, +- 'tax': self.tax and self.tax.id or None +- }])] +- return [res] ++ tax_line = TaxLine() ++ tax_line.code = self.tax_code ++ tax_line.amount = amount * self.tax_sign ++ tax_line.tax = self.tax ++ line.tax_lines = [tax_line] ++ return [line] + + def _credit(self): + ''' + Return values to credit tax. + ''' +- res = {} +- ++ credit = self.__class__() + for field in ('description', 'sequence', 'base', 'amount', +- 'manual', 'base_sign', 'tax_sign'): +- res[field] = getattr(self, field) +- +- for field in ('account', 'base_code', 'tax_code', 'tax'): +- res[field] = getattr(self, field).id +- return res ++ 'manual', 'base_sign', 'tax_sign', 'account', 'base_code', ++ 'tax_code', 'tax'): ++ setattr(credit, field, getattr(self, field)) ++ return credit + + + class PrintInvoiceWarning(ModelView): +diff -r 0e69764f2826 trytond/trytond/modules/account_payment_type/invoice.py +--- a/trytond/trytond/modules/account_payment_type/invoice.py Tue Jul 07 10:10:50 2015 +0200 ++++ b/trytond/trytond/modules/account_payment_type/invoice.py Tue Jul 07 17:06:02 2015 +0200 +@@ -51,7 +51,7 @@ + return res + + def _get_move_line(self, date, amount): +- res = super(Invoice, self)._get_move_line(date, amount) ++ line = super(Invoice, self)._get_move_line(date, amount) + if self.payment_type: +- res['payment_type'] = self.payment_type +- return res ++ line.payment_type = self.payment_type ++ return line +diff -r 6429c9c53cb8 trytond/trytond/modules/account_bank/account.py +--- a/trytond/trytond/modules/account_bank/account.py Tue May 05 14:36:02 2015 +0200 ++++ b/trytond/trytond/modules/account_bank/account.py Tue Jul 07 15:36:26 2015 +0200 +@@ -179,10 +179,10 @@ + ''' + Add account bank to move line when post invoice. + ''' +- res = super(Invoice, self)._get_move_line(date, amount) ++ line = super(Invoice, self)._get_move_line(date, amount) + if self.bank_account: +- res['bank_account'] = self.bank_account +- return res ++ line.bank_account = self.bank_account ++ return line + + @classmethod + def create(cls, vlist): diff --git a/series b/series index 5dad8e2..bd26b40 100644 --- a/series +++ b/series @@ -56,3 +56,4 @@ issue13181002_1.diff issue13211002_190001.diff issue17281002_20001.diff issue20301003_1.diff +invoice_speedup.diff