Files
tryton/invoice.py
T
2015-03-05 12:48:22 +01:00

148 lines
5.0 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.pool import PoolMeta, Pool
from trytond.model import ModelView, Workflow, fields
from trytond.wizard import Wizard, StateView, StateTransition, Button
from trytond.pyson import Eval, Id
from trytond.transaction import Transaction
__all__ = ['Invoice', 'InvoiceLine',
'DepositRecall', 'DepositRecallStart']
__metaclass__ = PoolMeta
class Invoice:
__name__ = 'account.invoice'
@classmethod
def __setup__(cls):
super(Invoice, cls).__setup__()
cls._error_messages.update({
'deposit_not_enough': (
'The account "%(account)s" for party "%(party)s" '
'has not enough deposit.'),
})
cls._buttons.update({
'recall_deposit': {
'invisible': Eval('state') != 'draft',
'readonly': ~Eval('groups', []).contains(
Id('account', 'group_account')),
},
})
@classmethod
@ModelView.button
@Workflow.transition('posted')
def post(cls, invoices):
super(Invoice, cls).post(invoices)
cls.check_deposit(invoices)
@classmethod
@ModelView.button_action('account_deposit.wizard_recall_deposit')
def recall_deposit(cls, invoices):
pass
@classmethod
def check_deposit(cls, invoices):
to_check = set()
for invoice in invoices:
for line in invoice.lines:
if line.type != 'line':
continue
if line.account.kind == 'deposit':
if ((invoice.type.endswith('invoice')
and line.amount < 0)
or (invoice.type.endswith('credit_note')
and line.amount > 0)):
sign = 1 if invoice.type.startswith('in') else -1
to_check.add((invoice.party, line.account, sign))
for party, account, sign in to_check:
if not party.check_deposit(account, sign):
cls.raise_user_error('deposit_not_enough', {
'account': account.rec_name,
'party': party.rec_name,
})
class InvoiceLine:
__name__ = 'account.invoice.line'
@classmethod
def _account_domain(cls, type_):
domain = super(InvoiceLine, cls)._account_domain(type_)
return domain + ['deposit']
class DepositRecall(Wizard):
'Recall deposit on Invoice'
__name__ = 'account.invoice.recall_deposit'
start = StateView('account.invoice.recall_deposit.start',
'account_deposit.recall_deposit_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Recall', 'recall', 'tryton-ok', default=True),
])
recall = StateTransition()
def default_start(self, fields):
pool = Pool()
Invoice = pool.get('account.invoice')
invoice = Invoice(Transaction().context['active_id'])
return {
'company': invoice.company.id,
}
def transition_recall(self):
pool = Pool()
Invoice = pool.get('account.invoice')
InvoiceLine = pool.get('account.invoice.line')
invoice = Invoice(Transaction().context['active_id'])
amount = 0
balance = invoice.party.get_deposit_balance(self.start.account)
if invoice.type.startswith('in'):
if balance > 0 and invoice.total_amount > 0:
amount = -min(balance, invoice.total_amount)
else:
if balance < 0 and invoice.total_amount > 0:
amount = -min(-balance, invoice.total_amount)
to_delete = []
for line in invoice.lines:
if line.account == self.start.account:
to_delete.append(line)
if amount < 0:
line = self._get_invoice_line(amount)
line.invoice = invoice
line.company = invoice.company
line.sequence = max(l.sequence for l in invoice.lines)
line.save()
if to_delete:
InvoiceLine.delete(to_delete)
return 'end'
def _get_invoice_line(self, amount):
pool = Pool()
Line = pool.get('account.invoice.line')
return Line(
type='line',
quantity=1,
account=self.start.account,
unit_price=amount,
description=self.start.description,
)
class DepositRecallStart(ModelView):
'Recall deposit on Invoice'
__name__ = 'account.invoice.recall_deposit.start'
company = fields.Many2One('company.company', 'Company', readonly=True)
account = fields.Many2One('account.account', 'Account', required=True,
domain=[
('kind', '=', 'deposit'),
('company', '=', Eval('company', -1)),
],
depends=['company'])
description = fields.Text('Description', required=True)