Bugfix, BUG #714
[odoo/odoo.git] / addons / purchase / purchase.py
index 69d0629..b91a2e8 100644 (file)
@@ -48,14 +48,15 @@ class purchase_order(osv.osv):
                return res
 
        def _amount_untaxed(self, cr, uid, ids, field_name, arg, context):
-               id_set = ",".join(map(str, ids))
-               cr.execute("SELECT s.id,COALESCE(SUM(l.price_unit*l.product_qty),0) AS amount FROM purchase_order s LEFT OUTER JOIN purchase_order_line l ON (s.id=l.order_id) WHERE s.id IN ("+id_set+") GROUP BY s.id ")
-               res = dict(cr.fetchall())
+               res = {}
                cur_obj=self.pool.get('res.currency')
-               for id in res.keys():
-                       order=self.browse(cr, uid, [id])[0]
-                       cur=order.pricelist_id.currency_id
-                       res[id]=cur_obj.round(cr, uid, cur, res[id])
+               for purchase in self.browse(cr, uid, ids):
+                       res[purchase.id] = 0.0
+                       for line in purchase.order_line:
+                               res[purchase.id] += line.price_subtotal
+                       cur = purchase.pricelist_id.currency_id
+                       res[purchase.id] = cur_obj.round(cr, uid, cur, res[purchase.id])
+
                return res
 
        def _amount_tax(self, cr, uid, ids, field_name, arg, context):
@@ -85,7 +86,7 @@ class purchase_order(osv.osv):
                'name': fields.char('Order Description', size=64, required=True, select=True),
                'origin': fields.char('Origin', size=64),
                'ref': fields.char('Order Reference', size=64),
-               'partner_ref': fields.char('Partner Reference', size=64),
+               'partner_ref': fields.char('Partner Ref.', size=64),
                'date_order':fields.date('Date Ordered', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}),
                'date_approve':fields.date('Date Approved'),
                'partner_id':fields.many2one('res.partner', 'Partner', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, change_default=True),
@@ -105,7 +106,7 @@ class purchase_order(osv.osv):
                'picking_ids': fields.one2many('stock.picking', 'purchase_id', 'Picking List', readonly=True, help="This is the list of picking list that have been generated for this purchase"),
                'shipped':fields.boolean('Received', readonly=True, select=True),
                'invoiced':fields.boolean('Invoiced & Paid', readonly=True, select=True),
-               'invoice_method': fields.selection([('manual','Manual'),('order','From order'),('picking','From picking')], 'Invoicing method', required=True),
+               'invoice_method': fields.selection([('manual','Manual'),('order','From order'),('picking','From picking')], 'Invoicing Control', required=True),
 
                'amount_untaxed': fields.function(_amount_untaxed, method=True, string='Untaxed Amount'),
                'amount_tax': fields.function(_amount_tax, method=True, string='Taxes'),
@@ -119,7 +120,7 @@ class purchase_order(osv.osv):
                'invoice_method': lambda *a: 'order',
                'invoiced': lambda *a: 0,
                'partner_address_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').address_get(cr, uid, [context['partner_id']], ['default'])['default'],
-               'pricelist_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').browse(cr, uid, context['partner_id']).property_product_pricelist_purchase[0],
+               'pricelist_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').browse(cr, uid, context['partner_id']).property_product_pricelist_purchase.id,
        }
        _name = "purchase.order"
        _description = "Purchase order"
@@ -132,7 +133,7 @@ class purchase_order(osv.osv):
                if not adr_id:
                        return {}
                part_id = self.pool.get('res.partner.address').read(cr, uid, [adr_id], ['partner_id'])[0]['partner_id'][0]
-               loc_id = self.pool.get('res.partner').browse(cr, uid, part_id).property_stock_customer[0]
+               loc_id = self.pool.get('res.partner').browse(cr, uid, part_id).property_stock_customer.id
                return {'value':{'location_id': loc_id, 'warehouse_id': False}}
 
        def onchange_warehouse_id(self, cr, uid, ids, warehouse_id):
@@ -145,7 +146,7 @@ class purchase_order(osv.osv):
                if not part:
                        return {'value':{'partner_address_id': False}}
                addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['default'])
-               pricelist = self.pool.get('res.partner').browse(cr, uid, part).property_product_pricelist_purchase[0]
+               pricelist = self.pool.get('res.partner').browse(cr, uid, part).property_product_pricelist_purchase.id
                return {'value':{'partner_address_id': addr['default'], 'pricelist_id': pricelist}}
 
        def wkf_approve_order(self, cr, uid, ids):
@@ -179,6 +180,17 @@ class purchase_order(osv.osv):
                                           'ref_partner_id': po.partner_id.id,
                                           'ref_doc1': 'purchase.order,%d' % (po.id,),
                                           })
+       def inv_line_create(self,a,ol):
+               return (0, False, {
+                                       'name': ol.name,
+                                       'account_id': a,
+                                       'price_unit': ol.price_unit or 0.0,
+                                       'quantity': ol.product_qty,
+                                       'product_id': ol.product_id.id or False,
+                                       'uos_id': ol.product_uom.id or False,
+                                       'invoice_line_tax_id': [(6, 0, [x.id for x in ol.taxes_id])],
+                                       'account_analytic_id': ol.account_analytic_id.id,
+                               })
 
        def action_invoice_create(self, cr, uid, ids, *args):
                res = False
@@ -187,28 +199,28 @@ class purchase_order(osv.osv):
                        for ol in o.order_line:
 
                                if ol.product_id:
-                                       a = ol.product_id.product_tmpl_id.property_account_expense
+                                       a = ol.product_id.product_tmpl_id.property_account_expense.id
                                        if not a:
-                                               a = ol.product_id.categ_id.property_account_expense_categ
+                                               a = ol.product_id.categ_id.property_account_expense_categ.id
                                        if not a:
-                                               raise osv.except_osv('Error !', 'There is no income account defined for this product: "%s" (id:%d)' % (line.product_id.name, line.product_id.id,))
-                                       a = a[0]
+                                               raise osv.except_osv('Error !', 'There is no expense account defined for this product: "%s" (id:%d)' % (ol.product_id.name, ol.product_id.id,))
                                else:
                                        a = self.pool.get('ir.property').get(cr, uid, 'property_account_expense_categ', 'product.category')
-                               il.append((0, False, {
-                                       'name': ol.name,
-                                       'account_id': a,
-                                       'price_unit': ol.price_unit or 0.0,
-                                       'quantity': ol.product_qty,
-                                       'product_id': ol.product_id.id or False,
-                                       'uos_id': ol.product_uom.id or False,
-                                       'invoice_line_tax_id': [(6, 0, [x.id for x in ol.taxes_id])],
-                                       'account_analytic_id': ol.account_analytic_id.id,
-                               }))
+                               il.append(self.inv_line_create(a,ol))
+#                              il.append((0, False, {
+#                                      'name': ol.name,
+#                                      'account_id': a,
+#                                      'price_unit': ol.price_unit or 0.0,
+#                                      'quantity': ol.product_qty,
+#                                      'product_id': ol.product_id.id or False,
+#                                      'uos_id': ol.product_uom.id or False,
+#                                      'invoice_line_tax_id': [(6, 0, [x.id for x in ol.taxes_id])],
+#                                      'account_analytic_id': ol.account_analytic_id.id,
+#                              }))
 
-                       a = o.partner_id.property_account_payable[0]
+                       a = o.partner_id.property_account_payable.id
                        inv = {
-                               'name': o.name,
+                               'name': o.partner_ref or o.name,
                                'reference': "P%dPO%d" % (o.partner_id.id, o.id),
                                'account_id': a,
                                'type': 'in_invoice',
@@ -220,6 +232,7 @@ class purchase_order(osv.osv):
                                'invoice_line': il,
                        }
                        inv_id = self.pool.get('account.invoice').create(cr, uid, inv, {'type':'in_invoice'})
+                       self.pool.get('account.invoice').button_compute(cr, uid, [inv_id], {'type':'in_invoice'}, set_total=True)
 
                        self.write(cr, uid, [o.id], {'invoice_id': inv_id})
                        res = inv_id
@@ -235,7 +248,7 @@ class purchase_order(osv.osv):
        def action_picking_create(self,cr, uid, ids, *args):
                picking_id = False
                for order in self.browse(cr, uid, ids):
-                       loc_id = order.partner_id.property_stock_supplier[0]
+                       loc_id = order.partner_id.property_stock_supplier.id
                        istate = 'none'
                        if order.invoice_method=='picking':
                                istate = '2binvoiced'
@@ -298,7 +311,7 @@ class purchase_order_line(osv.osv):
        _columns = {
                'name': fields.char('Description', size=64, required=True),
                'product_qty': fields.float('Quantity', required=True, digits=(16,2)),
-               'date_planned': fields.date('Date Promised', required=True),
+               'date_planned': fields.date('Scheduled date', required=True),
                'taxes_id': fields.many2many('account.tax', 'purchase_order_taxe', 'ord_id', 'tax_id', 'Taxes'),
                'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
                'product_id': fields.many2one('product.product', 'Product', domain=[('purchase_ok','=',True)], change_default=True),
@@ -322,9 +335,10 @@ class purchase_order_line(osv.osv):
                default.update({'state':'draft', 'move_id':False})
                return super(purchase_order_line, self).copy(cr, uid, id, default, context)
 
-       def product_id_change(self, cr, uid, ids, pricelist, product, qty, uom, partner_id):
+       def product_id_change(self, cr, uid, ids, pricelist, product, qty, uom,
+                       partner_id, date_order=False):
                if not pricelist:
-                       raise osv.except_osv('No Pricelist !', 'You have to select a pricelist in the sale form !\n Please set one before choosing a product.')
+                       raise osv.except_osv('No Pricelist !', 'You have to select a pricelist in the purchase form !\n Please set one before choosing a product.')
                if not product:
                        return {'value': {'price_unit': 0.0, 'name':'','notes':''}, 'domain':{'product_uom':[]}}
                lang=False
@@ -336,7 +350,13 @@ class purchase_order_line(osv.osv):
                prod_uom_po = prod['uom_po_id'][0]
                if not uom:
                        uom = prod_uom_po
-               price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist], product, qty or 1.0, partner_id, {'uom': uom})[pricelist]
+               if not date_order:
+                       date_order = time.strftime('%Y-%m-%d')
+               price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist],
+                               product, qty or 1.0, partner_id, {
+                                       'uom': uom,
+                                       'date': date_order,
+                                       })[pricelist]
                dt = (DateTime.now() + DateTime.RelativeDateTime(days=prod['seller_delay'] or 0.0)).strftime('%Y-%m-%d')
                prod_name = self.pool.get('product.product').name_get(cr, uid, [product], context=context)[0][1]
 
@@ -352,8 +372,10 @@ class purchase_order_line(osv.osv):
                res['domain'] = domain
                return res
 
-       def product_uom_change(self, cr, uid, ids, pricelist, product, qty, uom, partner_id):
-               res = self.product_id_change(cr, uid, ids, pricelist, product, qty, uom, partner_id)
+       def product_uom_change(self, cr, uid, ids, pricelist, product, qty, uom,
+                       partner_id, date_order=False):
+               res = self.product_id_change(cr, uid, ids, pricelist, product, qty, uom,
+                               partner_id, date_order=date_order)
                if 'product_uom' in res['value']:
                        del res['value']['product_uom']
                if not uom: