def onchange_trx_lines(self, cr, uid, ids, transaction_lines, payment_lines, context=None): amount = 0.0 if transaction_lines: _line_pool = self.pool.get('via.assign.transaction.line') transaction_lines = resolve_o2m_operations(cr, uid, _line_pool, transaction_lines, ['amount_to_use'], context=context) or [] if payment_lines: _line_pool = self.pool.get('via.assign.payment.line') payment_lines = resolve_o2m_operations(cr, uid, _line_pool, payment_lines, context=context) or [] if transaction_lines: amount = transaction_lines[0]['amount_to_use'] for _line in payment_lines: _amount_to_pay = min(_line['amount_to_pay'] or _line['residual'], amount) _line['amount_to_pay'] = _amount_to_pay amount -= _amount_to_pay _line = prep_dict_for_write(cr, uid, _line, context=context) return {'value': { 'payment_lines': payment_lines, 'writeoff_amount': amount, 'with_writeoff': amount and 'with_writeoff' or 'no_writeoff', }} else: for _line in payment_lines: _line['amount_to_pay'] = 0.0 _line = prep_dict_for_write(cr, uid, _line, context=context) return {'value': { 'payment_lines': payment_lines, 'writeoff_amount': 0.0, 'with_writeoff': 'no_writeoff', }} return {}
def onchange_payment_lines(self, cr, uid, ids, transaction_lines, payment_lines, context=None): # _wo_amount = self._get_writeoff_amount(cr, uid, ids, False, False, context=context) # _wwo = _wo_amount[ids[0]] and 'with_writeoff' or 'no_writeoff' # return {'value': {'writeoff_amount': _wo_amount[ids[0]], 'with_writeoff': _wwo}} amount = 0.0 if transaction_lines: _line_pool = self.pool.get('via.assign.transaction.line') transaction_lines = resolve_o2m_operations(cr, uid, _line_pool, transaction_lines, ['amount_to_use'], context=context) or [] if payment_lines: _line_pool = self.pool.get('via.assign.payment.line') payment_lines = resolve_o2m_operations(cr, uid, _line_pool, payment_lines, context=context) or [] if transaction_lines: amount = transaction_lines[0]['amount_to_use'] for _line in payment_lines: amount -= _line['amount_to_pay'] _line = prep_dict_for_write(cr, uid, _line, context=context) return {'value': { 'writeoff_amount': amount, 'with_writeoff': amount and 'with_writeoff' or 'no_writeoff', }} else: return {'value': { 'writeoff_amount': 0.0, 'with_writeoff': 'no_writeoff', }} return {}
def onchange_move_line_id(self, cr, uid, ids, move_line_id, context=None): if context is None: context = {} # Not saved o2m row sometimes pass the ids as a non numeric information if ids and isinstance(ids[0], ( int, long, )) and ids[0]: _trx_line = self.pool.get('via.account.move.line').read( cr, uid, ids[0], context=context) if (_trx_line['move_line_id'] == move_line_id): return {} rv = {'value': {'amount_to_use': 0.0}} if move_line_id: _aml = self.pool.get('account.move.line').browse(cr, uid, move_line_id, context=context) if _aml: _aml_data = _aml.read()[0] _aml_data = prep_dict_for_write(cr, uid, _aml_data, context=context) _aml_data['amount_residual'] = _aml.signed_amount_residual _aml_data['amount_to_use'] = _aml.signed_amount_residual rv['value'].update(_aml_data) return rv
def prepare_instance(self, cr, uid, ids, context=None): """ This method will create an instance of product.transformation based on the given information ----------------------------------------------------------- @param self : Object Pointer @param cr : Database Cursor @param uid : Current Logged in User @return : A dictionary ready to be passed to write method """ res = {} for _obj in self.browse(cr, uid, ids, context=context): _vals = _obj.read(context=context)[0] 'prod_cons_ids', 'finish_goods_ids' _vals = prep_dict_for_write(cr, uid, _vals, context=context) _vals.update({ 'reference': _vals.get('name', ''), 'raw_src_loc_id': _vals.get('raw_loc_id', False), 'finish_goods_loc_id': _vals.get('finish_loc_id', False), 'trans_tmpl_id': _obj.id, }) for _key in [ 'name', 'raw_loc_id', 'state', 'prod_cons_ids', 'finish_goods_ids' ]: if _key in _vals: del _vals[_key] _ctx = context.copy() _ctx.update({'raw_loc': bool(_obj.raw_loc_id)}) _vals.update({ 'consume_line_ids': [ line.prepare_instance(context=_ctx).get(line.id, {}) for line in _obj.prod_cons_ids ] }) _ctx = context.copy() _ctx.update({'finished_loc': bool(_obj.raw_loc_id)}) _vals.update({ 'finish_goods_line_ids': [ line.prepare_instance(context=_ctx).get(line.id, {}) for line in _obj.finish_goods_ids ] }) res.setdefault(_obj.id, _vals) return res
def onchange_get_lines(self, cr, uid, ids, date, opp_acc_id, journal_id, context=None): _aml_pool = self.pool.get('account.move.line') _move_lines = _aml_pool.search(cr, uid, [('date', '=', date), ('account_id', '=', opp_acc_id), ('journal_id', '=', journal_id), ('reconcile_id', '=', False)], context=context) # It is assumed that only one record is changed at a time _bank_lines = [] _assignment_lines = [] _bank_m2olines = [] _bank_mlines = {} _vexv = False if ids: _vexv = self.pool.get('via.expense.voucher').browse(cr, uid, ids[0], context=context) _assignment_lines = map(lambda x: x.id, _vexv.assignment_lines) for _line in _vexv.bank_lines: _bank_mlines[_line.move_line_id.id] = _line.id _aaml_pool = self.pool.get('via.account.move.line') for _line in _move_lines: if _line in _bank_mlines: _bank_lines.append(_bank_mlines[_line]) _bank_m2olines.append((1, _bank_mlines[_line], {})) else: if ids and _vexv: _new_line = _aaml_pool.create(cr, uid, {'exp_voucher_id': _vexv.id, 'move_line_id': _line}, context=context) _bank_lines.append(_new_line) _bank_m2olines.append((1, _new_line, {})) else: _aml = _aml_pool.browse(cr, uid, _line, context=context) if _aml: _aml_data = _aml.read()[0] for _key in ['id', 'create_uid', 'create_date', 'write_uid', 'write_date', 'amount_residual']: if _key in _vals: del _vals[_key] _aml_data = prep_dict_for_write(cr, uid, _aml_data, context=context) _aml_data['move_line_id'] = _line _aml_data['amount_residual'] = _aml.signed_amount_residual _aml_data['amount_to_use'] = _aml.signed_amount_residual rv['value'].update(_aml_data) _bank_lines.append(_aml_data) _bank_m2olines.append((1, False, _aml_data)) rv = self.onchange_lines(cr, uid, ids, _bank_m2olines, _assignment_lines, context=context) rv['value']['bank_lines'] = _bank_lines return rv
def prepare_instance(self, cr, uid, ids, context=None): """ This method will create an instance of product.transformation based on the given information ----------------------------------------------------------- @param self : Object Pointer @param cr : Database Cursor @param uid : Current Logged in User @return : A dictionary ready to be passed to write method """ res = {} for _obj in self.browse(cr, uid, ids, context=context): _vals = _obj.read(context=context)[0] "prod_cons_ids", "finish_goods_ids" _vals = prep_dict_for_write(cr, uid, _vals, context=context) _vals.update( { "reference": _vals.get("name", ""), "raw_src_loc_id": _vals.get("raw_loc_id", False), "finish_goods_loc_id": _vals.get("finish_loc_id", False), "trans_tmpl_id": _obj.id, } ) for _key in ["name", "raw_loc_id", "state", "prod_cons_ids", "finish_goods_ids"]: if _key in _vals: del _vals[_key] _ctx = context.copy() _ctx.update({"raw_loc": bool(_obj.raw_loc_id)}) _vals.update( { "consume_line_ids": [ line.prepare_instance(context=_ctx).get(line.id, {}) for line in _obj.prod_cons_ids ] } ) _ctx = context.copy() _ctx.update({"finished_loc": bool(_obj.raw_loc_id)}) _vals.update( { "finish_goods_line_ids": [ line.prepare_instance(context=_ctx).get(line.id, {}) for line in _obj.finish_goods_ids ] } ) res.setdefault(_obj.id, _vals) return res
def get_invoice_info(self, cr, uid, invoice_line_ids, context=None): res = {} if not context: context = {} if isinstance(invoice_line_ids, (list, tuple, dict, )): select = list(invoice_line_ids) else: select = [invoice_line_ids] _cols = self._columns.keys() for _obj in self.pool.get('account.invoice.line').read(cr, uid, select, _cols, context=context): _obj_id = _obj['id'] _obj = prep_dict_for_write(cr, uid, _obj, context=context) res[_obj_id] = _obj.copy() return isinstance(invoice_line_ids, (int, long, )) and res[invoice_line_ids] or res
def onchange_move_line_id(self, cr, uid, ids, move_line_id, context=None): if context is None: context = {} if ids and ids[0]: _trx_line = self.pool.get('via.assign.transaction.line').read(cr, uid, ids[0], context=context) if (_trx_line['move_line_id'] == move_line_id): return {} rv = {'value': {'amount_to_use': 0.0}} if move_line_id: _aml = self.pool.get('account.move.line').browse(cr, uid, move_line_id, context=context) if _aml: _aml_data = _aml.read()[0] _aml_data = prep_dict_for_write(cr, uid, _aml_data, context=context) _aml_data['amount_residual'] = -1 * _aml.signed_amount_residual _aml_data['amount_to_use'] = -1 * _aml.signed_amount_residual rv['value'].update(_aml_data) return rv
def onchange_move_line_id(self, cr, uid, ids, move_line_id, context=None): if context is None: context = {} # Not saved o2m row sometimes pass the ids as a non numeric information if ids and isinstance(ids[0], (int, long, )) and ids[0]: _trx_line = self.pool.get('via.account.move.line').read(cr, uid, ids[0], context=context) if (_trx_line['move_line_id'] == move_line_id): return {} rv = {'value': {'amount_to_use': 0.0}} if move_line_id: _aml = self.pool.get('account.move.line').browse(cr, uid, move_line_id, context=context) if _aml: _aml_data = _aml.read()[0] _aml_data = prep_dict_for_write(cr, uid, _aml_data, context=context) _aml_data['amount_residual'] = _aml.signed_amount_residual _aml_data['amount_to_use'] = _aml.signed_amount_residual rv['value'].update(_aml_data) return rv
def get_invoice_info(self, cr, uid, invoice_line_ids, context=None): res = {} if not context: context = {} if isinstance(invoice_line_ids, ( list, tuple, dict, )): select = list(invoice_line_ids) else: select = [invoice_line_ids] _cols = self._columns.keys() for _obj in self.pool.get('account.invoice.line').read( cr, uid, select, _cols, context=context): _obj_id = _obj['id'] _obj = prep_dict_for_write(cr, uid, _obj, context=context) res[_obj_id] = _obj.copy() return isinstance(invoice_line_ids, ( int, long, )) and res[invoice_line_ids] or res
def realise_tax(self, cr, uid, ids, realizaton_date=date.today().strftime('%Y-%m-%d'), context=None): if not context: context = {} select = ids if isinstance(select, ( int, long, )): select = [ids] obj_move = self.pool.get('account.move') obj_move_line = self.pool.get('account.move.line') obj_period = self.pool.get('account.period') for _tax in self.pool.get('account.invoice.tax').browse( cr, uid, select, context=context): # FIND PERIOD period_ids = obj_period.find(cr, uid, realizaton_date, context=context) period_id = period_ids and period_ids[0] or False # FIND DEBIT AND CREDIT ACCOUNT _doc_name = (_tax.invoice_id and (_tax.invoice_id.type in ('in_invoice', 'out_invoice')) and 'invoice') or 'refund' account_realise_id = _tax.get_realisation_account()[_tax.id] if not account_realise_id: if isinstance(ids, ( int, long, )) or (len(ids) == 1): raise osv.except_osv( _('Error!'), _('No %s tax realisation account defined for %s.') % (_doc_name, _tax.account_id.code)) continue # FIND JOURNAL journal_id = _tax.get_realisation_journal()[_tax.id] if not journal_id: if isinstance(ids, ( int, long, )) or (len(ids) == 1): raise osv.except_osv( _('Error!'), _('No %s tax realisation journal defined for %s') % (_doc_name, _tax.account_id.code)) continue # CANNOT REALIZE TAX LINE THAT HAS BEEN REALIZED if _tax.realise_move_id: if isinstance(ids, ( int, long, )) or (len(ids) == 1): raise osv.except_osv(_('Warning!'), _('Tax can only be realised once.')) continue # DETERMINE DEBIT / CREDIT ACCOUNT move_tax = _tax.find_tax_move()[_tax.id] if not move_tax: if isinstance(ids, ( int, long, )) or (len(ids) == 1): raise osv.except_osv(_('Error!'), _('Cannot find tax move!!!')) continue val_line = move_tax and move_tax.read()[0] or {} val_line = val_line and prep_dict_for_write( cr, uid, val_line, context=context) or {} for k in val_line.keys(): if k not in ('currency_id', 'partner_id', 'tax_amount', 'product_id', 'account_tax_id', 'product_uom_id', 'quantity'): del val_line[k] debit_account_id = ( (move_tax.debit != 0.00) and account_realise_id.id) or move_tax.account_id.id credit_account_id = ( (move_tax.credit != 0.00) and account_realise_id.id) or move_tax.account_id.id # CREATE MOVE val_move = { 'date': realizaton_date, 'journal_id': journal_id.id, 'period_id': period_id, } realise_move_id = obj_move.create(cr, uid, val_move, context=context) _tax.write({'realise_move_id': realise_move_id}) # CREATE DEBIT LINE val_line_debit = val_line.copy() val_line_debit.update({ 'name': 'Tax realisation - %s' % (move_tax.name), 'debit': abs(move_tax.debit - move_tax.credit), 'credit': 0.0, 'account_id': debit_account_id, 'period_id': period_id, 'journal_id': journal_id.id, 'move_id': realise_move_id, 'amount_currency': abs(move_tax.amount_currency), 'date': realizaton_date, }) line_debit_id = obj_move_line.create(cr, uid, val_line_debit, context=context) # CREDIT LINE val_line_credit = val_line.copy() val_line_credit.update({ 'name': 'Tax realisation - %s' % (move_tax.name), 'debit': 0.0, 'credit': abs(move_tax.debit - move_tax.credit), 'account_id': credit_account_id, 'period_id': period_id, 'journal_id': journal_id.id, 'move_id': realise_move_id, 'amount_currency': -1.0 * abs(move_tax.amount_currency), 'date': realizaton_date, }) line_credit_id = obj_move_line.create(cr, uid, val_line_credit, context=context) # POST MOVE obj_move.post(cr, uid, [realise_move_id], context=context) # RECONCILE reconcile_ids = [] reconcile_ids.append(move_tax.id) reconcile_ids.append(((move_tax.debit != 0.0) and line_credit_id) or line_debit_id) obj_move_line.reconcile_partial(cr, uid, reconcile_ids) return True
def realise_tax(self, cr, uid, ids, realizaton_date=date.today().strftime('%Y-%m-%d'), context=None): if not context: context = {} select = ids if isinstance(select, (int, long, )): select = [ids] obj_move = self.pool.get('account.move') obj_move_line = self.pool.get('account.move.line') obj_period = self.pool.get('account.period') for _tax in self.pool.get('account.invoice.tax').browse(cr, uid, select, context=context): # FIND PERIOD period_ids = obj_period.find(cr, uid, realizaton_date, context=context) period_id = period_ids and period_ids[0] or False # FIND DEBIT AND CREDIT ACCOUNT _doc_name = (_tax.invoice_id and (_tax.invoice_id.type in ('in_invoice', 'out_invoice')) and 'invoice') or 'refund' account_realise_id = _tax.get_realisation_account()[_tax.id] if not account_realise_id: if isinstance(ids, (int, long, )) or (len(ids) == 1): raise osv.except_osv(_('Error!'), _('No %s tax realisation account defined for %s.') % (_doc_name, _tax.account_id.code)) continue # FIND JOURNAL journal_id = _tax.get_realisation_journal()[_tax.id] if not journal_id: if isinstance(ids, (int, long, )) or (len(ids) == 1): raise osv.except_osv(_('Error!'), _('No %s tax realisation journal defined for %s') % (_doc_name, _tax.account_id.code)) continue # CANNOT REALIZE TAX LINE THAT HAS BEEN REALIZED if _tax.realise_move_id: if isinstance(ids, (int, long, )) or (len(ids) == 1): raise osv.except_osv(_('Warning!'), _('Tax can only be realised once.')) continue # DETERMINE DEBIT / CREDIT ACCOUNT move_tax = _tax.find_tax_move()[_tax.id] if not move_tax: if isinstance(ids, (int, long, )) or (len(ids) == 1): raise osv.except_osv(_('Error!'), _('Cannot find tax move!!!')) continue val_line = move_tax and move_tax.read()[0] or {} val_line = val_line and prep_dict_for_write(cr, uid, val_line, context=context) or {} for k in val_line.keys(): if k not in ('currency_id', 'partner_id', 'tax_amount', 'product_id', 'account_tax_id', 'product_uom_id', 'quantity'): del val_line[k] debit_account_id = ((move_tax.debit != 0.00) and account_realise_id.id) or move_tax.account_id.id credit_account_id = ((move_tax.credit != 0.00) and account_realise_id.id) or move_tax.account_id.id # CREATE MOVE val_move = { 'date': realizaton_date, 'journal_id': journal_id.id, 'period_id': period_id, } realise_move_id = obj_move.create(cr, uid, val_move, context=context) _tax.write({'realise_move_id': realise_move_id}) # CREATE DEBIT LINE val_line_debit = val_line.copy() val_line_debit.update({ 'name': 'Tax realisation - %s' % (move_tax.name), 'debit': abs(move_tax.debit - move_tax.credit), 'credit': 0.0, 'account_id': debit_account_id, 'period_id': period_id, 'journal_id': journal_id.id, 'move_id': realise_move_id, 'amount_currency': abs(move_tax.amount_currency), 'date': realizaton_date, }) line_debit_id = obj_move_line.create(cr, uid, val_line_debit, context=context) # CREDIT LINE val_line_credit = val_line.copy() val_line_credit.update({ 'name': 'Tax realisation - %s' % (move_tax.name), 'debit': 0.0, 'credit': abs(move_tax.debit - move_tax.credit), 'account_id': credit_account_id, 'period_id': period_id, 'journal_id': journal_id.id, 'move_id': realise_move_id, 'amount_currency': -1.0 * abs(move_tax.amount_currency), 'date': realizaton_date, }) line_credit_id = obj_move_line.create(cr, uid, val_line_credit, context=context) # POST MOVE obj_move.post(cr, uid, [realise_move_id], context=context) # RECONCILE reconcile_ids = [] reconcile_ids.append(move_tax.id) reconcile_ids.append(((move_tax.debit != 0.0) and line_credit_id) or line_debit_id) obj_move_line.reconcile_partial(cr, uid, reconcile_ids) return True
def _create_pickings_and_procurements(self, cr, uid, order, order_lines, picking_id=False, context=None): """ This method is creating move of the product from prodution Lot Based on FIFO/LIFO costing method ------------------------------------------------------------------------------------------------ @param self: ojbect pointer @param cr: database cursor @param uid: current logged in user @param order: browse record of sale order @param order_lines: contain list of browse moves of sale order @param picking_id: contain delivery order's id of created from sale order @param context: Standard Dictionary """ result = super(sale_order, self)._create_pickings_and_procurements(cr, uid, order, order_lines, picking_id, context) _fields_to_move = ['picking_id', 'product_id', 'date', 'date_expected', 'product_uom', 'product_packaging', 'location_id', 'location_dest_id', 'sale_line_id', 'state', 'note', 'company_id'] uom_obj = self.pool.get('product.uom') lot_obj = self.pool.get('stock.production.lot') stock_move_obj = self.pool.get('stock.move') for picking in order.picking_ids: for move in picking.move_lines: if move.product_id.is_auto_assign: move_vals = move.read(context=context) move_vals = move_vals and prep_dict_for_write(cr, uid, move_vals[0], context=context) or {} for k in move_vals.keys(): if k not in _fields_to_move: del move_vals[k] _prod_uom = move.product_id and move.product_id.uom_id.id or False _move_uom = (move.product_uom and move.product_uom.id) or \ (move.product_uos and move.product_uos.id) or \ _prod_uom move_vals.update({ 'name': move.product_id.name, 'product_uos_qty': (move.product_uos and move.product_uos_qty) or move.product_qty, 'product_uos': _move_uom, 'address_id': move.address_id.id or move.picking_id.sale_id.partner_shipping_id.id, }) # Get all available Production Lot sorted based on the Product's Cost Method _res = lot_obj.get_available_lots(cr, uid, product_id=move.product_id.id, location_id=move.location_id.id, context=context) # Auto assign based on available Production Lots _req_qty = move.product_qty if (_move_uom != _prod_uom): # Required Quantity is converted into Product's UOM for ease of calculation _req_qty = uom_obj._compute_qty(cr, uid, _move_uom, _req_qty, _prod_uom) _first = True for _lot_info in _res: if _req_qty <= 0: # Till required quantity is fulfilled break _pl_id = _lot_info.get('prodlot_id', False) _lot_qty = _lot_info.get('qty', 0.0) _qty_to_consume = min(_req_qty, _lot_qty) # Only consume if there is quantity to consume if _qty_to_consume: _update_val = { 'prodlot_id': _pl_id, 'product_qty': _qty_to_consume, } if _first: _first = False # Quantity from first lot is logged to the move move.write(_update_val, context=context) else: # Quantity from subsequent lots is logged in different move move_data = move_vals.copy() move_data.update(_update_val) stock_move_obj.create(cr, uid, move_data, context=context) _req_qty -= _qty_to_consume if _req_qty > 0 and not _first: # Create one last move without Production Lot if this is not the first # Don't change anything if it is the first _update_val = { 'prodlot_id': False, 'product_qty': _req_qty, } move_data = move_vals.copy() move_data.update(_update_val) stock_move_obj.create(cr, uid, move_data, context=context) return result
def onchange_get_lines(self, cr, uid, ids, date, opp_acc_id, journal_id, context=None): _aml_pool = self.pool.get('account.move.line') _move_lines = _aml_pool.search(cr, uid, [('date', '=', date), ('account_id', '=', opp_acc_id), ('journal_id', '=', journal_id), ('reconcile_id', '=', False)], context=context) # It is assumed that only one record is changed at a time _bank_lines = [] _assignment_lines = [] _bank_m2olines = [] _bank_mlines = {} _vexv = False if ids: _vexv = self.pool.get('via.expense.voucher').browse( cr, uid, ids[0], context=context) _assignment_lines = map(lambda x: x.id, _vexv.assignment_lines) for _line in _vexv.bank_lines: _bank_mlines[_line.move_line_id.id] = _line.id _aaml_pool = self.pool.get('via.account.move.line') for _line in _move_lines: if _line in _bank_mlines: _bank_lines.append(_bank_mlines[_line]) _bank_m2olines.append((1, _bank_mlines[_line], {})) else: if ids and _vexv: _new_line = _aaml_pool.create( cr, uid, { 'exp_voucher_id': _vexv.id, 'move_line_id': _line }, context=context) _bank_lines.append(_new_line) _bank_m2olines.append((1, _new_line, {})) else: _aml = _aml_pool.browse(cr, uid, _line, context=context) if _aml: _aml_data = _aml.read()[0] for _key in [ 'id', 'create_uid', 'create_date', 'write_uid', 'write_date', 'amount_residual' ]: if _key in _vals: del _vals[_key] _aml_data = prep_dict_for_write(cr, uid, _aml_data, context=context) _aml_data['move_line_id'] = _line _aml_data[ 'amount_residual'] = _aml.signed_amount_residual _aml_data[ 'amount_to_use'] = _aml.signed_amount_residual rv['value'].update(_aml_data) _bank_lines.append(_aml_data) _bank_m2olines.append((1, False, _aml_data)) rv = self.onchange_lines(cr, uid, ids, _bank_m2olines, _assignment_lines, context=context) rv['value']['bank_lines'] = _bank_lines return rv