[REF] product: refactoring : move fields related to stock into the stock module
[IMP] stock: account moves on stock moves. Bugfixing + correct implementation + refactoring bzr revid: qdp@cyan-20100610124452-ewla273tk6zg4lsv
This commit is contained in:
parent
5eab03db0d
commit
7c72cd000c
|
@ -209,13 +209,6 @@ class product_category(osv.osv):
|
|||
'child_id': fields.one2many('product.category', 'parent_id', string='Child Categories'),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of product categories."),
|
||||
'type': fields.selection([('view','View'), ('normal','Normal')], 'Category Type'),
|
||||
'property_stock_variation': fields.property(
|
||||
'account.account',
|
||||
type='many2one',
|
||||
relation='account.account',
|
||||
string="Stock variation Account",
|
||||
method=True,
|
||||
view_load=True, help="This account will be used in product when valuation type is real-time valuation ",),
|
||||
}
|
||||
|
||||
|
||||
|
@ -465,9 +458,6 @@ class product_product(osv.osv):
|
|||
'price_extra': fields.float('Variant Price Extra', digits_compute=dp.get_precision('Sale Price')),
|
||||
'price_margin': fields.float('Variant Price Margin', digits_compute=dp.get_precision('Sale Price')),
|
||||
'pricelist_id': fields.dummy(string='Pricelist',relation='product.pricelist', type='many2one'),
|
||||
'valuation':fields.selection([('manual_periodic','Manual Periodic Valuation'),
|
||||
('real_time','Real Time valuation'),
|
||||
('','')],'Valuation',help="Decide if the system must automatically creates account moves based on stock moves"),
|
||||
}
|
||||
|
||||
def onchange_uom(self, cursor, user, ids, uom_id,uom_po_id):
|
||||
|
|
|
@ -148,7 +148,6 @@
|
|||
<field name="price_extra" groups="base.group_extended"/>
|
||||
<newline/>
|
||||
<field groups="base.group_extended" name="cost_method"/>
|
||||
<field name="valuation"/>
|
||||
<newline/>
|
||||
<field colspan="4" name="seller_ids" nolabel="1"/>
|
||||
</page>
|
||||
|
|
|
@ -27,12 +27,12 @@ class product_product(osv.osv):
|
|||
_inherit = "product.product"
|
||||
|
||||
|
||||
def get_product_accounts(self, cr, uid, product_id, context={}):
|
||||
def get_product_accounts(self, cr, uid, product_id, context=None):
|
||||
""" To get the stock input account, stock output account and stock journal related to product.
|
||||
@param product_id: product id
|
||||
@return: dictionary which contains information regarding stock input account, stock output account and stock journal
|
||||
"""
|
||||
product_obj = self.pool.get('product.product').browse(cr, uid, product_id, False)
|
||||
"""
|
||||
product_obj = self.pool.get('product.product').browse(cr, uid, product_id, context)
|
||||
|
||||
stock_input_acc = product_obj.property_stock_account_input and product_obj.property_stock_account_input.id or False
|
||||
if not stock_input_acc:
|
||||
|
@ -42,14 +42,15 @@ class product_product(osv.osv):
|
|||
if not stock_output_acc:
|
||||
stock_output_acc = product_obj.categ_id.property_stock_account_output_categ and product_obj.categ_id.property_stock_account_output_categ.id or False
|
||||
|
||||
|
||||
journal_id = product_obj.categ_id.property_stock_journal and product_obj.categ_id.property_stock_journal.id or False
|
||||
account_variation = product_obj.categ_id.property_stock_variation and product_obj.categ_id.property_stock_variation.id or False
|
||||
|
||||
res = {}
|
||||
res.update({'stock_account_input': stock_input_acc})
|
||||
res.update({'stock_account_output': stock_output_acc})
|
||||
res.update({'stock_journal': journal_id})
|
||||
return res
|
||||
return {
|
||||
'stock_account_input': stock_input_acc,
|
||||
'stock_account_output': stock_output_acc,
|
||||
'stock_journal': journal_id,
|
||||
'property_stock_variation': account_variation
|
||||
}
|
||||
|
||||
def do_change_standard_price(self, cr, uid, ids, datas, context={}):
|
||||
""" Changes the Standard Price of Product and creates an account move accordingly.
|
||||
|
@ -312,7 +313,14 @@ class product_product(osv.osv):
|
|||
'track_incoming': fields.boolean('Track Incoming Lots', help="Forces to use a tracking lot during receptions"),
|
||||
'track_outgoing': fields.boolean('Track Outgoing Lots', help="Forces to use a tracking lot during deliveries"),
|
||||
'location_id': fields.dummy(string='Location', relation='stock.location', type='many2one', domain=[('usage','=','internal')]),
|
||||
'valuation':fields.selection([('manual_periodic', 'Periodic (manual)'),
|
||||
('real_time','Real Time (automatized)'),], 'Stock Valuation', help="Decide if the system must automatically creates account moves based on stock moves", required=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'valuation': lambda *a: 'manual_periodic',
|
||||
}
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
res = super(product_product,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
|
||||
if context == None:
|
||||
|
@ -398,7 +406,6 @@ class product_template(osv.osv):
|
|||
string='Stock Output Account', method=True, view_load=True,
|
||||
help='This account will be used, instead of the default one, to value output stock'),
|
||||
}
|
||||
|
||||
product_template()
|
||||
|
||||
|
||||
|
@ -417,8 +424,13 @@ class product_category(osv.osv):
|
|||
type='many2one', relation='account.account',
|
||||
string='Stock Output Account', method=True, view_load=True,
|
||||
help='This account will be used to value the output stock'),
|
||||
'property_stock_variation': fields.property('account.account',
|
||||
type='many2one',
|
||||
relation='account.account',
|
||||
string="Stock variation Account",
|
||||
method=True, view_load=True,
|
||||
help="This account will be used in product when valuation type is real-time valuation ",),
|
||||
}
|
||||
|
||||
product_category()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -123,6 +123,18 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_product_valuation_form" model="ir.ui.view">
|
||||
<field name="name">product.valuation.stock.form.inherit</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="cost_method" position="after">
|
||||
<field name="valuation"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
|
@ -158,7 +157,7 @@ class stock_location(osv.osv):
|
|||
_columns = {
|
||||
'name': fields.char('Location Name', size=64, required=True, translate=True),
|
||||
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the stock location without removing it."),
|
||||
'usage': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production')], 'Location Type', required=True),
|
||||
'usage': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production'), ('transit', 'Transit Location for Inter-Companies Transfers')], 'Location Type', required=True),
|
||||
'allocation_method': fields.selection([('fifo', 'FIFO'), ('lifo', 'LIFO'), ('nearest', 'Nearest')], 'Allocation Method', required=True),
|
||||
|
||||
'complete_name': fields.function(_complete_name, method=True, type='char', size=100, string="Location Name"),
|
||||
|
@ -195,7 +194,7 @@ class stock_location(osv.osv):
|
|||
'parent_right': fields.integer('Right Parent', select=1),
|
||||
'stock_real_value': fields.function(_product_value, method=True, type='float', string='Real Stock Value', multi="stock"),
|
||||
'stock_virtual_value': fields.function(_product_value, method=True, type='float', string='Virtual Stock Value', multi="stock"),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True,select=1),
|
||||
'company_id': fields.many2one('res.company', 'Company', select=1, help='Let this field empty if this location is shared for every companies'),
|
||||
'scrap_location': fields.boolean('Scrap Location', help='Check this box if the current location is a place for destroyed items'),
|
||||
}
|
||||
_defaults = {
|
||||
|
@ -1737,15 +1736,54 @@ class stock_move(osv.osv):
|
|||
#self.action_cancel(cr,uid, ids2, context)
|
||||
return True
|
||||
|
||||
def _get_accounting_values(self, cr, uid, move, context=None):
|
||||
product_obj=self.pool.get('product.product')
|
||||
product_uom_obj = self.pool.get('product.uom')
|
||||
price_type_obj = self.pool.get('product.price.type')
|
||||
accounts = product_obj.get_product_accounts(cr,uid,move.product_id.id,context)
|
||||
acc_src = accounts['stock_account_input']
|
||||
acc_dest = accounts['stock_account_output']
|
||||
acc_variation = accounts['property_stock_variation']
|
||||
journal_id = accounts['stock_journal']
|
||||
|
||||
if not acc_src:
|
||||
raise osv.except_osv(_('Error!'), _('There is no stock input account defined ' \
|
||||
'for this product: "%s" (id: %d)') % \
|
||||
(move.product_id.name, move.product_id.id,))
|
||||
if not acc_dest:
|
||||
raise osv.except_osv(_('Error!'), _('There is no stock output account defined ' \
|
||||
'for this product: "%s" (id: %d)') % \
|
||||
(move.product_id.name, move.product_id.id,))
|
||||
if not journal_id:
|
||||
raise osv.except_osv(_('Error!'), _('There is no journal defined '\
|
||||
'on the product category: "%s" (id: %d)') % \
|
||||
(move.product_id.categ_id.name, move.product_id.categ_id.id,))
|
||||
if not acc_variation:
|
||||
raise osv.except_osv(_('Error!'), _('There is no variation account defined '\
|
||||
'on the product category: "%s" (id: %d)') % \
|
||||
(move.product_id.categ_id.name, move.product_id.categ_id.id,))
|
||||
if acc_src != acc_dest:
|
||||
default_uom = move.product_id.uom_id.id
|
||||
q = product_uom_obj._compute_qty(cr, uid, move.product_uom.id, move.product_qty, default_uom)
|
||||
if move.product_id.cost_method == 'average' and move.price_unit:
|
||||
amount = q * move.price_unit
|
||||
# Base computation on valuation price type
|
||||
else:
|
||||
company_id = move.company_id.id
|
||||
context['currency_id'] = move.company_id.currency_id.id
|
||||
pricetype = price_type_obj.browse(cr,uid,move.company_id.property_valuation_price_type.id)
|
||||
amount_unit = move.product_id.price_get(pricetype.field, context)[move.product_id.id]
|
||||
amount = amount_unit * q or 1.0
|
||||
# amount = q * move.product_id.standard_price
|
||||
return journal_id, acc_src, acc_dest, acc_variation, amount
|
||||
|
||||
|
||||
def action_done(self, cr, uid, ids, context={}):
|
||||
""" Makes the move done and if all moves are done, it will finish the picking.
|
||||
@return:
|
||||
"""
|
||||
track_flag = False
|
||||
picking_ids = []
|
||||
lines=[]
|
||||
sale=[]
|
||||
purchase=[]
|
||||
product_uom_obj = self.pool.get('product.uom')
|
||||
price_type_obj = self.pool.get('product.price.type')
|
||||
product_obj=self.pool.get('product.product')
|
||||
|
@ -1770,76 +1808,37 @@ class stock_move(osv.osv):
|
|||
#
|
||||
acc_src = None
|
||||
acc_dest = None
|
||||
if move.product_id.valuation=='real_time':
|
||||
|
||||
journal_id = move.product_id.categ_id.property_stock_journal and move.product_id.categ_id.property_stock_journal.id or False
|
||||
accounts=product_obj.get_product_accounts(cr,uid,move.product_id.id,context)
|
||||
account_variation = move.product_id.categ_id.property_stock_variation.id
|
||||
acc_src=accounts['stock_account_input']
|
||||
acc_dest=accounts['stock_account_output']
|
||||
journal_id=accounts['stock_journal']
|
||||
if not acc_src:
|
||||
raise osv.except_osv(_('Error!'),
|
||||
_('There is no stock input account defined ' \
|
||||
'for this product: "%s" (id: %d)') % \
|
||||
(move.product_id.name,
|
||||
move.product_id.id,))
|
||||
if not acc_dest:
|
||||
raise osv.except_osv(_('Error!'),
|
||||
_('There is no stock output account defined ' \
|
||||
'for this product: "%s" (id: %d)') % \
|
||||
(move.product_id.name,
|
||||
move.product_id.id,))
|
||||
if not journal_id:
|
||||
raise osv.except_osv(_('Error!'),
|
||||
_('There is no journal defined '\
|
||||
'on the product category: "%s" (id: %d)') % \
|
||||
(move.product_id.categ_id.name,
|
||||
move.product_id.categ_id.id,))
|
||||
if not account_variation:
|
||||
raise osv.except_osv(_('Error!'),
|
||||
_('There is no variation account defined '\
|
||||
'on the product category: "%s" (id: %d)') % \
|
||||
(move.product_id.categ_id.name,
|
||||
move.product_id.categ_id.id,))
|
||||
if acc_src != acc_dest:
|
||||
default_uom = move.product_id.uom_id.id
|
||||
q = product_uom_obj._compute_qty(cr, uid, move.product_uom.id, move.product_qty, default_uom)
|
||||
if move.product_id.cost_method == 'average' and move.price_unit:
|
||||
amount = q * move.price_unit
|
||||
# Base computation on valuation price type
|
||||
else:
|
||||
company_id = move.company_id.id
|
||||
context['currency_id'] = move.company_id.currency_id.id
|
||||
pricetype = price_type_obj.browse(cr,uid,move.company_id.property_valuation_price_type.id)
|
||||
amount_unit = move.product_id.price_get(pricetype.field, context)[move.product_id.id]
|
||||
amount = amount_unit * q or 1.0
|
||||
# amount = q * move.product_id.standard_price
|
||||
partner_id = False
|
||||
if move.picking_id:
|
||||
|
||||
if (move.location_id.usage=='internal' and move.location_dest_id.usage=='customer') or \
|
||||
(move.location_id.usage=='internal' and move.location_dest_id.usage=='internal'\
|
||||
and move.location_id.company_id.id!=move.location_dest_id.company_id.id):
|
||||
sale.append(self.create_account_move(cr,uid,move,acc_dest ,account_variation ,amount,context))
|
||||
if move.product_id.valuation == 'real_time':
|
||||
lines = []
|
||||
if ((move.location_id.usage == 'internal' and move.location_dest_id.usage == 'customer') or (move.location_id.usage == 'internal' and move.location_dest_id.usage == 'transit')):
|
||||
if move.location_id.company_id:
|
||||
context.update({'force_company': move.location_id.company_id.id})
|
||||
journal_id, acc_src, acc_dest, acc_variation, amount = self._get_accounting_values(cr, uid, move, context)
|
||||
lines = [(journal_id, self.create_account_move(cr, uid, move, acc_dest, acc_variation, amount, context))]
|
||||
|
||||
if (move.location_id.usage =='supplier' and move.location_dest_id.usage=='internal') or\
|
||||
(move.location_id.usage=='internal' and move.location_dest_id.usage=='internal'\
|
||||
and move.location_id.company_id.id!=move.location_dest_id.company_id.id):
|
||||
|
||||
purchase.append(self.create_account_move(cr,uid,move,account_variation, acc_src ,amount,context))
|
||||
|
||||
|
||||
lines.append(purchase and purchase[0] )
|
||||
lines.append( sale and sale[0])
|
||||
|
||||
move_obj.create(cr, uid, {
|
||||
elif ((move.location_id.usage == 'supplier' and move.location_dest_id.usage == 'internal') or (move.location_id.usage == 'transit' and move.location_dest_id.usage == 'internal')):
|
||||
if move.location_dest_id.company_id:
|
||||
context.update({'force_company': move.location_dest_id.company_id.id})
|
||||
journal_id, acc_src, acc_dest, acc_variation, amount = self._get_accounting_values(cr, uid, move, context)
|
||||
lines = [(journal_id, self.create_account_move(cr, uid, move, acc_variation, acc_src, amount, context))]
|
||||
elif (move.location_id.usage == 'internal' and move.location_dest_id.usage == 'internal' and move.location_id.company_id != move.location_dest_id.company_id):
|
||||
if move.location_id.company_id:
|
||||
context.update({'force_company': move.location_id.company_id.id})
|
||||
journal_id, acc_src, acc_dest, acc_variation, amount = self._get_accounting_values(cr, uid, move, context)
|
||||
line1 = [(journal_id, self.create_account_move(cr, uid, move, acc_dest, acc_variation, amount, context))]
|
||||
if move.location_dest_id.company_id:
|
||||
context.update({'force_company': move.location_dest_id.company_id.id})
|
||||
journal_id, acc_src, acc_dest, acc_variation, amount = self._get_accounting_values(cr, uid, move, context)
|
||||
line2 = [(journal_id, self.create_account_move(cr, uid, move, acc_variation, acc_src, amount, context))]
|
||||
lines = line1 + line2
|
||||
for j_id, line in lines:
|
||||
move_obj.create(cr, uid, {
|
||||
'name': move.name,
|
||||
'journal_id': journal_id,
|
||||
'journal_id': j_id,
|
||||
'type':'cont_voucher',
|
||||
'line_id': len(lines)==2 and lines[0] +lines[1] or lines,
|
||||
'line_id': line,
|
||||
'ref': move.picking_id and move.picking_id.name,
|
||||
})
|
||||
})
|
||||
tracking_lot = False
|
||||
if context:
|
||||
tracking_lot = context.get('tracking_lot', False)
|
||||
|
|
Loading…
Reference in New Issue