1 ##############################################################################
3 # OpenERP, Open Source Management Solution
4 # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Affero General Public License as
8 # published by the Free Software Foundation, either version 3 of the
9 # License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Affero General Public License for more details.
16 # You should have received a copy of the GNU Affero General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 ##############################################################################
21 from osv import fields, osv
22 from tools.translate import _
24 class sale_advance_payment_inv(osv.osv_memory):
25 _name = "sale.advance.payment.inv"
26 _description = "Sales Advance Payment Invoice"
28 'product_id': fields.many2one('product.product', 'Advance Product', required=True,
29 help="Select a product of type service which is called 'Advance Product'. You may have to create it and set it as a default value on this field."),
30 'amount': fields.float('Advance Amount', digits=(16, 2), required=True, help="The amount to be invoiced in advance."),
31 'qtty': fields.float('Quantity', digits=(16, 2), required=True),
37 def create_invoices(self, cr, uid, ids, context=None):
41 @param self: The object pointer.
42 @param cr: A database cursor
43 @param uid: ID of the user currently logged in
44 @param ids: the ID or list of IDs if we want more than one
45 @param context: A standard dictionary
51 obj_sale = self.pool.get('sale.order')
52 obj_lines = self.pool.get('account.invoice.line')
53 inv_obj = self.pool.get('account.invoice')
57 for sale_adv_obj in self.browse(cr, uid, ids, context=context):
58 for sale in obj_sale.browse(cr, uid, context.get('active_ids', []), context=context):
61 if sale.order_policy == 'postpaid':
64 _("You cannot make an advance on a sales order \
65 that is defined as 'Automatic Invoice after delivery'."))
66 val = obj_lines.product_id_change(cr, uid, [], sale_adv_obj.product_id.id,
67 uom = False, partner_id = sale.partner_id.id, fposition_id = sale.fiscal_position.id)
69 if not res.get('account_id'):
70 raise osv.except_osv(_('Configuration Error !'),
71 _('There is no income account defined ' \
72 'for this product: "%s" (id:%d)') % \
73 (sale_adv_obj.product_id.name, sale_adv_obj.product_id.id,))
75 line_id = obj_lines.create(cr, uid, {
76 'name': res.get('name'),
77 'account_id': res['account_id'],
78 'price_unit': sale_adv_obj.amount,
79 'quantity': sale_adv_obj.qtty,
81 'uos_id': res.get('uos_id'),
82 'product_id': sale_adv_obj.product_id.id,
83 'invoice_line_tax_id': [(6, 0, res.get('invoice_line_tax_id'))],
84 'account_analytic_id': sale.project_id.id or False,
87 create_ids.append(line_id)
89 'name': sale.client_order_ref or sale.name,
91 'type': 'out_invoice',
93 'account_id': sale.partner_id.property_account_receivable.id,
94 'partner_id': sale.partner_id.id,
95 'invoice_line': [(6, 0, create_ids)],
96 'currency_id': sale.pricelist_id.currency_id.id,
98 'payment_term': sale.payment_term.id,
99 'fiscal_position': sale.fiscal_position.id or sale.partner_id.property_account_position.id
102 inv_id = inv_obj.create(cr, uid, inv)
103 inv_obj.button_reset_taxes(cr, uid, [inv_id], context=context)
105 for inv in sale.invoice_ids:
106 ids_inv.append(inv.id)
107 ids_inv.append(inv_id)
108 obj_sale.write(cr, uid, [sale.id], {'invoice_ids': [(6, 0, ids_inv)]})
109 list_inv.append(inv_id)
111 # If invoice on picking: add the cost on the SO
112 # If not, the advance will be deduced when generating the final invoice
114 if sale.order_policy == 'picking':
115 self.pool.get('sale.order.line').create(cr, uid, {
117 'name': res.get('name'),
118 'price_unit': -sale_adv_obj.amount,
119 'product_uom_qty': sale_adv_obj.qtty,
120 'product_uos_qty': sale_adv_obj.qtty,
121 'product_uos': res.get('uos_id'),
122 'product_uom': res.get('uos_id'),
123 'product_id': sale_adv_obj.product_id.id,
125 'tax_id': [(6, 0, res.get('invoice_line_tax_id'))],
128 context.update({'invoice_id':list_inv})
131 'name': 'Open Invoice',
134 'res_model': 'sale.open.invoice',
135 'type': 'ir.actions.act_window',
140 sale_advance_payment_inv()
142 class sale_open_invoice(osv.osv_memory):
143 _name = "sale.open.invoice"
144 _description = "Sales Open Invoice"
146 def open_invoice(self, cr, uid, ids, context=None):
150 @param self: The object pointer.
151 @param cr: A database cursor
152 @param uid: ID of the user currently logged in
153 @param ids: the ID or list of IDs if we want more than one
154 @param context: A standard dictionary
160 mod_obj = self.pool.get('ir.model.data')
161 for advance_pay in self.browse(cr, uid, ids, context=context):
162 form_res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_form')
163 form_id = form_res and form_res[1] or False
164 tree_res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_tree')
165 tree_id = tree_res and tree_res[1] or False
168 'name': _('Advance Invoice'),
170 'view_mode': 'form,tree',
171 'res_model': 'account.invoice',
172 'res_id': int(context['invoice_id'][0]),
174 'views': [(form_id, 'form'), (tree_id, 'tree')],
175 'context': "{'type': 'out_invoice'}",
176 'type': 'ir.actions.act_window',
181 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: