res[id] = cur_obj.round(cr, uid, cur, untax.get(id, 0.0) + tax.get(id, 0.0))
return res
+ def _set_minimum_planned_date(self, cr, uid, ids, name, value, arg, context):
+ if not value: return False
+ if type(ids)!=type([]):
+ ids=[ids]
+ for po in self.browse(cr, uid, ids, context):
+ cr.execute("""update purchase_order_line set
+ date_planned=%s
+ where
+ order_id=%d and
+ (date_planned=%s or date_planned<%s)""", (value,po.id,po.minimum_planned_date,value))
+ return True
+
def _minimum_planned_date(self, cr, uid, ids, field_name, arg, context):
res={}
purchase_obj=self.browse(cr, uid, ids, context=context)
_columns = {
'name': fields.char('Order Reference', size=64, required=True, select=True),
- 'origin': fields.char('Origin', size=64),
+ 'origin': fields.char('Origin', size=64,
+ help="Reference of the document that generated this purchase order request."
+ ),
'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'),
+ 'date_approve':fields.date('Date Approved', readonly=1),
'partner_id':fields.many2one('res.partner', 'Supplier', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, change_default=True),
'partner_address_id':fields.many2one('res.partner.address', 'Address', required=True, states={'posted':[('readonly',True)]}),
- 'dest_address_id':fields.many2one('res.partner.address', 'Destination Address', states={'posted':[('readonly',True)]}),
+ 'dest_address_id':fields.many2one('res.partner.address', 'Destination Address', states={'posted':[('readonly',True)]},
+ help="Put an address if you want to deliver directly from the supplier to the customer." \
+ "In this case, it will remove the warehouse link and set the customer location."
+ ),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', states={'posted':[('readonly',True)]}),
- 'location_id': fields.many2one('stock.location', 'Delivery destination', required=True),
+ 'location_id': fields.many2one('stock.location', 'Destination', required=True),
'pricelist_id':fields.many2one('product.pricelist', 'Pricelist', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, help="The pricelist sets the currency used for this purchase order. It also computes the supplier price for the selected products/quantities."),
'shipped_rate': fields.function(_shipped_rate, method=True, string='Received', type='float'),
'invoiced':fields.boolean('Invoiced & Paid', readonly=True, select=True),
'invoiced_rate': fields.function(_invoiced_rate, method=True, string='Invoiced', type='float'),
- 'invoice_method': fields.selection([('manual','Manual'),('order','From order'),('picking','From picking')], 'Invoicing Control', required=True),
- 'minimum_planned_date':fields.function(_minimum_planned_date, method=True,store=True, string='Planned Date', type='date', help="Minimum schedule date of all products."),
+ 'invoice_method': fields.selection([('manual','Manual'),('order','From Order'),('picking','From Picking')], 'Invoicing Control', required=True,
+ help="From Order: a draft invoice will be pre-generated based on the purchase order. The accountant " \
+ "will just have to validate this invoice for control.\n" \
+ "From Picking: a draft invoice will be pre-genearted based on validated receptions.\n" \
+ "Manual: no invoice will be pre-generated. The accountant will have to encode manually."
+ ),
+ 'minimum_planned_date':fields.function(_minimum_planned_date, fnct_inv=_set_minimum_planned_date, method=True,store=True, string='Planned Date', type='datetime', help="This is computed as the minimum scheduled date of all purchase order lines' products."),
'amount_untaxed': fields.function(_amount_untaxed, method=True, string='Untaxed Amount'),
'amount_tax': fields.function(_amount_tax, method=True, string='Taxes'),
'amount_total': fields.function(_amount_total, method=True, string='Total'),
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.id
+ part = self.pool.get('res.partner').browse(cr, uid, part)
+ pricelist = part.property_product_pricelist_purchase.id
return {'value':{'partner_address_id': addr['default'], 'pricelist_id': pricelist}}
def wkf_approve_order(self, cr, uid, ids):
})
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,
- })
+ '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
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')
+ a = self.pool.get('account.fiscal.position').map_account(cr, uid, o.partner_id, a)
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.id
inv = {
_columns = {
'name': fields.char('Description', size=64, required=True),
'product_qty': fields.float('Quantity', required=True, digits=(16,2)),
- 'date_planned': fields.date('Scheduled date', required=True),
+ 'date_planned': fields.datetime('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),
if not pricelist:
raise osv.except_osv(_('No Pricelist !'), _('You have to select a pricelist in the purchase form !\nPlease set one before choosing a product.'))
if not product:
- return {'value': {'price_unit': 0.0, 'name':'','notes':''}, 'domain':{'product_uom':[]}}
+ return {'value': {'price_unit': 0.0, 'name':'','notes':'', 'product_uom' : False}, 'domain':{'product_uom':[]}}
+ prod= self.pool.get('product.product').browse(cr, uid,product)
lang=False
if partner_id:
- lang=self.pool.get('res.partner').read(cr, uid, [partner_id])[0]['lang']
+ lang=self.pool.get('res.partner').read(cr, uid, partner_id)['lang']
context={'lang':lang}
- prod = self.pool.get('product.product').read(cr, uid, [product], ['supplier_taxes_id','name','seller_delay','uom_po_id','description_purchase'])[0]
+ prod = self.pool.get('product.product').read(cr, uid, product, ['supplier_taxes_id','name','seller_delay','uom_po_id','description_purchase'],context=context)
prod_uom_po = prod['uom_po_id'][0]
if not uom:
uom = prod_uom_po
'uom': uom,
'date': date_order,
})[pricelist]
- dt = (DateTime.now() + DateTime.RelativeDateTime(days=prod['seller_delay'] or 0.0)).strftime('%Y-%m-%d')
+ dt = (DateTime.now() + DateTime.RelativeDateTime(days=prod['seller_delay'] or 0.0)).strftime('%Y-%m-%d %H:%M:%S')
prod_name = self.pool.get('product.product').name_get(cr, uid, [product], context=context)[0][1]
res = {'value': {'price_unit': price, 'name':prod_name, 'taxes_id':prod['supplier_taxes_id'], 'date_planned': dt,'notes':prod['description_purchase'], 'product_uom': uom}}
domain = {}
- if res['value']['taxes_id']:
- taxes = self.pool.get('account.tax').browse(cr, uid,
- [x.id for x in product.supplier_taxes_id])
- taxep = None
- if partner_id:
- taxep = self.pool.get('res.partner').browse(cr, uid,
- partner_id).property_account_supplier_tax
- if not taxep or not taxep.id:
- res['value']['taxes_id'] = [x.id for x in product.taxes_id]
- else:
- res5 = [taxep.id]
- for t in taxes:
- if not t.tax_group==taxep.tax_group:
- res5.append(t.id)
- res['value']['taxes_id'] = res5
+
+ taxes = self.pool.get('account.tax').browse(cr, uid,prod['supplier_taxes_id'])
+ taxep = None
+ if partner_id:
+ partner = self.pool.get('res.partner').browse(cr, uid, partner_id)
+ taxep = partner.property_account_position and partner.property_account_position.account_supplier_tax
+ if not taxep or not taxep.id:
+ res['value']['taxes_id'] = prod['supplier_taxes_id']
+ else:
+ res5 = [taxep.id]
+ for t in taxes:
+ if not t.tax_group==taxep.tax_group:
+ res5.append(t.id)
+ res['value']['taxes_id'] = res5
res2 = self.pool.get('product.uom').read(cr, uid, [uom], ['category_id'])
res3 = self.pool.get('product.uom').read(cr, uid, [prod_uom_po], ['category_id'])