from osv import fields, osv
from tools.translate import _
from mx.DateTime import now
+import time
+import decimal_precision as dp
class crm_make_sale(osv.osv_memory):
""" Make sale order for crm """
vals = {
'origin': 'Opportunity:%s' % str(case.id),
'section_id': case.section_id and case.section_id.id or False,
- 'picking_policy': make.picking_policy,
'shop_id': make.shop_id.id,
'partner_id': partner_id,
'pricelist_id': pricelist,
if make.analytic_account.id:
vals['project_id'] = make.analytic_account.id
new_id = sale_obj.create(cr, uid, vals)
- for product_id in make.product_ids:
+ for line in make.sale_order_line:
value = sale_line_obj.product_id_change(cr, uid, [], pricelist,
- product_id.id, qty=1, partner_id=partner_id, fiscal_position=fpos)['value']
- value['product_id'] = product_id.id
+ line.product_id.id, qty=1, partner_id=partner_id, fiscal_position=fpos)['value']
+ value['product_id'] =line.product_id.id
value['order_id'] = new_id
- value['tax_id'] = [(6,0,value['tax_id'])]
+ value['tax_id'] = [(6,0,line['tax_id'])]
+ value['product_uom_qty']=line.product_uom_qty
+ value['discount']=line.discount
+ value['product_uom']=line.product_uom.id
sale_line_obj.create(cr, uid, value)
-
case_obj.write(cr, uid, [case.id], {'ref': 'sale.order,%s' % new_id})
new_ids.append(new_id)
message = _('Opportunity ') + " '" + case.name + "' "+ _("is converted to Sales Quotation.")
_columns = {
'shop_id': fields.many2one('sale.shop', 'Shop', required=True),
'partner_id': fields.many2one('res.partner', 'Customer', required=True, help='Use this partner if there is no partner on the Opportunity'),
- 'picking_policy': fields.selection([('direct','Partial Delivery'),
- ('one','Complete Delivery')], 'Picking Policy', required=True),
- 'product_ids': fields.many2many('product.product', 'product_sale_rel',\
- 'sale_id', 'product_id', 'Products'),
+ 'sale_order_line': fields.one2many('sale.order.make.line', 'order_line', 'Product Line', readonly=True, states={'draft': [('readonly', False)]}),
'analytic_account': fields.many2one('account.analytic.account', 'Analytic Account'),
'close': fields.boolean('Close Case', help='Check this to close the case after having created the sale order.'),
}
'partner_id': _selectPartner,
'close': 1
}
+
crm_make_sale()
+
+class sale_order_make_line(osv.osv_memory):
+
+
+ def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
+ uom=False, qty_uos=0, uos=False, name='', partner_id=False,
+ lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False):
+ if not partner_id:
+ raise osv.except_osv(_('No Customer Defined !'), _('You have to select a customer in the sale form !\nPlease set one customer before choosing a product.'))
+ warning = {}
+ product_uom_obj = self.pool.get('product.uom')
+ partner_obj = self.pool.get('res.partner')
+ product_obj = self.pool.get('product.product')
+ if partner_id:
+ lang = partner_obj.browse(cr, uid, partner_id).lang
+ context = {'lang': lang, 'partner_id': partner_id}
+
+ if not product:
+ return {'value': {'th_weight': 0, 'product_packaging': False,
+ 'product_uos_qty': qty}, 'domain': {'product_uom': [],
+ 'product_uos': []}}
+
+ if not date_order:
+ date_order = time.strftime('%Y-%m-%d')
+
+ result = {}
+ product_obj = product_obj.browse(cr, uid, product, context=context)
+ if not packaging and product_obj.packaging:
+ packaging = product_obj.packaging[0].id
+ result['product_packaging'] = packaging
+
+ 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=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):
+ ean = pack.ean
+ qty_pack = pack.qty
+ type_ul = pack.ul
+ warn_msg = _("You selected a quantity of %d Units.\nBut it's not compatible with the selected packaging.\nHere is a proposition of quantities according to the packaging: ") % (qty)
+ warn_msg = warn_msg + "\n\n" + _("EAN: ") + str(ean) + _(" Quantity: ") + str(qty_pack) + _(" Type of ul: ") + str(type_ul.name)
+ warning = {
+ 'title': _('Picking Information !'),
+ 'message': warn_msg
+ }
+ result['product_uom_qty'] = qty
+
+ uom2 = False
+ if uom:
+ uom2 = product_uom_obj.browse(cr, uid, uom)
+ if product_obj.uom_id.category_id.id != uom2.category_id.id:
+ uom = False
+
+ if uos:
+ if product_obj.uos_id:
+ uos2 = product_uom_obj.browse(cr, uid, uos)
+ if product_obj.uos_id.category_id.id != uos2.category_id.id:
+ uos = False
+ else:
+ 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
+ if update_tax: #The quantity only have changed
+ result['delay'] = (product_obj.sale_delay or 0.0)
+ partner = partner_obj.browse(cr, uid, partner_id)
+ result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, product_obj.taxes_id)
+ result.update({'type': product_obj.procure_method})
+
+ if not flag:
+ result['name'] = self.pool.get('product.product').name_get(cr, uid, [product_obj.id], context=context)[0][1]
+ domain = {}
+ if (not uom) and (not uos):
+ result['product_uom'] = product_obj.uom_id.id
+ if product_obj.uos_id:
+ result['product_uos'] = product_obj.uos_id.id
+ result['product_uos_qty'] = qty * product_obj.uos_coeff
+ uos_category_id = product_obj.uos_id.category_id.id
+ else:
+ result['product_uos'] = False
+ result['product_uos_qty'] = qty
+ uos_category_id = False
+ domain = {'product_uom':
+ [('category_id', '=', product_obj.uom_id.category_id.id)],
+ 'product_uos':
+ [('category_id', '=', uos_category_id)]}
+
+ 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
+ elif uom: # whether uos is set or not
+ default_uom = product_obj.uom_id and product_obj.uom_id.id
+ q = product_uom_obj._compute_qty(cr, uid, uom, qty, default_uom)
+ if product_obj.uos_id:
+ result['product_uos'] = product_obj.uos_id.id
+ result['product_uos_qty'] = qty * product_obj.uos_coeff
+ else:
+ result['product_uos'] = False
+ result['product_uos_qty'] = qty
+
+ if not uom2:
+ uom2 = product_obj.uom_id
+ return {'value': result, 'domain': domain, 'warning': warning}
+
+ def product_uom_change(self, cursor, user, ids, pricelist, product, qty=0,
+ 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=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']:
+ del res['value']['product_uom']
+ if not uom:
+ res['value']['price_unit'] = 0.0
+ return res
+
+ _name = 'sale.order.make.line'
+ _description = 'Sale Order Line'
+ _columns = {
+ 'order_line': fields.many2one('crm.make.sale', 'Order Reference', required=True, ondelete='cascade', select=True, readonly=True, ),
+ 'order_id': fields.many2one('sale.order', 'Order Reference', required=True, ondelete='cascade', select=True, readonly=True, ),
+ 'name': fields.char('Description', size=256, required=True, select=True, readonly=True, ),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of sale order lines."),
+ 'delay': fields.float('Delivery Lead Time', required=True, help="Number of days between the order confirmation the the shipping of the products to the customer", readonly=True, ),
+ 'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], change_default=True),
+ 'procurement_id': fields.many2one('procurement.order', 'Procurement'),
+ 'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Sale Price'), readonly=True, ),
+ 'tax_id': fields.many2many('account.tax', 'sale_order_tax', 'order_line_id', 'tax_id', 'Taxes', readonly=True, states={'draft':[('readonly',False)]}),
+ 'type': fields.selection([('make_to_stock', 'from stock'), ('make_to_order', 'on order')], 'Procurement Method', required=True, readonly=True, states={'draft':[('readonly',False)]}),
+ 'product_uom_qty': fields.float('Quantity (UoM)', digits=(16, 2), 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'),
+ 'discount': fields.float('Discount (%)', digits=(16, 2), readonly=True, states={'draft':[('readonly',False)]}),
+ 'notes': fields.text('Notes'),
+ }
+ _order = 'sequence, id'
+ _defaults = {
+ 'discount': 0.0,
+ 'delay': 0.0,
+ 'product_uom_qty': 1,
+ 'product_uos_qty': 1,
+ 'type': 'make_to_stock',
+ 'product_packaging': False
+ }
+
+sale_order_make_line()
+
+
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Create a Sale Order" >
+ <group width="660" height="300">
<group colspan="4">
<field name="partner_id" required="1"/>
<field name="shop_id" required="1" widget="selection"/>
<field name="analytic_account"/>
- <field name="picking_policy"/>
<field name="close" required="1"/>
- </group>
- <separator string="Products" colspan="4"/>
- <field name="product_ids" colspan="4" nolabel="1"/>
+ </group>
+ <field colspan="4" mode="tree,form,graph" name="sale_order_line" nolabel="1" widget="one2many_list">
+ <form string="Sale Order Lines">
+ <notebook>
+ <page string="Order Line">
+ <field colspan="4"
+ context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom"
+ name="product_id"
+ on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], True, parent.date_order, product_packaging, parent.fiscal_position, False)"
+ />
+ <field
+ context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom"
+ name="product_uom_qty"
+ on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], False, parent.date_order, product_packaging, parent.fiscal_position, True)"
+ />
+ <field groups="product.group_uos" name="product_uos_qty"/>
+ <field name="product_uom"
+ on_change="product_uom_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], False, parent.date_order)"/>
+ <field
+ name="product_packaging"
+ context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom"
+ on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], False, parent.date_order, product_packaging, parent.fiscal_position, False)"
+ domain="[('product_id','=',product_id)]"
+ groups="base.group_extended"/>
+
+ <field colspan="4" name="name"/>
+ <field name="price_unit"/>
+ <field name="discount"/>
+ <field name="type" groups="base.group_extended"/>
+ <field name="delay" groups="base.group_extended"/>
+ <newline/>
+ <separator colspan="5" string="Taxes"/>
+ <field colspan="4" name="tax_id" nolabel="1" domain="[('parent_id','=',False),('type_tax_use','<>','purchase')]"/>
+ </page>
+ </notebook>
+ </form>
+ <tree string="Sales order lines">
+ <field colspan="4" name="name"/>
+ <field name="product_uom_qty" string="Qty"/>
+ <field name="product_uom" string="UoM"/>
+ <field name="discount"/>
+ <field name="price_unit"/>
+ </tree>
+ </field>
+ <newline/>
+
+
<separator colspan="4"/>
<group col="4" colspan="4">
<label string="" colspan="2"/>
<button special="cancel" string="_Close" icon="gtk-cancel"/>
<button name="makeOrder" string="_Ok" type="object" icon='gtk-ok'/>
</group>
+ </group>
</form>
</field>
</record>