[MERGE] merge from trunk addons

bzr revid: mra@mra-laptop-20101029044405-mjh05se7006rk7sy
This commit is contained in:
Mustufa Rangwala 2010-10-29 10:14:05 +05:30
commit d32f945515
14 changed files with 261 additions and 199 deletions

View File

@ -916,7 +916,7 @@ class calendar_event(osv.osv):
return [(x.lower(), x) for x in pytz.all_timezones]
def onchange_allday(self, cr, uid, ids, allday, context=None):
"""Sets duration as 24 Hours if event is selcted for all day
"""Sets duration as 24 Hours if event is selected for all day
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@ -1630,6 +1630,14 @@ true, it will allow you to hide the event alarm information without removing it.
if vals.get('vtimezone', '') and vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'):
vals['vtimezone'] = vals['vtimezone'][40:]
updated_vals = self.onchange_dates(cr, uid, [],
vals.get('date', False),
vals.get('duration', False),
vals.get('date_deadline', False),
vals.get('allday', False),
context=context)
vals.update(updated_vals.get('value', {}))
res = super(calendar_event, self).create(cr, uid, vals, context)
alarm_obj = self.pool.get('res.alarm')
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)

View File

@ -229,7 +229,7 @@
<group col="6" colspan="4">
<field name="name" select="1" string="Summary"
colspan="4" required="1" />
<field name="allday" colspan="2" on_change="onchange_allday(allday)" />
<field name="allday" colspan="2" on_change="onchange_dates(date,False,False,allday)" />
<newline/>
<field name="date" string="Start Date" required="1" select="1"
on_change="onchange_dates(date,duration,False,allday)" />

View File

@ -32,7 +32,7 @@
<field name="categ_id" widget="selection"
string="Meeting Type" groups="base.group_extended"
domain="[('object_id.model', '=', 'crm.meeting')]" />
<field name="allday" on_change="onchange_allday(allday)" />
<field name="allday" on_change="onchange_dates(date,False,False,allday)" />
<newline/>
<field name="date" string="Start Date" required="1"
on_change="onchange_dates(date,duration,False,allday)" />

View File

@ -64,7 +64,7 @@ class crm_helpdesk(crm.crm_case, osv.osv):
'categ_id': fields.many2one('crm.case.categ', 'Category', \
domain="[('section_id','=',section_id),\
('object_id.model', '=', 'crm.helpdesk')]"),
'duration': fields.float('Duration'),
'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
help='The state is set to \'Draft\', when a case is created.\
\nIf the case is in progress the state is set to \'Open\'.\

View File

@ -183,7 +183,7 @@ class hr_employee(osv.osv):
return {'value': {'work_email' : work_email}}
def _get_photo(self, cr, uid, context=None):
photo_path = addons.get_module_resource('hr','image','photo.png')
photo_path = addons.get_module_resource('hr','image','photo.png')
return open(photo_path, 'rb').read().encode('base64')
_defaults = {

View File

@ -35,7 +35,7 @@
<field name="password">jth</field>
</record>
<record id="res_users_tester" model="res.users">
<field name="name">Alien</field>
<field name="name">Aline</field>
<field eval="[(6, 0, [ref('base.group_user'), ref('project.group_project_user')])]" name="groups_id"/>
<field name="login">apr</field>
<field name="password">apr</field>

View File

@ -187,7 +187,7 @@ class purchase_order(osv.osv):
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-generated based on validated receptions.\n" \
"Manual: no invoice will be pre-generated. The accountant will have to encode manually."
"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."),
'amount_untaxed': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Purchase Price'), string='Untaxed Amount',
@ -597,7 +597,7 @@ class purchase_order_line(osv.osv):
_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),
'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),
@ -616,7 +616,7 @@ class purchase_order_line(osv.osv):
\n* The \'Cancelled\' state is set automatically when user cancel purchase order.'),
'invoice_lines': fields.many2many('account.invoice.line', 'purchase_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True),
'invoiced': fields.boolean('Invoiced', readonly=True),
'partner_id': fields.related('order_id','partner_id',string='Partner',readonly=True,type="many2one", relation="res.partner"),
'partner_id': fields.related('order_id','partner_id',string='Partner',readonly=True,type="many2one", relation="res.partner", store=True),
'date_order': fields.related('order_id','date_order',string='Order Date',readonly=True,type="date")
}

View File

