sale_shop()
-def _incoterm_get(self, cr, uid, context={}):
+def _incoterm_get(self, cr, uid, context=None):
+ if context is None:
+ context = {}
cr.execute('select code, code||\', \'||name from stock_incoterms where active')
return cr.fetchall()
-
class sale_order(osv.osv):
_name = "sale.order"
+ _log_create = True
_description = "Sale Order"
- def copy(self, cr, uid, id, default=None, context={}):
+ def copy(self, cr, uid, id, default=None, context=None):
+ if context is None:
+ context = {}
if not default:
default = {}
default.update({
'picking_ids': [],
'name': self.pool.get('ir.sequence').get(cr, uid, 'sale.order'),
})
- return super(sale_order, self).copy(cr, uid, id, default, context)
+ return super(sale_order, self).copy(cr, uid, id, default, context=context)
- def _amount_line_tax(self, cr, uid, line, context={}):
+ def _amount_line_tax(self, cr, uid, line, context=None):
+ if context is None:
+ context = {}
val = 0.0
for c in self.pool.get('account.tax').compute(cr, uid, line.tax_id, line.price_unit * (1-(line.discount or 0.0)/100.0), line.product_uom_qty, line.order_id.partner_invoice_id.id, line.product_id, line.order_id.partner_id):
val += c['amount']
return val
- def _amount_all(self, cr, uid, ids, field_name, arg, context):
+ def _amount_all(self, cr, uid, ids, field_name, arg, context=None):
+ if context is None:
+ context = {}
res = {}
cur_obj = self.pool.get('res.currency')
- for order in self.browse(cr, uid, ids):
+ for order in self.browse(cr, uid, ids, context):
res[order.id] = {
'amount_untaxed': 0.0,
'amount_tax': 0.0,
cur = order.pricelist_id.currency_id
for line in order.order_line:
val1 += line.price_subtotal
- val += self._amount_line_tax(cr, uid, line, context)
+ val += self._amount_line_tax(cr, uid, line, context=context)
res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur, val)
res[order.id]['amount_untaxed'] = cur_obj.round(cr, uid, cur, val1)
res[order.id]['amount_total'] = res[order.id]['amount_untaxed'] + res[order.id]['amount_tax']
return res
def _picked_rate(self, cr, uid, ids, name, arg, context=None):
+ if context is None:
+ context = {}
if not ids:
return {}
res = {}
for id in ids:
res[id] = [0.0, 0.0]
cr.execute('''SELECT
- p.sale_id,sum(m.product_qty), m.state
+ p.sale_id,sum(m.product_qty), mp.state as mp_state
FROM
stock_move m
LEFT JOIN
stock_picking p on (p.id=m.picking_id)
+ LEFT JOIN
+ mrp_procurement mp on (mp.move_id=m.id)
WHERE
- p.sale_id = ANY(%s) GROUP BY m.state, p.sale_id''',(ids,))
- for oid, nbr, state in cr.fetchall():
- if state == 'cancel':
+ p.sale_id = ANY(%s) GROUP BY mp.state, p.sale_id''',(ids,))
+ for oid, nbr, mp_state in cr.fetchall():
+ if mp_state == 'cancel':
continue
- if state == 'done':
+ if mp_state == 'done':
res[oid][0] += nbr or 0.0
res[oid][1] += nbr or 0.0
else:
res[r] = 0.0
else:
res[r] = 100.0 * res[r][0] / res[r][1]
- for order in self.browse(cr, uid, ids, context):
+ for order in self.browse(cr, uid, ids, context=context):
if order.shipped:
res[order.id] = 100.0
return res
def _invoiced_rate(self, cursor, user, ids, name, arg, context=None):
+ if context is None:
+ context = {}
res = {}
for sale in self.browse(cursor, user, ids, context=context):
if sale.invoiced:
return res
def _invoiced(self, cursor, user, ids, name, arg, context=None):
+ if context is None:
+ context = {}
res = {}
for sale in self.browse(cursor, user, ids, context=context):
res[sale.id] = True
res[sale.id] = False
return res
- def _invoiced_search(self, cursor, user, obj, name, args, context):
+ def _invoiced_search(self, cursor, user, obj, name, args, context=None):
+ if context is None:
+ context = {}
if not len(args):
return []
clause = ''
return [('id', '=', 0)]
return [('id', 'in', [x[0] for x in res])]
- def _get_order(self, cr, uid, ids, context={}):
+ def _get_order(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
result = {}
for line in self.pool.get('sale.order.line').browse(cr, uid, ids, context=context):
result[line.order_id.id] = True
'partner_id': fields.many2one('res.partner', 'Customer', readonly=True, states={'draft': [('readonly', False)]}, required=True, change_default=True, select=True),
'partner_invoice_id': fields.many2one('res.partner.address', 'Invoice Address', readonly=True, required=True, states={'draft': [('readonly', False)]}),
'partner_order_id': fields.many2one('res.partner.address', 'Ordering Contact', readonly=True, required=True, states={'draft': [('readonly', False)]}, help="The name and address of the contact who requested the order or quotation."),
- 'partner_shipping_id': fields.many2one('res.partner.address', 'Shipping Address', readonly=True, required=True, states={'draft': [('readonly', False)]}),
+ 'partner_shipping_id': fields.many2one('res.partner.address', 'Shipping Address', readonly=True, required=True, states={'draft': [('readonly', False)]}, help="Shipping address for current sale order"),
'incoterm': fields.selection(_incoterm_get, 'Incoterm', size=3),
'picking_policy': fields.selection([('direct', 'Partial Delivery'), ('one', 'Complete Delivery')],
- The 'Shipping & Manual Invoice' will create the picking order directly and wait for the user to manually click on the 'Invoice' button to generate the draft invoice.
- The 'Invoice on Order After Delivery' choice will generate the draft invoice based on sale order after all picking lists have been finished.
- The 'Invoice from the picking' choice is used to create an invoice during the picking process."""),
- 'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', required=True, readonly=True, states={'draft': [('readonly', False)]}),
+ 'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Pricelist version for current sale order"),
'project_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True, states={'draft': [('readonly', False)]}),
'order_line': fields.one2many('sale.order.line', 'order_id', 'Order Lines', readonly=True, states={'draft': [('readonly', False)]}),
'partner_invoice_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').address_get(cr, uid, [context['partner_id']], ['invoice'])['invoice'],
'partner_order_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').address_get(cr, uid, [context['partner_id']], ['contact'])['contact'],
'partner_shipping_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').address_get(cr, uid, [context['partner_id']], ['delivery'])['delivery'],
- '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.id,
+# '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.id,
}
_order = 'name desc'
# Form filling
def unlink(self, cr, uid, ids, context=None):
- sale_orders = self.read(cr, uid, ids, ['state'])
+ if context is None:
+ context = {}
+ sale_orders = self.read(cr, uid, ids, ['state'], context=context)
unlink_ids = []
for s in sale_orders:
if s['state'] in ['draft', 'cancel']:
return {'value': val}
- def shipping_policy_change(self, cr, uid, ids, policy, context={}):
+ def shipping_policy_change(self, cr, uid, ids, policy, context=None):
+ if context is None:
+ context = {}
if not policy:
return {}
inv_qty = 'order'
return {'value': {'invoice_quantity': inv_qty}}
def write(self, cr, uid, ids, vals, context=None):
+ if context is None:
+ context = {}
if 'order_policy' in vals:
if vals['order_policy'] == 'prepaid':
vals.update({'invoice_quantity': 'order'})
vals.update({'invoice_quantity': 'procurement'})
return super(sale_order, self).write(cr, uid, ids, vals, context=context)
- def create(self, cr, uid, vals, context={}):
+ def create(self, cr, uid, vals, context=None):
+ if context is None:
+ context = {}
if 'order_policy' in vals:
if vals['order_policy'] == 'prepaid':
vals.update({'invoice_quantity': 'order'})
vals.update({'invoice_quantity': 'procurement'})
return super(sale_order, self).create(cr, uid, vals, context=context)
- def button_dummy(self, cr, uid, ids, context={}):
+ def button_dummy(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
return True
#FIXME: the method should return the list of invoices created (invoice_ids)
# and not the id of the last invoice created (res). The problem is that we
# cannot change it directly since the method is called by the sale order
# workflow and I suppose it expects a single id...
- def _inv_get(self, cr, uid, order, context={}):
+ def _inv_get(self, cr, uid, order, context=None):
+ if context is None:
+ context = {}
return {}
- def _make_invoice(self, cr, uid, order, lines, context={}):
+ def _make_invoice(self, cr, uid, order, lines, context=None):
+ if context is None:
+ context = {}
a = order.partner_id.property_account_receivable.id
if order.payment_term:
pay_term = order.payment_term.id
'currency_id': order.pricelist_id.currency_id.id,
'comment': order.note,
'payment_term': pay_term,
- 'fiscal_position': order.partner_id.property_account_position.id,
+ 'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id,
'date_invoice' : context.get('date_invoice',False),
'company_id' : order.company_id.id,
}
inv_obj = self.pool.get('account.invoice')
inv.update(self._inv_get(cr, uid, order))
- inv_id = inv_obj.create(cr, uid, inv, context)
+ inv_id = inv_obj.create(cr, uid, inv, context=context)
data = inv_obj.onchange_payment_term_date_invoice(cr, uid, [inv_id], pay_term, time.strftime('%Y-%m-%d'))
if data.get('value', False):
inv_obj.write(cr, uid, [inv_id], data['value'], context=context)
cr.execute('insert into sale_order_invoice_rel (order_id,invoice_id) values (%s,%s)', (order.id, res))
return res
- def action_invoice_cancel(self, cr, uid, ids, context={}):
- for sale in self.browse(cr, uid, ids):
+ def action_invoice_cancel(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
+ for sale in self.browse(cr, uid, ids, context=context):
for line in sale.order_line:
invoiced = False
for iline in line.invoice_lines:
self.write(cr, uid, ids, {'state': 'invoice_except', 'invoice_ids': False})
return True
- def action_invoice_end(self, cr, uid, ids, context={}):
- for order in self.browse(cr, uid, ids):
- val = {'invoiced': True}
- if order.state == 'invoice_except':
- val['state'] = 'progress'
+ def action_invoice_end(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
+ for order in self.browse(cr, uid, ids, context=context):
for line in order.order_line:
- towrite = []
if line.state == 'exception':
- towrite.append(line.id)
- if towrite:
- self.pool.get('sale.order.line').write(cr, uid, towrite, {'state': 'confirmed'}, context=context)
- self.write(cr, uid, [order.id], val)
+ self.pool.get('sale.order.line').write(cr, uid, [line.id], {'state': 'confirmed'}, context=context)
+
+ if order.state == 'invoice_except':
+ self.write(cr, uid, [order.id], {'state' : 'progress'}, context=context)
return True
- def action_cancel(self, cr, uid, ids, context={}):
+ def action_cancel(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
ok = True
sale_order_line_obj = self.pool.get('sale.order.line')
- for sale in self.browse(cr, uid, ids):
+ for sale in self.browse(cr, uid, ids, context=context):
for pick in sale.picking_ids:
if pick.state not in ('draft', 'cancel'):
raise osv.except_osv(
return True
def action_wait(self, cr, uid, ids, *args):
- event_p = self.pool.get('res.partner.event.type').check(cr, uid, 'sale_open')
- event_obj = self.pool.get('res.partner.event')
+ for (id,name) in self.name_get(cr, uid, ids):
+ message = _('Quotation ') + " '" + name + "' "+ _("converted to sale order.")
+ self.log(cr, uid, id, message)
for o in self.browse(cr, uid, ids):
- if event_p:
- event_obj.create(cr, uid, {'name': 'Sale Order: '+ o.name,\
- 'partner_id': o.partner_id.id,\
- 'date': time.strftime('%Y-%m-%d %H:%M:%S'),\
- 'user_id': (o.user_id and o.user_id.id) or uid,\
- 'partner_type': 'customer', 'probability': 1.0,\
- 'planned_revenue': o.amount_untaxed})
if (o.order_policy == 'manual'):
self.write(cr, uid, [o.id], {'state': 'manual', 'date_confirm': time.strftime('%Y-%m-%d')})
else:
return True
- def action_ship_end(self, cr, uid, ids, context={}):
- for order in self.browse(cr, uid, ids):
+ def action_ship_end(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
+ for order in self.browse(cr, uid, ids, context=context):
val = {'shipped': True}
if order.state == 'shipping_except':
val['state'] = 'progress'
# - update it on change product and unit price
# - use it in report if there is a uos
class sale_order_line(osv.osv):
- def _amount_line_net(self, cr, uid, ids, field_name, arg, context):
+ def _amount_line_net(self, cr, uid, ids, field_name, arg, context=None):
+ if context is None:
+ context = {}
res = {}
- for line in self.browse(cr, uid, ids):
+ for line in self.browse(cr, uid, ids, context=context):
res[line.id] = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
return res
- def _amount_line(self, cr, uid, ids, field_name, arg, context):
+ def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
+ if context is None:
+ context = {}
res = {}
cur_obj = self.pool.get('res.currency')
- for line in self.browse(cr, uid, ids):
+ for line in self.browse(cr, uid, ids, context=context):
res[line.id] = line.price_unit * line.product_uom_qty * (1 - (line.discount or 0.0) / 100.0)
cur = line.order_id.pricelist_id.currency_id
res[line.id] = cur_obj.round(cr, uid, cur, res[line.id])
return res
- def _number_packages(self, cr, uid, ids, field_name, arg, context):
+ def _number_packages(self, cr, uid, ids, field_name, arg, context=None):
+ if context is None:
+ context = {}
res = {}
- for line in self.browse(cr, uid, ids):
+ for line in self.browse(cr, uid, ids, context=context):
try:
res[line.id] = int(line.product_uom_qty / line.product_packaging.qty)
except:
return res
_name = 'sale.order.line'
- _description = 'Sale Order line'
+ _description = 'Sale Order Line'
_columns = {
'order_id': fields.many2one('sale.order', 'Order Reference', required=True, ondelete='cascade', select=True, readonly=True, states={'draft':[('readonly',False)]}),
'name': fields.char('Description', size=256, required=True, select=True, readonly=True, states={'draft':[('readonly',False)]}),
'property_ids': fields.many2many('mrp.property', 'sale_order_line_property_rel', 'order_id', 'property_id', 'Properties', readonly=True, states={'draft':[('readonly',False)]}),
'address_allotment_id': fields.many2one('res.partner.address', 'Allotment Partner'),
'product_uom_qty': fields.float('Quantity (UoM)', digits=(16, 2), required=True, readonly=True, states={'draft':[('readonly',False)]}),
- 'product_uom': fields.many2one('product.uom', 'Product UoM', required=True, readonly=True, states={'draft':[('readonly',False)]}),
+ 'product_uom': fields.many2one('product.uom', 'Unit of Measure ', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'product_uos_qty': fields.float('Quantity (UoS)', readonly=True, states={'draft':[('readonly',False)]}),
'product_uos': fields.many2one('product.uom', 'Product UoS'),
'product_packaging': fields.many2one('product.packaging', 'Packaging'),
'product_packaging': lambda *a: False
}
- def invoice_line_create(self, cr, uid, ids, context={}):
+ def invoice_line_create(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
def _get_line_qty(line):
if (line.order_id.invoice_quantity=='order') or not line.procurement_id:
if line.product_uos:
return line.product_uom_qty
else:
return self.pool.get('mrp.procurement').quantity_get(cr, uid,
- line.procurement_id.id, context)
+ line.procurement_id.id, context=context)
def _get_line_uom(line):
if (line.order_id.invoice_quantity=='order') or not line.procurement_id:
return line.product_uom.id
else:
return self.pool.get('mrp.procurement').uom_get(cr, uid,
- line.procurement_id.id, context)
+ line.procurement_id.id, context=context)
create_ids = []
sales = {}
- for line in self.browse(cr, uid, ids, context):
+ for line in self.browse(cr, uid, ids, context=context):
if not line.invoiced:
if line.product_id:
a = line.product_id.product_tmpl_id.property_account_income.id
wf_service.trg_write(uid, 'sale.order', sid, cr)
return create_ids
- def button_cancel(self, cr, uid, ids, context={}):
+ def button_cancel(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
for line in self.browse(cr, uid, ids, context=context):
if line.invoiced:
raise osv.except_osv(_('Invalid action !'), _('You cannot cancel a sale order line that has already been invoiced !'))
return self.write(cr, uid, ids, {'state': 'cancel'})
- def button_confirm(self, cr, uid, ids, context={}):
+ def button_confirm(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
return self.write(cr, uid, ids, {'state': 'confirmed'})
- def button_done(self, cr, uid, ids, context={}):
+ def button_done(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
wf_service = netsvc.LocalService("workflow")
res = self.write(cr, uid, ids, {'state': 'done'})
- for line in self.browse(cr, uid, ids, context):
+ for line in self.browse(cr, uid, ids, context=context):
wf_service.trg_write(uid, 'sale.order', line.order_id.id, cr)
return res
pass
return {'value': value}
- def copy_data(self, cr, uid, id, default=None, context={}):
+ def copy_data(self, cr, uid, id, default=None, context=None):
+ if context is None:
+ context = {}
if not default:
default = {}
default.update({'state': 'draft', 'move_ids': [], 'invoiced': False, 'invoice_lines': []})
- return super(sale_order_line, self).copy_data(cr, uid, id, default, context)
+ return super(sale_order_line, self).copy_data(cr, uid, id, default, context=context)
def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
if packaging:
default_uom = product_obj.uom_id and product_obj.uom_id.id
- pack = self.pool.get('product.packaging').browse(cr, uid, packaging, context)
+ pack = self.pool.get('product.packaging').browse(cr, uid, packaging, context=context)
q = product_uom_obj._compute_qty(cr, uid, uom, pack.qty, default_uom)
# qty = qty - qty % q + q
if qty and (q and not (qty % q) == 0):
if product_obj.uos_id.category_id.id != uos2.category_id.id:
uos = False
else:
- uos = False
+ uos = False
if product_obj.description_sale:
result['notes'] = product_obj.description_sale
fpos = fiscal_position and self.pool.get('account.fiscal.position').browse(cr, uid, fiscal_position) or False
'product_uos':
[('category_id', '=', uos_category_id)]}
- elif uos: # only happens if uom is False
+ elif uos and not uom: # only happens if uom is False
result['product_uom'] = product_obj.uom_id and product_obj.uom_id.id
result['product_uom_qty'] = qty_uos / product_obj.uos_coeff
result['th_weight'] = result['product_uom_qty'] * product_obj.weight
warning = {
'title': 'No Pricelist !',
'message':
- 'You have to select a pricelist in the sale form !\n'
+ 'You have to select a pricelist or a customer in the sale form !\n'
'Please set one before choosing a product.'
}
else:
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
lang=False, update_tax=True, date_order=False):
res = self.product_id_change(cursor, user, ids, pricelist, product,
- qty=0, uom=uom, qty_uos=qty_uos, uos=uos, name=name,
+ qty=qty, uom=uom, qty_uos=qty_uos, uos=uos, name=name,
partner_id=partner_id, lang=lang, update_tax=update_tax,
date_order=date_order)
if 'product_uom' in res['value']:
res['value']['price_unit'] = 0.0
return res
- def unlink(self, cr, uid, ids, context={}):
+ def unlink(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
"""Allows to delete sale order lines in draft,cancel states"""
for rec in self.browse(cr, uid, ids, context=context):
if rec.state not in ['draft', 'cancel']:
'order_policy': fields.selection([
('manual', 'Invoice Based on Sales Orders'),
('picking', 'Invoice Based on Deliveries'),
- ], 'Shipping Default Policy', required=True),
+ ], 'Shipping Default Policy', required=True,
+ help="You can generate invoices based on sales orders or based on shippings."),
'step': fields.selection([
('one', 'Delivery Order Only'),
('two', 'Picking List & Delivery Order')
}
_defaults = {
'picking_policy': lambda *a: 'direct',
- 'order_policy': lambda *a: 'picking',
+ 'order_policy': lambda *a: 'manual',
'step': lambda *a: 'one'
}
def execute(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
for o in self.browse(cr, uid, ids, context=context):
ir_values_obj = self.pool.get('ir.values')
ir_values_obj.set(cr, uid, 'default', False, 'picking_policy', ['sale.order'], o.picking_policy)
if o.step == 'one':
md = self.pool.get('ir.model.data')
group_id = md._get_id(cr, uid, 'base', 'group_no_one')
- group_id = md.browse(cr, uid, group_id, context).res_id
+ group_id = md.browse(cr, uid, group_id, context=context).res_id
menu_id = md._get_id(cr, uid, 'stock', 'menu_action_picking_tree_delivery')
- menu_id = md.browse(cr, uid, menu_id, context).res_id
+ menu_id = md.browse(cr, uid, menu_id, context=context).res_id
self.pool.get('ir.ui.menu').write(cr, uid, [menu_id], {'groups_id': [(6, 0, [group_id])]})
location_id = md._get_id(cr, uid, 'stock', 'stock_location_output')
- location_id = md.browse(cr, uid, location_id, context).res_id
+ location_id = md.browse(cr, uid, location_id, context=context).res_id
self.pool.get('stock.location').write(cr, uid, [location_id], {'chained_auto_packing': 'transparent'})
sale_config_picking_policy()