if type(context['location']) == type(1):
location_ids = [context['location']]
elif type(context['location']) in (type(''), type(u'')):
- location_ids = location_obj.search(cr, uid, [('name','ilike',context['location'])], context=context)
+ if context.get('force_company', False):
+ location_ids = location_obj.search(cr, uid, [('name','ilike',context['location']), ('company_id', '=', context['force_company'])], context=context)
+ else:
+ location_ids = location_obj.search(cr, uid, [('name','ilike',context['location'])], context=context)
else:
location_ids = context['location']
else:
if not wids:
return False
for w in warehouse_obj.browse(cr, uid, wids, context=context):
- location_ids.append(w.lot_stock_id.id)
+ if not context.get('force_company', False) or w.lot_stock_id.company_id == context['force_company']:
+ location_ids.append(w.lot_stock_id.id)
# build the list of ids of children of the location given by id
if context.get('compute_child',True):
- child_location_ids = location_obj.search(cr, uid, [('location_id', 'child_of', location_ids)])
+ if context.get('force_company', False):
+ child_location_ids = location_obj.search(cr, uid, [('location_id', 'child_of', location_ids), ('company_id', '=', context['force_company'])])
+ else:
+ child_location_ids = location_obj.search(cr, uid, [('location_id', 'child_of', location_ids)])
location_ids = child_location_ids or location_ids
-
+
+
+
return location_ids
if where_add:
where += where_add
- #It depends on the company of the user OR by using force_company in context
- user = self.pool.get("res.users").browse(cr, uid, uid, context=context)
- if context.get("force_company", False):
- where.append(context['force_company'])
- else:
- where.append(user.company_id.id)
prodlot_id = context.get('prodlot_id', False)
prodlot_clause = ''
'and location_dest_id IN %s '\
'and product_id IN %s '\
'and state IN %s ' + (date_str and 'and '+date_str+' ' or '') +' '\
- 'and company_id = %s '\
+ prodlot_clause +
'group by product_id,product_uom',tuple(where))
results = cr.fetchall()
'and location_dest_id NOT IN %s '\
'and product_id IN %s '\
'and state in %s ' + (date_str and 'and '+date_str+' ' or '') + ' '\
- 'and company_id = %s '\
+ prodlot_clause +
'group by product_id,product_uom',tuple(where))
results2 = cr.fetchall()
return reference_amount, reference_currency_id
+
+
+
def _create_product_valuation_moves(self, cr, uid, move, context=None):
"""
Generate the appropriate accounting moves if the product being moves is subject
reference_amount, reference_currency_id = self._get_reference_accounting_values_for_valuation(cr, uid, move, src_company_ctx)
#returning goods to supplier
if move.location_dest_id.usage == 'supplier':
- account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_valuation, acc_src, reference_amount, reference_currency_id, context))]
+ account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_valuation, acc_src, reference_amount, reference_currency_id, 'out', context=context))]
else:
- account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_valuation, acc_dest, reference_amount, reference_currency_id, context))]
+ account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_valuation, acc_dest, reference_amount, reference_currency_id, 'out', context=context))]
# Incoming moves (or cross-company input part)
if move.location_dest_id.company_id \
reference_amount, reference_currency_id = self._get_reference_accounting_values_for_valuation(cr, uid, move, src_company_ctx)
#goods return from customer
if move.location_id.usage == 'customer':
- account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_dest, acc_valuation, reference_amount, reference_currency_id, context))]
+ account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_dest, acc_valuation, reference_amount, reference_currency_id, 'in', context=context))]
else:
- account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_src, acc_valuation, reference_amount, reference_currency_id, context))]
+ account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_src, acc_valuation, reference_amount, reference_currency_id, 'in', context=context))]
move_obj = self.pool.get('account.move')
for j_id, move_lines in account_moves:
move_obj.create(cr, uid,
return True
- def _create_account_move_line(self, cr, uid, move, src_account_id, dest_account_id, reference_amount, reference_currency_id, context=None):
+ def _create_account_move_line(self, cr, uid, move, src_account_id, dest_account_id, reference_amount, reference_currency_id, type='', context=None):
"""
Generate the account.move.line values to post to track the stock valuation difference due to the
processing of the given stock move.
"""
- # prepare default values considering that the destination accounts have the reference_currency_id as their main currency
- partner_id = (move.picking_id.partner_id and self.pool.get('res.partner')._find_accounting_partner(move.picking_id.partner_id).id) or False
- debit_line_vals = {
- 'name': move.name,
- 'product_id': move.product_id and move.product_id.id or False,
- 'quantity': move.product_qty,
- 'ref': move.picking_id and move.picking_id.name or False,
- 'date': time.strftime('%Y-%m-%d'),
- 'partner_id': partner_id,
- 'debit': reference_amount,
- 'account_id': dest_account_id,
- }
- credit_line_vals = {
- 'name': move.name,
- 'product_id': move.product_id and move.product_id.id or False,
- 'quantity': move.product_qty,
- 'ref': move.picking_id and move.picking_id.name or False,
- 'date': time.strftime('%Y-%m-%d'),
- 'partner_id': partner_id,
- 'credit': reference_amount,
- 'account_id': src_account_id,
- }
+ move_list = []
+ # Consists of access rights
+ # TODO Check if currency is not needed
+ if type == 'out' and move.product_id.cost_method in ['fifo', 'lifo']:
+ match_obj = self.pool.get("stock.move.matching")
+ matches = match_obj.search(cr, uid, [('move_out_id','=', move.id)], context=context)
+ for match in match_obj.browse(cr, uid, matches, context=context):
+ move_in = match.move_in_id
+ move_list += [(match.qty, match.qty * match.price_unit_out)]
+ else:
+ move_list = [(move.product_qty, reference_amount)]
+
+ res = []
+ for item in move_list:
+ # prepare default values considering that the destination accounts have the reference_currency_id as their main currency
+ partner_id = (move.picking_id.partner_id and self.pool.get('res.partner')._find_accounting_partner(move.picking_id.partner_id).id) or False
+ debit_line_vals = {
+ 'name': move.name,
+ 'product_id': move.product_id and move.product_id.id or False,
+ 'quantity': item[0],
+ 'ref': move.picking_id and move.picking_id.name or False,
+ 'date': time.strftime('%Y-%m-%d'),
+ 'partner_id': partner_id,
+ 'debit': item[1],
+ 'account_id': dest_account_id,
+ }
+ credit_line_vals = {
+ 'name': move.name,
+ 'product_id': move.product_id and move.product_id.id or False,
+ 'quantity': item[0],
+ 'ref': move.picking_id and move.picking_id.name or False,
+ 'date': time.strftime('%Y-%m-%d'),
+ 'partner_id': partner_id,
+ 'credit': item[1],
+ 'account_id': src_account_id,
+ }
- # if we are posting to accounts in a different currency, provide correct values in both currencies correctly
- # when compatible with the optional secondary currency on the account.
- # Financial Accounts only accept amounts in secondary currencies if there's no secondary currency on the account
- # or if it's the same as that of the secondary amount being posted.
- account_obj = self.pool.get('account.account')
- src_acct, dest_acct = account_obj.browse(cr, uid, [src_account_id, dest_account_id], context=context)
- src_main_currency_id = src_acct.company_id.currency_id.id
- dest_main_currency_id = dest_acct.company_id.currency_id.id
- cur_obj = self.pool.get('res.currency')
- if reference_currency_id != src_main_currency_id:
- # fix credit line:
- credit_line_vals['credit'] = cur_obj.compute(cr, uid, reference_currency_id, src_main_currency_id, reference_amount, context=context)
- if (not src_acct.currency_id) or src_acct.currency_id.id == reference_currency_id:
- credit_line_vals.update(currency_id=reference_currency_id, amount_currency=-reference_amount)
- if reference_currency_id != dest_main_currency_id:
- # fix debit line:
- debit_line_vals['debit'] = cur_obj.compute(cr, uid, reference_currency_id, dest_main_currency_id, reference_amount, context=context)
- if (not dest_acct.currency_id) or dest_acct.currency_id.id == reference_currency_id:
- debit_line_vals.update(currency_id=reference_currency_id, amount_currency=reference_amount)
-
- return [(0, 0, debit_line_vals), (0, 0, credit_line_vals)]
+ # if we are posting to accounts in a different currency, provide correct values in both currencies correctly
+ # when compatible with the optional secondary currency on the account.
+ # Financial Accounts only accept amounts in secondary currencies if there's no secondary currency on the account
+ # or if it's the same as that of the secondary amount being posted.
+ #TODO -> might need to be changed still for fifolifo
+ account_obj = self.pool.get('account.account')
+ src_acct, dest_acct = account_obj.browse(cr, uid, [src_account_id, dest_account_id], context=context)
+ src_main_currency_id = src_acct.company_id.currency_id.id
+ dest_main_currency_id = dest_acct.company_id.currency_id.id
+ cur_obj = self.pool.get('res.currency')
+ if reference_currency_id != src_main_currency_id:
+ # fix credit line:
+ credit_line_vals['credit'] = cur_obj.compute(cr, uid, reference_currency_id, src_main_currency_id, reference_amount, context=context)
+ if (not src_acct.currency_id) or src_acct.currency_id.id == reference_currency_id:
+ credit_line_vals.update(currency_id=reference_currency_id, amount_currency=-reference_amount)
+ if reference_currency_id != dest_main_currency_id:
+ # fix debit line:
+ debit_line_vals['debit'] = cur_obj.compute(cr, uid, reference_currency_id, dest_main_currency_id, reference_amount, context=context)
+ if (not dest_acct.currency_id) or dest_acct.currency_id.id == reference_currency_id:
+ debit_line_vals.update(currency_id=reference_currency_id, amount_currency=reference_amount)
+ res += [(0, 0, debit_line_vals), (0, 0, credit_line_vals)]
+ return res
def unlink(self, cr, uid, ids, context=None):
if context is None:
if avg_in_update or avg_out_update:
# If no price from picking, use cost price from product
- if product_price == 0:
+ if product_price == 0.0:
product_price = product.price_get('standard_price', context=ctx)[product.id]
move_currency_id = move.company_id.currency_id.id
<record id="stock_location_intermediatelocation0" model="stock.location">
<field name="partner_id" ref="base.main_partner"/>
<field name="location_id" ref="stock.stock_location_locations_partner"/>
- <field name="usage">procurement</field>
+ <field name="usage">transit</field>
<field name="name">Internal Shippings</field>
</record>
ctx['force_company'] = company_id
product = product_obj.browse(cr, uid, move.product_id.id, context=ctx)
cost_method = product.cost_method
-
+ uom_id = product.uom_id.id
if move.picking_id.type == 'out' and cost_method in ['fifo', 'lifo']:
+ #This price has to be put as the new standard price for the product, but needs to be converted to product UoM and currency
+ #convert uom of qty
+
+ product_uom_qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, uom_id)
+
#get_stock_matchings will convert to currency and UoM of this stock move
tuples = product_obj.get_stock_matchings_fifolifo(cr, uid, [product.id], product_qty, cost_method == 'fifo',
- product_uom, move.company_id.currency_id.id, context=context) #Always move of the company
+ product_uom, move.company_id.currency_id.id, context=context) #Always currency of the company
price_amount = 0.0
amount = 0.0
move_currency_id = move.company_id.currency_id.id
ctx['currency_id'] = move_currency_id
for match in tuples:
matchvals = {'move_in_id': match[0], 'qty': match[1],
- 'move_out_id': move.id}
+ 'move_out_id': move.id, 'price_unit_out': match[2]}
match_id = matching_obj.create(cr, uid, matchvals, context=context)
move_in = self.browse(cr, uid, match[0], context=context)
#Reduce remaining quantity
self.write(cr, uid, match[0], { 'qty_remaining': move_in.qty_remaining - match[3]}, context=context)
price_amount += match[1] * match[2]
amount += match[1]
- self.write(cr, uid, move.id, {'price_unit': price_amount / amount}, context=context)
- print price_amount
- print amount
- #This price has to be put as the new standard price for the product, but needs to be converted to product UoM and currency
- #convert uom of qty
- uom_id = product.uom_id.id
- product_qty = uom_obj._compute_qty(cr, uid, product_uom, amount, uom_id)
+ if product.qty_available >= product_uom_qty:
+ self.write(cr, uid, move.id, {'price_unit': price_amount / amount}, context=context)
+ else:
+ self.write(cr, uid, move.id, {'price_unit': price_amount / amount}, context=context)
+
+
#convert price, no need of UoM conversion as it is the total price
currency_id = move.company_id.currency_id.id
currency_from = move.price_currency_id
else:
new_price = price_amount
#new_price does not depend on qty as it is the total amount => no conversion needed for uom
- product_obj.write(cr, uid, product.id, {'standard_price': new_price / product_qty}, context=ctx)
- # When the move is products returned to supplier or return products from customer
- # then the price should be the price from the original move
+ product_obj.write(cr, uid, product.id, {'standard_price': new_price / product_uom_qty}, context=ctx)
+ # When the move is products returned to supplier or return products from customer,
+ # it should be treated as a normal in or out, so for every in
elif cost_method in ['fifo', 'lifo']:
#The currency in the stock move should be the currency of the company
- if product_currency != move.company_id.currency_id.id:
- new_price = currency_obj.compute(cr, uid, product_currency, move.company_id.currency_id.id,
- product_price, round=False)
- else:
- new_price = product_price
+ if product_price > 0.0:
+ if product_currency != move.company_id.currency_id.id:
+ new_price = currency_obj.compute(cr, uid, product_currency, move.company_id.currency_id.id,
+ product_price, round=False)
+ else:
+ new_price = product_price
+ else:
+ if product_uom != uom_id:
+ new_price = uom_obj._compute_price(cr, uid, uom_id, new_price,
+ product_uom)
+ else:
+ new_price = product.standard_price
self.write(cr, uid, [move.id],
{'price_unit': new_price,
'price_currency_id': move.company_id.currency_id.id})
_columns = {
'move_in_id': fields.many2one('stock.move', 'Stock move in', required=True),
'move_out_id': fields.many2one('stock.move', 'Stock move out', required=True),
- 'qty': fields.integer('Quantity', required=True),
+ 'qty': fields.float('Quantity', required=True),
'price_unit':fields.related('move_in_id', 'price_unit', string="Unit price", type="float"),
+ 'price_unit_out': fields.float('Unit price out')
}
partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]})
self.do_partial(cr, uid, [partial_id])
-
+ A purchase order towards the Chicago shop
+-
+ !record {model: purchase.order, id: purchase_order_fifo_comp}:
+ partner_id: base.res_partner_3
+ company_id: stock.res_company_1
+ location_id: stock.stock_location_shop0
+ pricelist_id: 1
+ order_line:
+ - product_id: product_fifo_icecream
+ product_qty: 35.0
+ product_uom: product.product_uom_categ_kgm
+ price_unit: 50.0
+ name: 'FIFO Ice Cream'
+-
+ I confirm the Chicago Shop company's purchase order'
+-
+ !workflow {model: purchase.order, action: purchase_confirm, ref: purchase_order_fifo_comp}
+-
+ I receive the Chicago Shop company's purchase order'
+-
+ !python {model: stock.partial.picking}: |
+ pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo_comp")).picking_ids
+ partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]})
+ self.do_partial(cr, uid, [partial_id])
+-
Check the standard price should not have changed
-
!python {model: product.product}: |
!python {model: product.product}: |
print self.browse(cr, uid, ref("product_fifo_icecream")).standard_price
print self.browse(cr, uid, ref("product_fifo_icecream")).qty_available
+ print self.browse(cr, uid, ref("product_fifo_icecream"), context={'force_company': 1}).qty_available
list = self.pool.get("stock.move").search(cr, uid, [('product_id','=', ref("product_fifo_icecream"))])
for move in self.pool.get("stock.move").browse(cr, uid, list):
print move.price_unit, move.product_qty, move.qty_remaining, move.type, move.date
\ No newline at end of file