[MERGE] merge from trunk addons
bzr revid: mra@mra-laptop-20101029044405-mjh05se7006rk7sy
This commit is contained in:
commit
d32f945515
|
@ -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 user’s 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)
|
||||
|
|
|
@ -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)" />
|
||||
|
|
|
@ -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)" />
|
||||
|
|
|
@ -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\'.\
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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")
|
||||
|
||||
}
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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))+"])]",
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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">['|','&',('picking_id','=',False),('location_id.usage', 'in', ['customer','supplier']),'&',('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>
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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':[]}}
|
||||
|
|
Loading…
Reference in New Issue