@ -144,10 +144,10 @@
<button name="action_cancel" states="approved,except_picking,except_invoice" string="Cancel Purchase Order" type="object" icon="gtk-cancel"/>
<button name="picking_ok" states="except_picking" string="Manually Corrected" icon="gtk-convert"/>
<button name="invoice_ok" states="except_invoice" string="Manually Corrected" icon="gtk-convert"/>
<button name="purchase_confirm" states="draft" string="Confirm Purchase Order" icon="gtk-go-forward"/>
<button name="purchase_confirm" states="draft" string="Convert to Purchase Order" icon="gtk-go-forward"/>
<button name="purchase_appbuyer" states="wait_auth" string="Approve Purchase" icon="gtk-ok"/>
<button name="purchase_approve" states="confirmed" string="Approved by Supplier" icon="gtk-go-forward"/>
<button name="%(report_purchase_order)d" string="Print" states="approved" type="action" icon="gtk-print"/>
<button name="%(report_purchase_order)d" string="Print" states="approved" type="action" icon="gtk-print"/>
</group>
</page>
@ -307,12 +307,16 @@
<tree string="Purchase Order Lines">
<field name="order_id"/>
<field name="name"/>
<field name="date_planned" widget="date" width="135"/>
<field name="partner_id" string="Supplier" />
<field name="product_id"/>
<field name="product_qty"/>
<field name="product_uom"/>
<field name="price_unit"/>
<field name="product_qty"/>
<field name="product_uom"/>
<field name="price_subtotal"/>
<field name="date_planned" widget="date" width="135"/>
<field name="state" invisible="1"/>
<field name="invoiced" invisible="1"/>
</tree>
@ -369,10 +373,12 @@
<group>
<field name="order_id"/>
<field name="product_id"/>
</group>
<field name="partner_id" string="Supplier"/>
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="Product" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by' : 'product_id'}" />
<filter string="Supplier" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by' : 'partner_id'}" />
<filter icon="terp-gtk-jump-to-rtl" string="Order Reference" domain="[]" context="{'group_by' :'order_id'}"/>
<separator orientation="vertical"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by' : 'state'}" />
@ -401,7 +407,7 @@
<field name="name">Purchase Lines Not Invoiced</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.order.line</field>
<field name="domain">[('state','in',('confirmed','done')), ('invoiced','=',False)]</field>
<field name="domain">[('state','in',('confirmed','done')), ('invoiced', '=', False)]</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="purchase_order_line_search"/>

View File

@ -24,6 +24,7 @@ import ir
from osv import osv
from tools.translate import _
class purchase_line_invoice(osv.osv_memory):
""" To create invoice for purchase order line"""
@ -31,7 +32,8 @@ class purchase_line_invoice(osv.osv_memory):
_name = 'purchase.order.line_invoice'
_description = 'Purchase Order Line Make Invoice'
def makeInvoices(self, cr, uid, ids, context):
def makeInvoices(self, cr, uid, ids, context=None):
"""
To get Purchase Order line and create Invoice
@param self: The object pointer.
@ -39,7 +41,11 @@ class purchase_line_invoice(osv.osv_memory):
@param uid: ID of the user currently logged in
@param context: A standard dictionary
@return : retrun view of Invoice
"""
"""
if context is None:
context={}
record_ids = context.get('active_ids',[])
if record_ids:
res = False
@ -49,35 +55,63 @@ class purchase_line_invoice(osv.osv_memory):
property_obj=self.pool.get('ir.property')
account_fiscal_obj=self.pool.get('account.fiscal.position')
invoice_line_obj=self.pool.get('account.invoice.line')
def make_invoice(order, lines):
a = order.partner_id.property_account_payable.id
if order.partner_id and order.partner_id.property_payment_term.id:
pay_term = order.partner_id.property_payment_term.id
def multiple_order_invoice_name(orders):
name = "PO";
for order in orders:
name += "-%d" % order.id
return name
def multiple_order_invoice_reference(partner, orders):
reference = "P%dPO" % partner.id
for order in orders:
reference += "-%d" % order.id
return reference
def multiple_order_invoice_notes(orders):
notes = ""
for order in orders:
notes += "%s \n" % order.notes
return notes
def make_invoice_by_partner(partner, orders, lines_ids):
"""
create a new invoice for one supplier
@param partner : The object partner
@param orders : The set of orders to add in the invoice
@param lines : The list of line's id
"""
a = partner.property_account_payable.id
if partner and partner.property_payment_term.id:
pay_term = partner.property_payment_term.id
else:
pay_term = False
inv = {
'name': order.name,
'origin': order.name,
'name': multiple_order_invoice_name(orders),
'origin': multiple_order_invoice_name(orders),
'type': 'in_invoice',
'reference': "P%dPO%d" % (order.partner_id.id, order.id),
'reference': multiple_order_invoice_reference(partner, orders),
'account_id': a,
'partner_id': order.partner_id.id,
'address_invoice_id': order.partner_address_id.id,
'address_contact_id': order.partner_address_id.id,
'invoice_line': [(6,0,lines)],
'currency_id' : order.pricelist_id.currency_id.id,
'comment': order.notes,
'partner_id': partner.id,
'address_invoice_id': orders[0].partner_address_id.id,
'address_contact_id': orders[0].partner_address_id.id,
'invoice_line': [(6,0,lines_ids)],
'currency_id' : orders[0].pricelist_id.currency_id.id,
'comment': multiple_order_invoice_notes(orders),
'payment_term': pay_term,
'fiscal_position': order.partner_id.property_account_position.id
'fiscal_position': partner.property_account_position.id
}
inv_id = invoice_obj.create(cr, uid, inv)
return inv_id
for line in purchase_line_obj.browse(cr,uid,record_ids):
if (not line.invoiced) and (line.state not in ('draft','cancel')):
if not line.order_id.id in invoices:
invoices[line.order_id.id] = []
if not line.partner_id.id in invoices:
invoices[line.partner_id.id] = []
if line.product_id:
a = line.product_id.product_tmpl_id.property_account_expense.id
if not a:
@ -102,18 +136,19 @@ class purchase_line_invoice(osv.osv_memory):
'uos_id': line.product_uom.id,
'product_id': line.product_id.id or False,
'invoice_line_tax_id': [(6, 0, [x.id for x in line.taxes_id])],
'note': line.notes,
'note': line.notes,
'account_analytic_id': line.account_analytic_id and line.account_analytic_id.id or False,
})
cr.execute('insert into purchase_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id))
purchase_line_obj.write(cr, uid, [line.id], {'invoiced': True})
invoices[line.order_id.id].append((line,inv_id))
invoices[line.partner_id.id].append((line,inv_id))
res = []
for result in invoices.values():
order = result[0][0].order_id
il = map(lambda x: x[1], result)
res.append(make_invoice(order, il))
orders = list(set(map(lambda x : x[0].order_id, result)))
res.append(make_invoice_by_partner(orders[0].partner_id, orders, il))
return {
'domain': "[('id','in', ["+','.join(map(str,res))+"])]",

View File

@ -210,7 +210,7 @@
<button name="ship_recreate" states="shipping_except" string="Recreate Procurement" icon="gtk-ok"/>
<button name="ship_corrected" states="shipping_except" string="Procurement Corrected" icon="gtk-apply"/>
<button name="action_cancel" states="manual,progress" string="Cancel Order" type="object" icon="gtk-cancel"/>
<button name="manual_invoice" states="manual" string="Create Invoice" icon="gtk-go-forward" type="object"/>
<button name="manual_invoice" states="manual" string="Create Final Invoice" icon="gtk-go-forward" type="object"/>
<button name="ship_cancel" states="shipping_except" string="Cancel Order" icon="gtk-cancel"/>
<button name="action_cancel_draft" states="cancel" string="Set to Draft" type="object" icon="gtk-convert"/>
<button name="cancel" states="draft" string="Cancel Order" icon="gtk-cancel"/>

View File

@ -1461,12 +1461,15 @@
====================================
Reception Picking (By Stock Move)
====================================
<!-- from stock_partial_move_view -->
<record id="view_move_tree_reception_picking" model="ir.ui.view">
<field name="name">stock.move.tree2</field>
<field name="model">stock.move</field>
<field name="type">tree</field>
<field eval="6" name="priority"/>
<field name="priority" eval="6" />
<field name="arch" type="xml">
<tree colors="grey:state in ('cancel')" string="Moves">
<field name="picking_id" string="Reference"/>
@ -1521,6 +1524,7 @@
</tree>
</field>
</record>
<record id="view_move_form_reception_picking" model="ir.ui.view">
<field name="name">stock.move.form2</field>
@ -1672,7 +1676,7 @@
<field name="view_mode">tree,form</field>
<field name="domain">['|','&amp;',('picking_id','=',False),('location_id.usage', 'in', ['customer','supplier']),'&amp;',('picking_id','!=',False),('picking_id.type','=','in')]</field>
<field name="view_id" ref="view_move_tree_reception_picking"/>
<field name="context" eval="'{\'search_default_receive\':1, \'default_location_id\':%d, \'default_location_dest_id\':%d}' % (ref('stock_location_suppliers'),ref('stock_location_stock'))"/>
<field name="context" eval="'{\'search_default_receive\':1, \'product_receive\' : True, \'default_location_id\':%d, \'default_location_dest_id\':%d}' % (ref('stock_location_suppliers'),ref('stock_location_stock') )"/>
<field name="search_view_id" ref="view_move_search_reception_incoming_picking"/>
<field name="help">You will find here the list of all products you are waiting for, according to your preceding purchase orders. Once you receive an order, you can filter based on the name of the supplier or the purchase order reference. Then you can confirm all products received using the buttons on the right of each line.</field>
</record>

View File

@ -23,164 +23,124 @@ from osv import fields, osv
from tools.translate import _
import time
class stock_partial_move_memory(osv.osv_memory):
_name = "stock.move.memory"
_rec_name = 'product_id'
_columns = {
'product_id' : fields.many2one('product.product', string="Product", required=True, readonly=True),
'quantity' : fields.float("Quantity", required=True),
'product_uom': fields.many2one('product.uom', 'Unit of Measure', required=True, readonly=True),
'prodlot_id' : fields.many2one('stock.production.lot', 'Production Lot'),
'move_id' : fields.many2one('stock.move', "Move"),
'wizard_id' : fields.many2one('stock.partial.move', string="Wizard"),
'cost' : fields.float("Cost", help="Unit Cost for this product line", readonly=True),
'currency' : fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed", readonly=True),
}
class stock_partial_move(osv.osv_memory):
_name = "stock.partial.move"
_description = "Partial Move"
_columns = {
'date': fields.datetime('Date', required=True),
'type': fields.char("Type", size=3),
'product_moves' : fields.one2many('stock.move.memory', 'wizard_id', 'Moves'),
}
def view_init(self, cr, uid, fields_list, context=None):
res = super(stock_partial_move, self).view_init(cr, uid, fields_list, context=context)
move_obj = self.pool.get('stock.move')
if not context:
context={}
for m in move_obj.browse(cr, uid, context.get('active_ids', [])):
if m.state in ('done', 'cancel'):
context = {}
for move in move_obj.browse(cr, uid, context.get('active_ids', [])):
if move.state in ('done', 'cancel'):
raise osv.except_osv(_('Invalid action !'), _('Cannot deliver products which are already delivered !'))
if 'move%s_product_id'%(m.id) not in self._columns:
self._columns['move%s_product_id'%(m.id)] = fields.many2one('product.product',string="Product")
if 'move%s_product_qty'%(m.id) not in self._columns:
self._columns['move%s_product_qty'%(m.id)] = fields.float("Quantity")
if 'move%s_product_uom'%(m.id) not in self._columns:
self._columns['move%s_product_uom'%(m.id)] = fields.many2one('product.uom',string="Product UOM")
if 'move%s_prodlot_id'%(m.id) not in self._columns:
self._columns['move%s_prodlot_id'%(m.id)] = fields.many2one('stock.production.lot', string="Lot")
if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
if 'move%s_product_price'%(m.id) not in self._columns:
self._columns['move%s_product_price'%(m.id)] = fields.float("Cost", help="Unit Cost for this product line")
if 'move%s_product_currency'%(m.id) not in self._columns:
self._columns['move%s_product_currency'%(m.id)] = fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed")
return res
def __create_partial_move_memory(self, move):
move_memory = {
'product_id' : move.product_id.id,
'quantity' : move.product_qty,
'product_uom' : move.product_uom.id,
'prodlot_id' : move.prodlot_id.id,
'move_id' : move.id,
}
if move.picking_id.type == 'in':
move_memory.update({
'cost' : move.product_id.standard_price,
'currency' : move.product_id.company_id.currency_id.id,
})
return move_memory
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
result = super(stock_partial_move, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)
def __get_active_stock_moves(self, cr, uid, context=None):
move_obj = self.pool.get('stock.move')
move_ids = context.get('active_ids', False)
move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
_moves_arch_lst = """<form string="Deliver Products">
<separator colspan="4" string="Delivery Information"/>
<field name="date" colspan="2"/>
<separator colspan="4" string="Move Detail"/>
"""
_moves_fields = result['fields']
if move_ids and view_type in ['form']:
for m in move_obj.browse(cr, uid, move_ids, context):
if m.state in ('done', 'cancel'):
continue
_moves_fields.update({
'move%s_product_id'%(m.id) : {
'string': _('Product'),
'type' : 'many2one',
'relation': 'product.product',
'required' : True,
'readonly' : True,
},
'move%s_product_qty'%(m.id) : {
'string': _('Quantity'),
'type' : 'float',
'required': True,
},
'move%s_product_uom'%(m.id) : {
'string': _('Product UOM'),
'type' : 'many2one',
'relation': 'product.uom',
'required' : True,
'readonly' : True,
},
'move%s_prodlot_id'%(m.id): {
'string': _('Production Lot'),
'type': 'many2one',
'relation': 'stock.production.lot',
}
})
if not context:
context = {}
res = []
for move in move_obj.browse(cr, uid, context.get('active_ids', [])):
if move.state in ('done', 'cancel'):
continue
res.append(self.__create_partial_move_memory(move))
return res
_defaults = {
'product_moves' : __get_active_stock_moves,
'date' : time.strftime('%Y-%m-%d %H:%M:%S'),
}
_moves_arch_lst += """
<group colspan="4" col="10">
<field name="move%s_product_id" nolabel="1"/>
<field name="move%s_product_qty" string="Qty" />
<field name="move%s_product_uom" nolabel="1" />
<field name="move%s_prodlot_id" domain="[('product_id','=',move%s_product_id)]" groups="base.group_extended" />
"""%(m.id, m.id, m.id,m.id,m.id)
if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
_moves_fields.update({
'move%s_product_price'%(m.id) : {
'string': _('Cost'),
'type' : 'float',
'help': _('Unit Cost for this product line'),
},
'move%s_product_currency'%(m.id): {
'string': _('Currency'),
'type' : 'many2one',
'relation': 'res.currency',
'help': _("Currency in which Unit Cost is expressed"),
}
})
_moves_arch_lst += """
<field name="move%s_product_price" />
<field name="move%s_product_currency" nolabel="1"/>
"""%(m.id, m.id)
_moves_arch_lst += """
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
height = 2 * 25;
message = {
'title' : _('Deliver Products'),
'info' : _('Delivery Information'),
'button' : _('Deliver'),
}
if context:
height = (len(context.get('active_ids', [])) + 1) * 25
if context.get('product_receive', False):
message = {
'title' : _('Receive Products'),
'info' : _('Receive Information'),
'button' : _('Receive'),
}
message['height'] = height
result = super(stock_partial_move, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
_moves_fields = result['fields']
_moves_fields.update({'product_moves' :
{
'relation': 'stock.move.memory',
'type' : 'one2many',
'string' : 'Product Moves',
}
})
_moves_arch_lst = """
<form string="%(title)s">
<separator colspan="4" string="%(info)s"/>
<field name="date" colspan="2"/>
<separator colspan="4" string="Move Detail"/>
<field name="product_moves" colspan="4" nolabel="1" width="550" height="200" />
<separator string="" colspan="4" />
<label string="" colspan="2"/>
<group col="2" colspan="2">
<button icon='gtk-cancel' special="cancel" string="_Cancel" />
<button name="do_partial" string="%(button)s"
colspan="1" type="object" icon="gtk-apply" />
</group>
"""
_moves_arch_lst += """
<separator string="" colspan="4" />
<label string="" colspan="2"/>
<group col="2" colspan="2">
<button icon='gtk-cancel' special="cancel"
string="_Cancel" />
<button name="do_partial" string="_Deliver"
colspan="1" type="object" icon="gtk-apply" />
</group>
</form>"""
</form> """ % message
result['arch'] = _moves_arch_lst
result['fields'] = _moves_fields
return result
def default_get(self, cr, uid, fields, context=None):
""" To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
res = super(stock_partial_move, self).default_get(cr, uid, fields, context=context)
move_obj = self.pool.get('stock.move')
if not context:
context={}
if 'date' in fields:
res.update({'date': time.strftime('%Y-%m-%d %H:%M:%S')})
move_ids = context.get('active_ids', [])
move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
for m in move_obj.browse(cr, uid, context.get('active_ids', [])):
if m.state in ('done', 'cancel'):
continue
res['type'] = m.picking_id and m.picking_id.type or ''
if 'move%s_product_id'%(m.id) in fields:
res['move%s_product_id'%(m.id)] = m.product_id.id
if 'move%s_product_qty'%(m.id) in fields:
res['move%s_product_qty'%(m.id)] = m.product_qty
if 'move%s_product_uom'%(m.id) in fields:
res['move%s_product_uom'%(m.id)] = m.product_uom.id
if 'move%s_prodlot_id'%(m.id) in fields:
res['move%s_prodlot_id'%(m.id)] = m.prodlot_id.id
if m.picking_id.type == 'in' and m.product_id.cost_method == 'average':
# Always use default product cost and currency from Product Form,
# which belong to the Company owning the product
currency = m.product_id.company_id.currency_id.id
price = m.product_id.standard_price
if 'move%s_product_price'%(m.id) in fields:
res['move%s_product_price'%(m.id)] = price
if 'move%s_product_currency'%(m.id) in fields:
res['move%s_product_currency'%(m.id)] = currency
return res
def do_partial(self, cr, uid, ids, context):
""" Makes partial moves and pickings done.
@param self: The object pointer.
@ -190,32 +150,44 @@ class stock_partial_move(osv.osv_memory):
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
move_obj = self.pool.get('stock.move')
move_ids = context.get('active_ids', False)
partial = self.browse(cr, uid, ids[0], context)
partial_datas = {
'delivery_date' : partial.date
}
for m in move_obj.browse(cr, uid, move_ids):
if m.state in ('done', 'cancel'):
p_moves = {}
for product_move in partial.product_moves:
p_moves[product_move.move_id.id] = product_move
moves_ids_final = []
for move in move_obj.browse(cr, uid, move_ids):
if move.state in ('done', 'cancel'):
continue
partial_datas['move%s'%(m.id)] = {
'product_id' : getattr(partial, 'move%s_product_id'%(m.id)).id,
'product_qty' : getattr(partial, 'move%s_product_qty'%(m.id)),
'product_uom' : getattr(partial, 'move%s_product_uom'%(m.id)).id,
'prodlot_id' : getattr(partial, 'move%s_prodlot_id'%(m.id)).id
if not p_moves.get(move.id, False):
continue
partial_datas['move%s' % (move.id)] = {
'product_id' : p_moves[move.id].product_id.id,
'product_qty' : p_moves[move.id].quantity,
'product_uom' : p_moves[move.id].product_uom.id,
'prodlot_id' : p_moves[move.id].prodlot_id.id,
}
if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
partial_datas['move%s'%(m.id)].update({
'product_price' : getattr(partial, 'move%s_product_price'%(m.id)),
'product_currency': getattr(partial, 'move%s_product_currency'%(m.id)).id
moves_ids_final.append(move.id)
if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
partial_datas['move%s' % (move.id)].update({
'product_price' : p_moves[move.id].cost,
'product_currency': p_moves[move.id].currency.id,
})
move_obj.do_partial(cr, uid, move_ids, partial_datas, context=context)
move_obj.do_partial(cr, uid, moves_ids_final, partial_datas, context=context)
return {}
stock_partial_move()
stock_partial_move_memory()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -2,13 +2,49 @@
<openerp>
<data>
<act_window name="Deliver Products"
<act_window name="Deliver/Receive Products"
res_model="stock.partial.move"
src_model="stock.move"
view_mode="form"
multi="True"
target="new"
key2="client_action_multi"
id="action_partial_move"/>
id="action_partial_move"></act_window>
<record id="stock_move_memory_tree" model="ir.ui.view">
<field name="name">stock.move.memory.tree</field>
<field name="model">stock.move.memory</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree editable="bottom" string="Product Moves">
<field name="product_id" readonly="1" />
<field name="quantity" ></field>
<field name="product_uom"></field>
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" ></field>
<field name="cost"></field>
<field name="currency" ></field>
</tree>
</field>
</record>
<record id="stock_move_memory_form" model="ir.ui.view">
<field name="name">stock.move.memory.form</field>
<field name="model">stock.move.memory</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form>
<field name="product_id" readonly="1" />
<field name="quantity" ></field>
<field name="product_uom"></field>
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" ></field>
<field name="cost"></field>
<field name="currency"></field>
</form>
</field>
</record>
</data>
</openerp>

View File

@ -231,7 +231,8 @@ sale_order_line()
class purchase_order_line(osv.osv):
_inherit = 'purchase.order.line'
def product_id_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):
warning = {}
if not product:
return {'value': {'price_unit': 0.0, 'name':'','notes':'', 'product_uom' : False}, 'domain':{'product_uom':[]}}