diff --git a/addons/purchase_manual/__init__.py b/addons/purchase_manual/__init__.py new file mode 100644 index 00000000000..c15d258564d --- /dev/null +++ b/addons/purchase_manual/__init__.py @@ -0,0 +1,25 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved +# $Id$ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + +import purchase_manual +import wizard + diff --git a/addons/purchase_manual/__terp__.py b/addons/purchase_manual/__terp__.py new file mode 100644 index 00000000000..d9c3087c86c --- /dev/null +++ b/addons/purchase_manual/__terp__.py @@ -0,0 +1,42 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved +# $Id$ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + + +{ + 'name': 'Purchase Management - Manual Control of Invoice', + 'version': '1.1', + 'category': 'Generic Modules/Sales & Purchases', + 'description': """Module for purchase management, manual control of invoice""", + 'author': 'Tiny', + 'website': 'http://www.openerp.com', + 'depends': ['purchase'], + 'init_xml': [], + 'update_xml': [ + 'purchase_manual_view.xml', + 'purchase_manual_wizard.xml', + ], + 'demo_xml': [], + 'installable': True, + 'active': False, + 'certificate': False, +} +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase_manual/purchase_manual.py b/addons/purchase_manual/purchase_manual.py new file mode 100644 index 00000000000..e5d32ca49cc --- /dev/null +++ b/addons/purchase_manual/purchase_manual.py @@ -0,0 +1,78 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved +# $Id$ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + +from osv import fields +from osv import osv +import netsvc + +class purchase_order_line(osv.osv): + _inherit='purchase.order.line' + _columns = { + 'state': fields.selection([('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Status', required=True, readonly=True), + 'invoice_lines': fields.many2many('account.invoice.line', 'purchase_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True), + 'invoiced': fields.boolean('Invoiced', readonly=True), + 'partner_id': fields.related('order_id','partner_id',string='Partner',readonly=True,type="many2one", relation="res.partner"), + 'date_order': fields.related('order_id','date_order',string='Order Date',readonly=True,type="date") + } + _defaults = { + 'state': lambda *args: 'draft', + 'invoiced': lambda *a: 0, + + } + def copy_data(self, cr, uid, id, default=None, context={}): + print 'copy called' + if not default: + default = {} + default.update({ + 'state':'draft', + 'invoiced':0, + 'invoice_lines':[], + }) + return super(purchase_order_line, self).copy_data(cr, uid, id, default, context) + + def action_confirm(self, cr, uid, ids, context={}): + self.write(cr, uid, ids, {'state': 'confirmed'}, context) + return True +purchase_order_line() + +class purchase_order(osv.osv): + _inherit='purchase.order' + def action_invoice_create(self, cr, uid, ids, context={}): + print 'Invoice Create' + res = super(purchase_order, self).action_invoice_create(cr, uid, ids, context) + for po in self.browse(cr, uid, ids, context): + todo = [] + for line in po.order_line: + todo.append(line.id) + self.pool.get('purchase.order.line').write(cr, uid, todo, {'invoiced':True}, context) + return res + + def wkf_confirm_order(self, cr, uid, ids, context={}): + res = super(purchase_order, self).wkf_confirm_order(cr, uid, ids, context) + todo = [] + for po in self.browse(cr, uid, ids, context): + for line in po.order_line: + if line.state=='draft': + todo.append(line.id) + self.pool.get('purchase.order.line').action_confirm(cr, uid, todo, context) + return res +purchase_order() diff --git a/addons/purchase_manual/purchase_manual_view.xml b/addons/purchase_manual/purchase_manual_view.xml new file mode 100644 index 00000000000..5ef2d7ac3bb --- /dev/null +++ b/addons/purchase_manual/purchase_manual_view.xml @@ -0,0 +1,117 @@ + + + + + # + # Define PO Line Views + # + + purchase.order.line.form + purchase.order.line + form + 20 + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + purchase.order.line.tree + purchase.order.line + tree + 20 + + + + + + + + + + + + + + + + + + # + # Inherit PO view to get buttons + # + + + Purchase Order Lines + ir.actions.act_window + purchase.order.line + tree,form + + + + tree + + + + + + form + + + + + + + Uninvoiced Purchase Order Lines + ir.actions.act_window + purchase.order.line + [('state','in',('confirmed','done')), ('invoiced','=',False)] + form + tree,form + + + + tree + + + + + + form + + + + + +
+
diff --git a/addons/purchase_manual/purchase_manual_wizard.xml b/addons/purchase_manual/purchase_manual_wizard.xml new file mode 100644 index 00000000000..62771cf9fbb --- /dev/null +++ b/addons/purchase_manual/purchase_manual_wizard.xml @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/addons/purchase_manual/wizard/__init__.py b/addons/purchase_manual/wizard/__init__.py new file mode 100644 index 00000000000..616c5c7090c --- /dev/null +++ b/addons/purchase_manual/wizard/__init__.py @@ -0,0 +1 @@ +import wizard_purchase_line_invoice diff --git a/addons/purchase_manual/wizard/wizard_purchase_line_invoice.py b/addons/purchase_manual/wizard/wizard_purchase_line_invoice.py new file mode 100644 index 00000000000..89d7d188287 --- /dev/null +++ b/addons/purchase_manual/wizard/wizard_purchase_line_invoice.py @@ -0,0 +1,161 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved +# $Id$ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + +import wizard +import netsvc +import ir +import pooler + +invoice_form = """ +
+ + +""" + +invoice_fields = { +} + +def _makeInvoices(self, cr, uid, data, context): + pool = pooler.get_pool(cr.dbname) + res = False + invoices = {} + + def make_invoice(order, lines): + a = order.partner_id.property_account_payable.id + if order.partner_id and order.partner_id.property_payment_term.id: + pay_term = order.partner_id.property_payment_term.id + else: + pay_term = False + inv = { + 'name': order.name, + 'origin': order.name, + 'type': 'in_invoice', + 'reference': "P%dPO%d" % (order.partner_id.id, order.id), + 'account_id': a, + 'partner_id': order.partner_id.id, + 'address_invoice_id': order.partner_address_id.id, + 'address_contact_id': order.partner_address_id.id, + 'invoice_line': [(6,0,lines)], + 'currency_id' : order.pricelist_id.currency_id.id, + 'comment': order.notes, + 'payment_term': pay_term, + 'fiscal_position': order.partner_id.property_account_position.id + } + inv_id = pool.get('account.invoice').create(cr, uid, inv) + return inv_id + + for line in pool.get('purchase.order.line').browse(cr,uid,data['ids']): + if (not line.invoiced) and (line.state not in ('draft','cancel')): + if not line.order_id.id in invoices: + invoices[line.order_id.id] = [] + if line.product_id: + a = line.product_id.product_tmpl_id.property_account_expense.id + if not a: + a = line.product_id.categ_id.property_account_expense_categ.id + if not a: + raise osv.except_osv(_('Error !'), + _('There is no expense account defined ' \ + 'for this product: "%s" (id:%d)') % \ + (line.product_id.name, line.product_id.id,)) + else: + a = pool.get('ir.property').get(cr, uid, + 'property_account_expense_categ', 'product.category', + context=context) + fpos = line.order_id.fiscal_position or False + a = pool.get('account.fiscal.position').map_account(cr, uid, fpos, a) + inv_id = pool.get('account.invoice.line').create(cr, uid, { + 'name': line.name, + 'origin': line.order_id.name, + 'account_id': a, + 'price_unit': line.price_unit, + 'quantity': line.product_qty, + 'uos_id': line.product_uom.id, + 'product_id': line.product_id.id or False, + 'invoice_line_tax_id': [(6, 0, [x.id for x in line.taxes_id])], + 'note': line.notes, + 'account_analytic_id': line.account_analytic_id and line.account_analytic_id.id or False, + }) + cr.execute('insert into purchase_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id)) + pool.get('purchase.order.line').write(cr, uid, [line.id], {'invoiced': True}) + invoices[line.order_id.id].append((line,inv_id)) + + res = [] + for result in invoices.values(): + order = result[0][0].order_id + il = map(lambda x: x[1], result) + res.append(make_invoice(order, il)) + return {'invoice_ids': res} + + return { + 'domain': "[('id','in', ["+','.join(map(str,res))+"])]", + 'name': _('Supplier Invoices'), + 'view_type': 'form', + 'view_mode': 'tree,form', + 'res_model': 'account.invoice', + 'view_id': False, + 'context': "{'type':'in_invoice'}", + 'type': 'ir.actions.act_window' + } + +class line_make_invoice(wizard.interface): + def _open_invoice(self, cr, uid, data, context): + pool_obj = pooler.get_pool(cr.dbname) + model_data_ids = pool_obj.get('ir.model.data').search(cr,uid,[('model','=','ir.ui.view'),('name','=','invoice_supplier_form')]) + resource_id = pool_obj.get('ir.model.data').read(cr,uid,model_data_ids,fields=['res_id'])[0]['res_id'] + return { + 'domain': "[('id','in', ["+','.join(map(str,data['form']['invoice_ids']))+"])]", + 'name': 'Invoices', + 'view_type': 'form', + 'view_mode': 'tree,form', + 'res_model': 'account.invoice', + 'views': [(False,'tree'),(resource_id,'form')], + 'context': "{'type':'in_invoice'}", + 'type': 'ir.actions.act_window' + } + + states = { + 'init' : { + 'actions': [], + 'result': { + 'type': 'form', + 'arch': invoice_form, + 'fields': invoice_fields, + 'state': [ + ('end', 'Cancel'), + ('invoice', 'Create invoices') + ] + } + }, + 'invoice' : { + 'actions' : [_makeInvoices], + 'result' : {'type': 'state', 'state': 'open'} + }, + 'open': { + 'actions': [], + 'result': {'type':'action', 'action':_open_invoice, 'state':'end'} + } + } + +line_make_invoice("purchase.order.line.make_invoice") + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 1492143a7d0..6b50cd3cb48 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -829,7 +829,7 @@ class sale_order_line(osv.osv): 'product_id': line.product_id.id or False, 'invoice_line_tax_id': [(6, 0, [x.id for x in line.tax_id])], 'note': line.notes, - 'account_analytic_id': line.order_id.project_id.id, + 'account_analytic_id': line.order_id.project_id and line.order_id.project_id.id or False, }) cr.execute('insert into sale_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id)) self.write(cr, uid, [line.id], {'invoiced': True})