if type(ids)!=type([]):
ids=[ids]
for po in self.browse(cr, uid, ids, context=context):
- cr.execute("""update purchase_order_line set
- date_planned=%s
- where
- order_id=%s and
- (date_planned=%s or date_planned<%s)""", (value,po.id,po.minimum_planned_date,value))
+ if po.order_line:
+ cr.execute("""update purchase_order_line set
+ date_planned=%s
+ where
+ order_id=%s and
+ (date_planned=%s or date_planned<%s)""", (value,po.id,po.minimum_planned_date,value))
+ cr.execute("""update purchase_order set
+ minimum_planned_date=%s where id=%s""", (value, po.id))
return True
def _minimum_planned_date(self, cr, uid, ids, field_name, arg, context=None):
res={}
purchase_obj=self.browse(cr, uid, ids, context=context)
for purchase in purchase_obj:
- res[purchase.id] = time.strftime('%Y-%m-%d %H:%M:%S')
+ res[purchase.id] = False
if purchase.order_line:
min_date=purchase.order_line[0].date_planned
for line in purchase.order_line:
for invoice in purchase.invoice_ids:
if invoice.state not in ('draft','cancel'):
tot += invoice.amount_untaxed
+
if purchase.amount_untaxed:
- res[purchase.id] = tot * 100.0 / purchase.amount_untaxed
+ res[purchase.id] = min(100.0, tot * 100.0 / (purchase.amount_untaxed))
else:
res[purchase.id] = 0.0
return res
help="Reference of the document that generated this purchase order request."
),
'partner_ref': fields.char('Supplier Reference', states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)],'done':[('readonly',True)]}, size=64),
- 'date_order':fields.date('Date Ordered', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, help="Date on which this document has been created."),
- 'date_approve':fields.date('Date Approved', readonly=1, help="Date on which purchase order has been approved"),
+ 'date_order':fields.date('Date Ordered', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, select=True, help="Date on which this document has been created."),
+ 'date_approve':fields.date('Date Approved', readonly=1, select=True, help="Date on which purchase order has been approved"),
'partner_id':fields.many2one('res.partner', 'Supplier', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)],'done':[('readonly',True)]}, change_default=True),
'partner_address_id':fields.many2one('res.partner.address', 'Address', required=True,
states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)],'done':[('readonly',True)]},domain="[('partner_id', '=', partner_id)]"),
"From Picking: a draft invoice will be pre-generated based on validated receptions.\n" \
"Manual: allows you to generate suppliers invoices by chosing in the uninvoiced lines of all manual purchase orders."
),
- 'minimum_planned_date':fields.function(_minimum_planned_date, fnct_inv=_set_minimum_planned_date, method=True,store=True, string='Expected Date', type='date', help="This is computed as the minimum scheduled date of all purchase order lines' products."),
+ 'minimum_planned_date':fields.function(_minimum_planned_date, fnct_inv=_set_minimum_planned_date, method=True, string='Expected Date', type='date', select=True, help="This is computed as the minimum scheduled date of all purchase order lines' products.",
+ store = {
+ 'purchase.order.line': (_get_order, ['date_planned'], 10),
+ }
+ ),
'amount_untaxed': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Purchase Price'), string='Untaxed Amount',
store={
'purchase.order.line': (_get_order, None, 10),
'company_id': fields.many2one('res.company','Company',required=True,select=1),
}
_defaults = {
- 'date_order': time.strftime('%Y-%m-%d'),
+ 'date_order': lambda *a: time.strftime('%Y-%m-%d'),
'state': 'draft',
'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'purchase.order'),
'shipped': 0,
def onchange_dest_address_id(self, cr, uid, ids, adr_id):
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.id
- return {'value':{'location_id': loc_id, 'warehouse_id': False}}
+ values = {'warehouse_id': False}
+ part_id = self.pool.get('res.partner.address').browse(cr, uid, adr_id).partner_id
+ if part_id:
+ loc_id = part_id.property_stock_customer.id
+ values.update({'location_id': loc_id})
+ return {'value':values}
def onchange_warehouse_id(self, cr, uid, ids, warehouse_id):
if not warehouse_id:
def action_invoice_create(self, cr, uid, ids, *args):
res = False
-
+ property_obj = self.pool.get('ir.property')
+ fp_obj = self.pool.get('account.fiscal.position')
journal_obj = self.pool.get('account.journal')
for o in self.browse(cr, uid, ids):
il = []
for ol in o.order_line:
todo.append(ol.id)
if ol.product_id:
- a = ol.product_id.product_tmpl_id.property_account_expense.id
- if not a:
- a = ol.product_id.categ_id.property_account_expense_categ.id
- if not a:
+ acc_id = ol.product_id.product_tmpl_id.property_account_expense.id
+ if not acc_id:
+ acc_id = ol.product_id.categ_id.property_account_expense_categ.id
+ if not acc_id:
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').id
+ prop = property_obj.get(cr, uid, 'property_account_expense_categ', 'product.category')
+ acc_id = prop and prop.id or False
fpos = o.fiscal_position or False
- a = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, a)
- il.append(self.inv_line_create(cr, uid, a, ol))
+ acc_id = fp_obj.map_account(cr, uid, fpos, acc_id)
+ if not acc_id:
+ raise osv.except_osv(_('Error !'),
+ _('There is no expense account defined in default Properties for Product Category or Fiscal Position is not defined !'))
+ il.append(self.inv_line_create(cr, uid, acc_id, ol))
- a = o.partner_id.property_account_payable.id
+ acc_id = o.partner_id.property_account_payable.id
journal_ids = journal_obj.search(cr, uid, [('type', '=','purchase'),('company_id', '=', o.company_id.id)], limit=1)
if not journal_ids:
raise osv.except_osv(_('Error !'),
_('There is no purchase journal defined for this company: "%s" (id:%d)') % (o.company_id.name, o.company_id.id))
inv = {
'name': o.partner_ref or o.name,
- 'reference': "P%dPO%d" % (o.partner_id.id, o.id),
- 'account_id': a,
+ 'reference': o.partner_ref or o.name,
+ 'account_id': acc_id,
'type': 'in_invoice',
'partner_id': o.partner_id.id,
'currency_id': o.pricelist_id.currency_id.id,
'payment_term': o.partner_id.property_payment_term and o.partner_id.property_payment_term.id or False,
'company_id': o.company_id.id,
}
- inv_id = self.pool.get('account.invoice').create(cr, uid, inv, {'type':'in_invoice'})
+ inv_id = self.pool.get('account.invoice').create(cr, uid, inv, {'type':'in_invoice', 'journal_type': 'purchase'})
self.pool.get('account.invoice').button_compute(cr, uid, [inv_id], {'type':'in_invoice'}, set_total=True)
self.pool.get('purchase.order.line').write(cr, uid, todo, {'invoiced':True})
self.write(cr, uid, [o.id], {'invoice_ids': [(4, inv_id)]})
def action_picking_create(self,cr, uid, ids, *args):
picking_id = False
for order in self.browse(cr, uid, ids):
+ reception_address_id = False
+ if order.dest_address_id:
+ reception_address_id = order.dest_address_id.id
+ elif order.warehouse_id and order.warehouse_id.partner_address_id:
+ reception_address_id = order.warehouse_id.partner_address_id.id
+ else:
+ if order.company_id.partner_id.address:
+ addresses_default = [address.id for address in order.company_id.partner_id.address if address.type == 'default']
+ addresses_delivery = [address.id for address in order.company_id.partner_id.address if address.type == 'delivery']
+ reception_address_id = (addresses_delivery and addresses_delivery[0]) or (addresses_default and addresses_default[0]) or False
loc_id = order.partner_id.property_stock_supplier.id
istate = 'none'
if order.invoice_method=='picking':
'name': pick_name,
'origin': order.name+((order.origin and (':'+order.origin)) or ''),
'type': 'in',
- 'address_id': order.dest_address_id.id or order.partner_address_id.id,
+ 'address_id': reception_address_id,
'invoice_state': istate,
'purchase_id': order.id,
'company_id': order.company_id.id,
if order_line.product_id.product_tmpl_id.type in ('product', 'consu'):
dest = order.location_id.id
move = self.pool.get('stock.move').create(cr, uid, {
- 'name': 'PO:'+order_line.name,
+ 'name': order.name + ': ' +(order_line.name or ''),
'product_id': order_line.product_id.id,
'product_qty': order_line.product_qty,
'product_uos_qty': order_line.product_qty,
_columns = {
'name': fields.char('Description', size=256, required=True),
'product_qty': fields.float('Quantity', required=True, digits=(16,2)),
- 'date_planned': fields.date('Scheduled Date', required=True),
+ 'date_planned': fields.date('Scheduled Date', required=True, select=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),
'notes': fields.text('Notes'),
'order_id': fields.many2one('purchase.order', 'Order Reference', select=True, required=True, ondelete='cascade'),
'account_analytic_id':fields.many2one('account.analytic.account', 'Analytic Account',),
- 'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',store=True,string='Company'),
+ 'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True),
'state': fields.selection([('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', required=True, readonly=True,
help=' * The \'Draft\' state is set automatically when purchase order in draft state. \
\n* The \'Confirmed\' state is set automatically as confirm when purchase order in confirm state. \
def copy_data(self, cr, uid, id, default=None, context=None):
if not default:
default = {}
- default.update({'state':'draft', 'move_ids':[],'invoiced':0,'invoice_lines':[]})
+ default.update({'state':'draft', 'move_ids':[], 'move_dest_id':False, 'invoiced':0,'invoice_lines':[]})
return super(purchase_order_line, self).copy_data(cr, uid, id, default, context)
def product_id_change(self, cr, uid, ids, pricelist, product, qty, uom,
lang=False
if partner_id:
lang=self.pool.get('res.partner').read(cr, uid, partner_id, ['lang'])['lang']
- context={'lang':lang}
- context['partner_id'] = partner_id
-
+ context = self.pool.get('res.users').context_get(cr, uid)
+ context_partner = {'lang':lang, 'partner_id': partner_id}
prod = self.pool.get('product.product').browse(cr, uid, product, context=context)
prod_uom_po = prod.uom_po_id.id
if not uom:
qty = qty or 1.0
seller_delay = 0
- prod_name = self.pool.get('product.product').name_get(cr, uid, [prod.id], context=context)[0][1]
- res = {}
+ prod_name = self.pool.get('product.product').name_get(cr, uid, [prod.id], context=context_partner)[0][1]
+ res = {}
for s in prod.seller_ids:
if s.name.id == partner_id:
seller_delay = s.delay
'uom': uom,
'date': date_order,
})[pricelist]
+ if price is False:
+ warning = {
+ 'title': 'No valid pricelist line found !',
+ 'message':
+ "Couldn't find a pricelist line matching this product and quantity.\n"
+ "You have to change either the product, the quantity or the pricelist."
+ }
+ res.update({'warning': warning})
dt = (datetime.now() + relativedelta(days=int(seller_delay) or 0.0)).strftime('%Y-%m-%d %H:%M:%S')
- res.update({'value': {'price_unit': price, 'name': name or prod_name,
+ res.update({'value': {'price_unit': price, 'name': prod_name,
'taxes_id':map(lambda x: x.id, prod.supplier_taxes_id),
'date_planned': date_planned or dt,'notes': notes or prod.description_purchase,
'product_qty': qty,
return res
def product_uom_change(self, cr, uid, ids, pricelist, product, qty, uom,
- partner_id, date_order=False,fiscal_position=False):
+ partner_id, date_order=False, fiscal_position=False, date_planned=False,
+ name=False, price_unit=False, notes=False):
res = self.product_id_change(cr, uid, ids, pricelist, product, qty, uom,
- partner_id, date_order=date_order,fiscal_position=fiscal_position)
+ partner_id, date_order=date_order, fiscal_position=fiscal_position, date_planned=date_planned,
+ name=name, price_unit=price_unit, notes=notes)
if 'product_uom' in res['value']:
- if uom and uom != res['value']['product_uom']:
+ if uom and (uom != res['value']['product_uom']) and res['value']['product_uom']:
seller_uom_name = self.pool.get('product.uom').read(cr, uid, [res['value']['product_uom']], ['name'])[0]['name']
res.update({'warning': {'title': _('Warning'), 'message': _('The selected supplier only sells this product by %s') % seller_uom_name }})
del res['value']['product_uom']
prod_obj = self.pool.get('product.product')
acc_pos_obj = self.pool.get('account.fiscal.position')
po_obj = self.pool.get('purchase.order')
+ po_line_obj = self.pool.get('purchase.order.line')
for procurement in self.browse(cr, uid, ids, context=context):
res_id = procurement.move_id.id
partner = procurement.product_id.seller_id # Taken Main Supplier of Product of Procurement.
partner_id = partner.id
address_id = partner_obj.address_get(cr, uid, [partner_id], ['delivery'])['delivery']
pricelist_id = partner.property_product_pricelist_purchase.id
+ fiscal_position = partner.property_account_position and partner.property_account_position.id or False
uom_id = procurement.product_id.uom_po_id.id
if seller_qty:
qty = max(qty,seller_qty)
- price = pricelist_obj.price_get(cr, uid, [pricelist_id], procurement.product_id.id, qty, False, {'uom': uom_id})[pricelist_id]
+ price = pricelist_obj.price_get(cr, uid, [pricelist_id], procurement.product_id.id, qty, partner_id, {'uom': uom_id})[pricelist_id]
newdate = datetime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S')
newdate = (newdate - relativedelta(days=company.po_lead)) - relativedelta(days=seller_delay)
+ res_onchange = po_line_obj.product_id_change(cr, uid, ids, pricelist_id, procurement.product_id.id, qty, uom_id,
+ partner_id, time.strftime('%Y-%m-%d'), fiscal_position=fiscal_position, date_planned=datetime.now() + relativedelta(days=seller_delay or 0.0),
+ name=procurement.name, price_unit=procurement.product_id.list_price, notes=procurement.product_id.description_purchase)
+
#Passing partner_id to context for purchase order line integrity of Line name
context.update({'lang': partner.lang, 'partner_id': partner_id})
line = {
'name': product.partner_ref,
- 'product_qty': qty,
+ 'product_qty': res_onchange['value']['product_qty'],
'product_id': procurement.product_id.id,
- 'product_uom': uom_id,
- 'price_unit': price,
+ 'product_uom': res_onchange['value']['product_uom'],
+ 'price_unit': res_onchange['value']['price_unit'],
'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
'move_dest_id': res_id,
'notes': product.description_purchase,