def remove_done_moves(self): """Splits the given procs creating a copy with the qty of their done moves and set to done. """ for procurement in self: if procurement.rule_id.action == 'move': qty_done = sum([ move.product_qty for move in procurement.move_ids if move.state == 'done' ]) qty_done_proc_uom = self.env['product.uom']. \ _compute_qty_obj(procurement.product_id.uom_id, qty_done, procurement.product_uom) if procurement.product_uos: qty_done_proc_uos = float_round( self.env['product.uom']._compute_qty_obj( procurement.product_id.uom_id, qty_done, procurement.product_uos), precision_rounding=procurement.product_uos.rounding) else: qty_done_proc_uos = float_round( qty_done_proc_uom, precision_rounding=procurement.product_uom.rounding) if float_compare(qty_done, 0.0, precision_rounding=procurement.product_id. uom_id.rounding) > 0: procurement.write({ 'product_qty': float_round(qty_done_proc_uom, precision_rounding=procurement.product_uom. rounding), 'product_uos_qty': qty_done_proc_uos, })
def update_clean_parsed_inv(self, parsed_inv): prec_ac = self.env['decimal.precision'].precision_get('Account') prec_pp = self.env['decimal.precision'].precision_get('Product Price') prec_uom = self.env['decimal.precision'].precision_get( 'Product Unit of Measure') if 'amount_tax' in parsed_inv and 'amount_untaxed' not in parsed_inv: parsed_inv['amount_untaxed'] =\ parsed_inv['amount_total'] - parsed_inv['amount_tax'] elif ('amount_untaxed' not in parsed_inv and 'amount_tax' not in parsed_inv): # For invoices that never have taxes parsed_inv['amount_untaxed'] = parsed_inv['amount_total'] if float_compare(parsed_inv['amount_total'], 0, precision_digits=prec_ac) == -1: parsed_inv['type'] = 'in_refund' else: parsed_inv['type'] = 'in_invoice' for entry in ['amount_untaxed', 'amount_total']: parsed_inv[entry] = float_round(parsed_inv[entry], precision_digits=prec_ac) if parsed_inv['type'] == 'in_refund': parsed_inv[entry] *= -1 if parsed_inv.get('lines'): for line in parsed_inv['lines']: line['qty'] = float_round(line['qty'], precision_digits=prec_uom) line['price_unit'] = float_round(line['price_unit'], precision_digits=prec_pp) if parsed_inv['type'] == 'in_refund': line['qty'] *= -1 if 'chatter_msg' not in parsed_inv: parsed_inv['chatter_msg'] = [] logger.debug('Resulf of invoice parsing parsed_inv=%s', parsed_inv) return parsed_inv
def _compute_red_zone(self): for rec in self: rec.red_base_qty = float_round( rec.dlt * rec.adu * rec.buffer_profile_id.lead_time_id.factor, precision_rounding=rec.product_uom.rounding) rec.red_safety_qty = float_round( rec.red_base_qty * rec.buffer_profile_id.variability_id.factor, precision_rounding=rec.product_uom.rounding) rec.red_zone_qty = rec.red_base_qty + rec.red_safety_qty
def process_not_reserved_tuples(self, list_reservations, move_recordset, new_picking, location_from, dest_location, picking_type_id): not_reserved_tuples = [item for item in list_reservations if not item[0].reservation_id] if not_reserved_tuples: done_move_ids = move_recordset.ids dict_reservations = {} force_domain = [('id', 'not in', done_move_ids)] first_corresponding_move = self.get_corresponding_moves(not_reserved_tuples[0][0], location_from, dest_location, picking_type_id, force_domain=force_domain, limit=1) while not_reserved_tuples and first_corresponding_move: prec = first_corresponding_move.product_id.uom_id.rounding if not dict_reservations.get(first_corresponding_move): dict_reservations[first_corresponding_move] = [] quant = not_reserved_tuples[0][0] qty = not_reserved_tuples[0][1] first_corresponding_move.do_unreserve() qty_reserved_on_move = sum([tpl[1] for tpl in dict_reservations[first_corresponding_move]]) # If the current move can exactly assume the new reservation, # we reserve the quants and pass to the next one if float_compare(qty_reserved_on_move + qty, first_corresponding_move.product_qty, precision_rounding=prec) == 0: dict_reservations[first_corresponding_move] += [(quant, qty)] done_move_ids += [first_corresponding_move.id] # If the current move can assume more than the new reservation, # we reserve the quants and stay on this move elif float_compare(qty_reserved_on_move + qty, first_corresponding_move.product_qty, precision_rounding=prec) < 0: dict_reservations[first_corresponding_move] += [(quant, qty)] # If the current move can not assume the new reservation, we split the quant else: reservable_qty_on_move = first_corresponding_move.product_qty - qty_reserved_on_move splitted_quant = self.env['stock.quant']._quant_split(quant, float_round(reservable_qty_on_move, precision_rounding=prec)) dict_reservations[first_corresponding_move] += [(quant, quant.qty)] not_reserved_tuples += [(splitted_quant, float_round(qty - reservable_qty_on_move, precision_rounding=prec))] done_move_ids += [first_corresponding_move.id] move_recordset |= first_corresponding_move force_domain = [('id', 'not in', done_move_ids)] first_corresponding_move = self.get_corresponding_moves(quant, location_from, dest_location, picking_type_id, limit=1, force_domain=force_domain) not_reserved_tuples = not_reserved_tuples[1:] # Let's split the move which are not entirely_used for move in dict_reservations: prec = move.product_id.uom_id.rounding qty_reserved = sum([tpl[1] for tpl in dict_reservations[move]]) if float_compare(qty_reserved, move.product_qty, precision_rounding=prec) < 0: move.split(move, float_round(move.product_qty - qty_reserved, precision_rounding=prec)) # Let's reserve the quants for move in dict_reservations: move.picking_id = new_picking self.quants_reserve(dict_reservations[move], move) return move_recordset, not_reserved_tuples
def _get_price(self, pricelist_id, product_id, qty): sale_price_digits = self.get_digits(dp='Product Price') pricelist = self.pool.get('product.pricelist').browse(self.cr, self.uid, [pricelist_id], context=self.localcontext)[0] price_dict = self.pool.get('product.pricelist').price_get(self.cr, self.uid, [pricelist_id], product_id, qty, context=self.localcontext) if price_dict[pricelist_id]: price = float_round(price_dict[pricelist_id], precision_digits=sale_price_digits) else: res = self.pool.get('product.product').read(self.cr, self.uid, [product_id], ['list_price']) price = float_round(res[0]['list_price'], precision_digits=sale_price_digits) price = self.formatLang(price, digits=sale_price_digits, currency_obj=pricelist.currency_id) return price
def _check_order_confirm(self): if self.state == 'confirmed': lines = self.order_line.mapped('cotizaciones_linea_id').ids contracts = self.env['grp.contrato.proveedores'].search([ ('nro_line_adj_id', 'in', lines), ('contrato_general_id', '!=', False) ]) for contract in contracts: if float_round(contract.total_oc, 2) > float_round( contract.total_ajustado, 2): raise ValidationError( u'No puede confirmar la orden de compra, el total en OC es mayor que el total contratado ajustado' )
def _amount_all(self, cr, uid, ids, name, args, context=None): res = {} cur_obj = self.pool.get('res.currency') for apu in self.browse(cr, uid, ids, context=context): nro_decimal = 10 ** -apu.nro_decimal #print 'nro_decimal', nro_decimal res[apu.id] = { 'amount_equipo': 0.0, 'porcentage_equipo':0.0, 'amount_material': 0.0, 'amount_transporte': 0.0, 'amount_obra': 0.0, 'amount_equipo2': 0.0, 'amount_material2': 0.0, 'amount_transporte2': 0.0, 'amount_obra2': 0.0, 'amount_otros':0.00, 'amount_otros2':0.00 } #float_round(amount, precision_rounding=currency.rounding) cur = 7 #Escenario 1 for line in apu.equipo_ids: res[apu.id]['amount_equipo'] += float_round(line.qty * line.price * line.rendimiento,precision_rounding=nro_decimal) for line in apu.materiales_ids: res[apu.id]['amount_material'] += float_round(line.qty * line.price,precision_rounding=nro_decimal) for line in apu.transporte_ids: res[apu.id]['amount_transporte'] += float_round(line.qty * line.price,precision_rounding=nro_decimal) for line in apu.mano_obra_ids: res[apu.id]['amount_obra'] += float_round(line.qty * line.price * line.rendimiento,precision_rounding=nro_decimal) for line in apu.otros_ids: res[apu.id]['amount_otros'] += float_round(line.qty * line.price,precision_rounding=nro_decimal) #res[apu.id]['amount_total']= res[apu.id]['amount_equipo'] + res[apu.id]['amount_material'] +res[apu.id]['amount_transporte']+res[apu.id]['amount_obra'] #Escenario 2 for line in apu.equipo2_ids: res[apu.id]['amount_equipo2'] += float_round(line.qty * line.price *line.rendimiento ,precision_rounding=nro_decimal) for line in apu.materiales2_ids: res[apu.id]['amount_material2'] += float_round(line.qty * line.price,precision_rounding=nro_decimal) for line in apu.transporte2_ids: res[apu.id]['amount_transporte2'] += float_round(line.qty * line.price,precision_rounding=nro_decimal) for line in apu.mano_obra2_ids: res[apu.id]['amount_obra2'] += float_round(line.qty * line.price *line.rendimiento,precision_rounding=nro_decimal) for line in apu.otros2_ids: res[apu.id]['amount_otros2'] += float_round(line.qty * line.price,precision_rounding=nro_decimal) #print 'ampount_all', res return res
def __init__(self, depreciation_date, base_value, depreciation_value, accumulated_value, book_value, exceptional_value=0.0, book_value_wo_exceptional=0.0, readonly=False, rounding=2, **optional_args): self.depreciation_date = depreciation_date self.base_value = float_round(base_value, precision_digits=rounding) self.depreciation_value = float_round(depreciation_value, precision_digits=rounding) self.accumulated_value = float_round(accumulated_value, precision_digits=rounding) self.book_value = float_round(book_value, precision_digits=rounding) self.exceptional_value = float_round(exceptional_value, precision_digits=rounding) self.book_value_wo_exceptional = float_round(book_value_wo_exceptional or book_value, precision_digits=rounding) self.readonly = readonly self.current_year_accumulated_value = float_round( optional_args.get('current_year_accumulated_value', self.depreciation_value + self.exceptional_value), precision_digits=rounding) self.previous_years_accumulated_value = float_round( optional_args.get( 'previous_years_accumulated_value', self.accumulated_value - self.depreciation_value + self.book_value_wo_exceptional - self.book_value - self.exceptional_value), precision_digits=rounding)
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False, lazy=True): context = context or {} res = super(account_move_line, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby, lazy=lazy) if context.get('include_initial_bal', False) and ('initial_bal' in fields or 'curr_initial_bal' in fields): precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account') for line in res: lines = self.search(cr, uid, line.get('__domain', domain), context=context) lines_rec = self.browse(cr, uid, lines, context=context) if 'initial_bal' in fields: line['initial_bal'] = sum(line_rec.initial_bal for line_rec in lines_rec) line['initial_bal'] = float_round(line['initial_bal'], precision_digits=precision) if 'curr_initial_bal' in fields: line['curr_initial_bal'] = sum(line_rec.curr_initial_bal for line_rec in lines_rec) line['curr_initial_bal'] = float_round(line['curr_initial_bal'], precision_digits=precision) return res
def compute_inv(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None, precision=None): if not precision: precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account') res = self._unit_compute_inv(cr, uid, taxes, price_unit, product, partner=None) total = 0.0 accuracy = 4 for r in res: if r.get('balance',False): #r['amount'] = round(r['balance'] * quantity, precision) - total r['amount'] = float_round(r['balance'] * quantity, accuracy) - total else: #r['amount'] = round(r['amount'] * quantity, precision) r['amount'] = float_round(r['amount'] * quantity, accuracy) total += r['amount'] return res
def adyen_form_generate_values(self, cr, uid, id, values, context=None): base_url = self.pool['ir.config_parameter'].get_param( cr, uid, 'web.base.url') acquirer = self.browse(cr, uid, id, context=context) # tmp import datetime from dateutil import relativedelta tmp_date = datetime.date.today() + relativedelta.relativedelta(days=1) values.update({ 'merchantReference': values['reference'], 'paymentAmount': '%d' % int(float_round(values['amount'], 2) * 100), 'currencyCode': values['currency'] and values['currency'].name or '', 'shipBeforeDate': tmp_date, 'skinCode': acquirer.adyen_skin_code, 'merchantAccount': acquirer.adyen_merchant_account, 'shopperLocale': values.get('partner_lang'), 'sessionValidity': tmp_date, 'resURL': '%s' % urlparse.urljoin(base_url, AdyenController._return_url), 'merchantReturnData': json.dumps({'return_url': '%s' % values.pop('return_url')}) if values.get('return_url') else False, 'merchantSig': self._adyen_generate_merchant_sig(acquirer, 'in', values), }) return values
def adyen_form_generate_values(self, cr, uid, id, partner_values, tx_values, context=None): base_url = self.pool["ir.config_parameter"].get_param(cr, uid, "web.base.url") acquirer = self.browse(cr, uid, id, context=context) # tmp import datetime from dateutil import relativedelta tmp_date = datetime.date.today() + relativedelta.relativedelta(days=1) adyen_tx_values = dict(tx_values) adyen_tx_values.update( { "merchantReference": tx_values["reference"], "paymentAmount": "%d" % int(float_round(tx_values["amount"], 2) * 100), "currencyCode": tx_values["currency"] and tx_values["currency"].name or "", "shipBeforeDate": tmp_date, "skinCode": acquirer.adyen_skin_code, "merchantAccount": acquirer.adyen_merchant_account, "shopperLocale": partner_values["lang"], "sessionValidity": tmp_date, "resURL": "%s" % urlparse.urljoin(base_url, AdyenController._return_url), } ) if adyen_tx_values.get("return_url"): adyen_tx_values["merchantReturnData"] = json.dumps({"return_url": "%s" % adyen_tx_values.pop("return_url")}) adyen_tx_values["merchantSig"] = self._adyen_generate_merchant_sig(acquirer, "in", adyen_tx_values) return partner_values, adyen_tx_values
def _get_remaining_qty(self, cr, uid, ids, field_name, arg, context=None): res = {} if 'no_recompute_rar' not in context: for line in self.browse(cr, uid, ids, context=context): res[line.id] = 0 if line.product_id and line.product_id.type != 'service': cr.execute( """SELECT sum(sm.product_qty) FROM purchase_order_line pol LEFT JOIN stock_move sm ON sm.purchase_line_id = pol.id AND sm.state = 'done' AND sm.origin_returned_move_id IS NULL WHERE pol.id = %s""", (line.id, )) delivered_qty = cr.fetchall()[0][0] or 0 delivered_qty_pol_uom = self.pool.get('product.uom'). \ _compute_qty(cr, uid, line.product_id.uom_id.id, delivered_qty, line.product_uom.id) cr.execute( """SELECT sum(sm.product_qty) FROM purchase_order_line pol LEFT JOIN stock_move sm ON sm.purchase_line_id = pol.id AND sm.state = 'done' AND sm.origin_returned_move_id IS NOT NULL WHERE pol.id = %s""", (line.id, )) returned_qty = cr.fetchall()[0][0] or 0 returned_qty_pol_uom = self.pool.get('product.uom'). \ _compute_qty(cr, uid, line.product_id.uom_id.id, returned_qty, line.product_uom.id) res[line.id] = float_round( line.product_qty - delivered_qty_pol_uom + returned_qty_pol_uom, precision_rounding=line.product_uom.rounding) if res[line.id] == line.remaining_qty: del res[line.id] return res
def determine_list_reservations(self, product, move_items): move_tuples = move_items[product] prec = product.uom_id.rounding list_reservations = [] for move_tuple in move_tuples: qty_reserved = 0 qty_to_reserve = move_tuple['qty'] for quant in move_tuple['quants']: # If the new quant does not exceed the requested qty, we move it (end of loop) and continue # If requested qty is reached, we break the loop if float_compare(qty_reserved, qty_to_reserve, precision_rounding=prec) >= 0: break # If the new quant exceeds the requested qty, we reserve the good qty and then break elif float_compare(qty_reserved + quant.qty, qty_to_reserve, precision_rounding=prec) > 0: list_reservations += [ (quant, float_round(qty_to_reserve - qty_reserved, precision_rounding=prec)) ] break list_reservations += [(quant, quant.qty)] qty_reserved += quant.qty return list_reservations
def ogone_form_generate_values(self, cr, uid, id, partner_values, tx_values, context=None): base_url = self.pool["ir.config_parameter"].get_param(cr, uid, "web.base.url") acquirer = self.browse(cr, uid, id, context=context) ogone_tx_values = dict(tx_values) temp_ogone_tx_values = { "PSPID": acquirer.ogone_pspid, "ORDERID": tx_values["reference"], "AMOUNT": float_repr(float_round(tx_values["amount"], 2) * 100, 0), "CURRENCY": tx_values["currency"] and tx_values["currency"].name or "", "LANGUAGE": partner_values["lang"], "CN": partner_values["name"], "EMAIL": partner_values["email"], "OWNERZIP": partner_values["zip"], "OWNERADDRESS": partner_values["address"], "OWNERTOWN": partner_values["city"], "OWNERCTY": partner_values["country"] and partner_values["country"].code or "", "OWNERTELNO": partner_values["phone"], "ACCEPTURL": "%s" % urlparse.urljoin(base_url, OgoneController._accept_url), "DECLINEURL": "%s" % urlparse.urljoin(base_url, OgoneController._decline_url), "EXCEPTIONURL": "%s" % urlparse.urljoin(base_url, OgoneController._exception_url), "CANCELURL": "%s" % urlparse.urljoin(base_url, OgoneController._cancel_url), } if tx_values.get("type") == "form_save": temp_ogone_tx_values.update( { "ALIAS": "ODOO-NEW-ALIAS-%s" % time.time(), # something unique, "ALIASUSAGE": tx_values.get("alias_usage") or acquirer.ogone_alias_usage, } ) if ogone_tx_values.get("return_url"): temp_ogone_tx_values["PARAMPLUS"] = "return_url=%s" % ogone_tx_values.pop("return_url") shasign = self._ogone_generate_shasign(acquirer, "in", temp_ogone_tx_values) temp_ogone_tx_values["SHASIGN"] = shasign ogone_tx_values.update(temp_ogone_tx_values) return partner_values, ogone_tx_values
def _ubl_add_tax_subtotal(self, taxable_amount, tax_amount, tax, currency_code, parent_node, ns, version='2.1'): prec = self.env['decimal.precision'].precision_get('Account') tax_subtotal = etree.SubElement(parent_node, ns['cac'] + 'TaxSubtotal') if not float_is_zero(taxable_amount, precision_digits=prec): taxable_amount_node = etree.SubElement(tax_subtotal, ns['cbc'] + 'TaxableAmount', currencyID=currency_code) taxable_amount_node.text = unicode(taxable_amount) tax_amount_node = etree.SubElement(tax_subtotal, ns['cbc'] + 'TaxAmount', currencyID=currency_code) tax_amount_node.text = unicode(tax_amount) if (tax.type == 'percent' and not float_is_zero(tax.amount, precision_digits=prec + 3)): percent = etree.SubElement(tax_subtotal, ns['cbc'] + 'Percent') percent.text = unicode( float_round(tax.amount * 100, precision_digits=2)) self._ubl_add_tax_category(tax, tax_subtotal, ns, version=version)
def _ubl_add_invoice_line_tax_total(self, iline, parent_node, ns, version='2.1'): cur_name = self.currency_id.name prec = self.env['decimal.precision'].precision_get('Account') tax_total_node = etree.SubElement(parent_node, ns['cac'] + 'TaxTotal') price = iline.price_unit * (1 - (iline.discount or 0.0) / 100.0) res_taxes = iline.invoice_line_tax_id.compute_all( price, iline.quantity, product=iline.product_id, partner=self.partner_id) tax_total = float_round(res_taxes['total_included'] - res_taxes['total'], precision_digits=prec) tax_amount_node = etree.SubElement(tax_total_node, ns['cbc'] + 'TaxAmount', currencyID=cur_name) tax_amount_node.text = unicode(tax_total) for res_tax in res_taxes['taxes']: tax = self.env['account.tax'].browse(res_tax['id']) # we don't have the base amount in res_tax :-( self._ubl_add_tax_subtotal(False, res_tax['amount'], tax, cur_name, tax_total_node, ns, version=version)
def split_and_reserve_moves_ok(self, list_reservations, move_recordset, new_picking): processed_moves = move_recordset for quant_tuple in list_reservations: prec = quant_tuple[0].product_id.uom_id.rounding current_reservation = quant_tuple[0].reservation_id # We split moves matching requirements using the list of reservations if current_reservation and current_reservation not in processed_moves: quant_tuples_current_reservation = [ tpl for tpl in list_reservations if tpl[0].reservation_id == current_reservation ] current_reservation.do_unreserve() final_qty = sum( [tpl[1] for tpl in quant_tuples_current_reservation]) # Split move if needed if float_compare(final_qty, current_reservation.product_uom_qty, precision_rounding=prec) < 0: current_reservation.split( current_reservation, float_round(current_reservation.product_uom_qty - final_qty, precision_rounding=prec)) # Reserve quants on move self.quants_reserve(quant_tuples_current_reservation, current_reservation) # Assign the current move to the new picking current_reservation.picking_id = new_picking move_recordset |= current_reservation processed_moves |= current_reservation return move_recordset
def _compute_theoretical_multi(self): for template in self: classification = template.margin_classification_id if classification: multi = 1 + (classification.margin / 100) temp_vat = template.taxes_id.compute_all( template.standard_price * multi, 1, inverce=False)['total_included'] temp_price = tools.float_round( temp_vat, precision_rounding=classification.price_round) +\ classification.price_surcharge _logger.info( "New price with VAT %s:%s:%s:%s" % (multi, template.standard_price, temp_price, temp_vat)) else: temp_price = template.taxes_id.compute_all( template.list_price, 1, inverce=False)['total_included'] difference = (template.list_price - template.taxes_id.compute_all( temp_price, 1, inverce=True)['total_included']) if max(difference, -difference) < 10**-9: difference = 0 template.theoretical_difference = difference if difference < 0: template.margin_state = 'cheap' elif difference > 0: template.margin_state = 'expensive' else: template.margin_state = 'ok' template.theoretical_price = temp_price
def ogone_form_generate_values(self, cr, uid, id, values, context=None): base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url') acquirer = self.browse(cr, uid, id, context=context) ogone_tx_values = dict(values) temp_ogone_tx_values = { 'PSPID': acquirer.ogone_pspid, 'ORDERID': values['reference'], 'AMOUNT': float_repr(float_round(values['amount'], 2) * 100, 0), 'CURRENCY': values['currency'] and values['currency'].name or '', 'LANGUAGE': values.get('partner_lang'), 'CN': values.get('partner_name'), 'EMAIL': values.get('partner_email'), 'OWNERZIP': values.get('partner_zip'), 'OWNERADDRESS': values.get('partner_address'), 'OWNERTOWN': values.get('partner_city'), 'OWNERCTY': values.get('partner_country') and values.get('partner_country').code or '', 'OWNERTELNO': values.get('partner_phone'), 'ACCEPTURL': '%s' % urlparse.urljoin(base_url, OgoneController._accept_url), 'DECLINEURL': '%s' % urlparse.urljoin(base_url, OgoneController._decline_url), 'EXCEPTIONURL': '%s' % urlparse.urljoin(base_url, OgoneController._exception_url), 'CANCELURL': '%s' % urlparse.urljoin(base_url, OgoneController._cancel_url), 'PARAMPLUS': 'return_url=%s' % ogone_tx_values.pop('return_url') if ogone_tx_values.get('return_url') else False, } if values.get('type') == 'form_save': temp_ogone_tx_values.update({ 'ALIAS': 'ODOO-NEW-ALIAS-%s' % time.time(), # something unique, 'ALIASUSAGE': values.get('alias_usage') or acquirer.ogone_alias_usage, }) shasign = self._ogone_generate_shasign(acquirer, 'in', temp_ogone_tx_values) temp_ogone_tx_values['SHASIGN'] = shasign ogone_tx_values.update(temp_ogone_tx_values) return ogone_tx_values
def _compute_theoretical_multi(self): for template in self: classification = template.margin_classification_id if classification: multi = 1 + (classification.margin / 100) for tax in template.taxes_id: if tax.amount_type != 'percent' or not tax.price_include: raise exceptions.UserError( _("Unimplemented Feature\n" "The Tax %s is not correctly set for computing" " prices with coefficients for the product %s") % (tax.name, template.name)) multi *= 1 + (tax.amount / 100) template.theoretical_price = tools.float_round( template.standard_price * multi, precision_rounding=classification.price_round) +\ classification.price_surcharge else: template.theoretical_price = template.list_price difference = (template.list_price - template.theoretical_price) if max(difference, -difference) < 10**-9: difference = 0 template.theoretical_difference = difference if difference < 0: template.margin_state = 'cheap' elif difference > 0: template.margin_state = 'expensive' else: template.margin_state = 'ok'
def move_quants_old_school(self, list_reservation, move_recordset, dest_location, picking_type_id, new_picking): values = self.env['stock.quant'].read_group([('id', 'in', self.ids)], ['product_id', 'location_id', 'qty'], ['product_id', 'location_id'], lazy=False) for val in values: uom = self.env['product.product'].search([('id', '=', val['product_id'][0])]).uom_id new_move = self.env['stock.move'].with_context(mail_notrack=True).create({ 'name': 'Move %s to %s' % (val['product_id'][1], dest_location.name), 'product_id': val['product_id'][0], 'location_id': val['location_id'][0], 'location_dest_id': dest_location.id, 'product_uom_qty': float_round(val['qty'], precision_rounding=uom.rounding), 'product_uom': uom.id, 'date_expected': fields.Datetime.now(), 'date': fields.Datetime.now(), 'picking_type_id': picking_type_id.id, 'picking_id': new_picking.id, }) quants = self.env['stock.quant'].search([('id', 'in', self.ids), ('product_id', '=', val['product_id'][0])]) qties = quants.read(['id', 'qty']) list_reservation[new_move] = [] for qty in qties: list_reservation[new_move].append((self.env['stock.quant'].search( [('id', '=', qty['id'])]), qty['qty'])) move_recordset = move_recordset | new_move return list_reservation, move_recordset
def _make_calculations_for_create_procurement( self, cr, uid, prods, op, use_new_cursor, context=None): procurement_obj = self.pool['procurement.order'] orderpoint_obj = self.pool['stock.warehouse.orderpoint'] result = float_compare(prods, op.product_min_qty, precision_rounding=op.product_uom.rounding) if result < 0: qty = (max(op.product_min_qty, op.product_max_qty) - prods) reste = (op.qty_multiple > 0 and qty % op.qty_multiple or 0.0) result = float_compare(reste, 0.0, precision_rounding=op.product_uom.rounding) if result > 0: qty += op.qty_multiple - reste result = float_compare(qty, 0.0, precision_rounding=op.product_uom.rounding) if result > 0: qty -= orderpoint_obj.subtract_procurements( cr, uid, op, context=context) qty_rounded = float_round( qty, precision_rounding=op.product_uom.rounding) if qty_rounded > 0: vals = self._prepare_orderpoint_procurement( cr, uid, op, qty_rounded, context=context) proc_id = procurement_obj.create( cr, uid, vals, context=context) self.check(cr, uid, [proc_id]) self.run(cr, uid, [proc_id]) if use_new_cursor: cr.commit()
def determine_list_reservations(self, product, move_tuples): prec = product.uom_id.rounding list_reservations = [] for move_tuple in move_tuples: qty_reserved = 0 qty_to_reserve = move_tuple['qty'] quants = self.env['stock.quant'].search( [('id', 'in', move_tuple['quant_ids'])], order='qty asc, id asc') for quant in quants: quant_read = quant.read(['id', 'qty'], load=False)[0] # If the new quant does not exceed the requested qty, we move it (end of loop) and continue # If requested qty is reached, we break the loop if float_compare(qty_reserved, qty_to_reserve, precision_rounding=prec) >= 0: break # If the new quant exceeds the requested qty, we reserve the good qty and then break elif float_compare(qty_reserved + quant_read['qty'], qty_to_reserve, precision_rounding=prec) > 0: list_reservations += [ (quant, float_round(qty_to_reserve - qty_reserved, precision_rounding=prec)) ] break list_reservations += [(quant, quant_read['qty'])] qty_reserved += quant_read['qty'] return list_reservations
def create_account_payment(self): self.ensure_one() if self.acquirer_id.payment_term_id: totlines = self.acquirer_id.payment_term_id.with_context( currency_id=self.currency_id.id ).compute( float_round(self.amount, 2), fields.Date.context_today(self) )[0] for payment_date, amount in sorted(totlines): self.env['account.payment'].create({ 'payment_date': payment_date, 'payment_type': 'inbound', 'amount': amount, 'currency_id': self.currency_id.id, 'journal_id': self.acquirer_id.journal_id.id, 'partner_type': 'customer', 'partner_id': self.partner_id.id, 'payment_reference': self.reference, 'payment_method_id': self.env.ref('account.account_payment_method_manual_in').id, 'transaction_id': self.id, }).post() else: super(PaymentTransaction, self).create_account_payment() return True
def _compute_total_entry_encoding(self): for rec in self: _in_amount = sum(rec.transaction_ids.filtered(lambda x:x.rounded_amount >= 0).mapped('rounded_amount'),0.0) _out_amount = sum(rec.transaction_ids.filtered(lambda x:x.rounded_amount < 0).mapped('rounded_amount'),0.0) rec.in_amount = abs(_in_amount) rec.out_amount = abs(_out_amount) rec.total_entry_encoding = float_round(_in_amount + _out_amount, 0)
def write(self, cr, uid, ids, values, context=None): Acquirer = self.pool['payment.acquirer'] if ('acquirer_id' in values or 'amount' in values) and 'fees' not in values: # The acquirer or the amount has changed, and the fees are not explicitely forced. Fees must be recomputed. if isinstance(ids, (int, long)): ids = [ids] for txn_id in ids: vals = dict(values) vals['fees'] = 0.0 transaction = self.browse(cr, uid, txn_id, context=context) if 'acquirer_id' in values: acquirer = Acquirer.browse(cr, uid, values['acquirer_id'], context=context) if values['acquirer_id'] else None else: acquirer = transaction.acquirer_id if acquirer: custom_method_name = '%s_compute_fees' % acquirer.provider if hasattr(Acquirer, custom_method_name): amount = (values['amount'] if 'amount' in values else transaction.amount) or 0.0 currency_id = values.get('currency_id') or transaction.currency_id.id country_id = values.get('partner_country_id') or transaction.partner_country_id.id fees = getattr(Acquirer, custom_method_name)(cr, uid, acquirer.id, amount, currency_id, country_id, context=None) vals['fees'] = float_round(fees, 2) res = super(PaymentTransaction, self).write(cr, uid, txn_id, vals, context=context) return res return super(PaymentTransaction, self).write(cr, uid, ids, values, context=context)
def create(self, cr, uid, values, context=None): Acquirer = self.pool["payment.acquirer"] if values.get("partner_id"): # @TDENOTE: not sure values.update(self.on_change_partner_id(cr, uid, None, values.get("partner_id"), context=context)["values"]) # call custom create method if defined (i.e. ogone_create for ogone) if values.get("acquirer_id"): acquirer = self.pool["payment.acquirer"].browse(cr, uid, values.get("acquirer_id"), context=context) # compute fees custom_method_name = "%s_compute_fees" % acquirer.provider if hasattr(Acquirer, custom_method_name): fees = getattr(Acquirer, custom_method_name)( cr, uid, acquirer.id, values.get("amount", 0.0), values.get("currency_id"), values.get("country_id"), context=None, ) values["fees"] = float_round(fees, 2) # custom create custom_method_name = "%s_create" % acquirer.provider if hasattr(self, custom_method_name): values.update(getattr(self, custom_method_name)(cr, uid, values, context=context)) return super(PaymentTransaction, self).create(cr, uid, values, context=context)
def create(self, cr, uid, values, context=None): Acquirer = self.pool['payment.acquirer'] if values.get('partner_id'): # @TDENOTE: not sure values.update(self.on_change_partner_id(cr, uid, None, values.get('partner_id'), context=context)['value']) # call custom create method if defined (i.e. ogone_create for ogone) if values.get('acquirer_id'): acquirer = self.pool['payment.acquirer'].browse(cr, uid, values.get('acquirer_id'), context=context) # compute fees custom_method_name = '%s_compute_fees' % acquirer.provider if hasattr(Acquirer, custom_method_name): fees = getattr(Acquirer, custom_method_name)( cr, uid, acquirer.id, values.get('amount', 0.0), values.get('currency_id'), values.get('partner_country_id'), context=None) values['fees'] = float_round(fees, 2) # custom create custom_method_name = '%s_create' % acquirer.provider if hasattr(self, custom_method_name): values.update(getattr(self, custom_method_name)(cr, uid, values, context=context)) # Default value of reference is tx_id = super(PaymentTransaction, self).create(cr, uid, values, context=context) if not values.get('reference'): self.write(cr, uid, [tx_id], {'reference': str(tx_id)}, context=context) return tx_id
def partial_move(self, move_items, product, qty): if not move_items.get(product.id): move_items[product.id] = [] move_items[product.id] += [{ 'quant_ids': self.ids, 'qty': float_round(qty, precision_rounding=product.uom_id.rounding)}] return move_items
def move_remaining_quants(self, product, location_from, dest_location, picking_type_id, new_picking_id, moves_to_create): new_move = self.env['stock.move'] if moves_to_create: new_move = self.env['stock.move'].with_context( mail_notrack=True).create({ 'name': 'Move %s to %s' % (product.name, dest_location.name), 'product_id': product.id, 'location_id': location_from.id, 'location_dest_id': dest_location.id, 'product_uom_qty': float_round(sum([item[1] for item in moves_to_create]), precision_rounding=product.uom_id.rounding), 'product_uom': product.uom_id.id, 'date_expected': fields.Datetime.now(), 'date': fields.Datetime.now(), 'picking_type_id': picking_type_id, 'picking_id': new_picking_id }) new_move.action_confirm() self.quants_reserve(moves_to_create, new_move) return new_move
def _quant_create(self, cr, uid, qty, move, lot_id=False, owner_id=False, src_package_id=False, dest_package_id=False, force_location_from=False, force_location_to=False, context=None): quant_obj = self.pool.get('stock.quant') quant = super(stock_quant, self)._quant_create(cr, uid, qty, move, lot_id=lot_id, owner_id=owner_id, src_package_id=src_package_id, dest_package_id=dest_package_id, force_location_from=force_location_from, force_location_to=force_location_to, context=context) if move.product_id.valuation == 'real_time': self._account_entry_move(cr, uid, [quant], move, context) # If the precision required for the variable quant cost is larger than the accounting # precision, inconsistencies between the stock valuation and the accounting entries # may arise. # For example, a box of 13 units is bought 15.00. If the products leave the # stock one unit at a time, the amount related to the cost will correspond to # round(15/13, 2)*13 = 14.95. To avoid this case, we split the quant in 12 + 1, then # record the difference on the new quant. # We need to make sure to able to extract at least one unit of the product. There is # an arbitrary minimum quantity set to 2.0 from which we consider we can extract a # unit and adapt the cost. curr_rounding = move.company_id.currency_id.rounding cost_rounded = float_round(quant.cost, precision_rounding=curr_rounding) cost_correct = cost_rounded if float_compare(quant.product_id.uom_id.rounding, 1.0, precision_digits=1) == 0\ and float_compare(quant.qty * quant.cost, quant.qty * cost_rounded, precision_rounding=curr_rounding) != 0\ and float_compare(quant.qty, 2.0, precision_rounding=quant.product_id.uom_id.rounding) >= 0: qty = quant.qty cost = quant.cost quant_correct = quant_obj._quant_split(cr, uid, quant, quant.qty - 1.0, context=context) cost_correct += (qty * cost) - (qty * cost_rounded) quant_obj.write(cr, SUPERUSER_ID, [quant.id], {'cost': cost_rounded}, context=context) quant_obj.write(cr, SUPERUSER_ID, [quant_correct.id], {'cost': cost_correct}, context=context) return quant
def get_periodical_lines(self, board): # TODO: improve me if board.depreciation_period == 12: return [self] period_depreciation_start_date = get_period_start_date( self.depreciation_date, board.fiscalyear_start_day, 12) if period_depreciation_start_date < board.depreciation_start_date: period_depreciation_start_date = board.depreciation_start_date period_depreciation_stop_date = self.depreciation_date if board.board_stop_date and period_depreciation_stop_date > board.board_stop_date: period_depreciation_stop_date = board.board_stop_date prorata_temporis_by_period = get_prorata_temporis_by_period( period_depreciation_start_date, period_depreciation_stop_date, board.fiscalyear_start_day, board.depreciation_period) if not prorata_temporis_by_period: return [] lines = [] total = sum(prorata_temporis_by_period.values()) previous_accumulated_value = accumulated_value = self.accumulated_value - self.depreciation_value book_value_wo_exceptional = self.book_value_wo_exceptional + self.depreciation_value book_value = self.book_value_wo_exceptional + self.exceptional_value exceptional_value = gap = accumulated_value_in_period = 0.0 depreciation_number = len(prorata_temporis_by_period) for depreciation_index, depreciation_date in enumerate( sorted(prorata_temporis_by_period)): readonly_depreciation_value, readonly = self._get_readonly_value( board) depreciation_value = float_round( self.depreciation_value * prorata_temporis_by_period[depreciation_date] / total, precision_digits=board.rounding) if readonly: gap += depreciation_value - readonly_depreciation_value depreciation_value = readonly_depreciation_value elif gap: depreciation_value += gap if depreciation_index + 1 == depreciation_number: depreciation_value = self.depreciation_value - accumulated_value_in_period else: accumulated_value_in_period += depreciation_value accumulated_value += depreciation_value exceptional_value = self._get_exceptional_value(board) book_value_wo_exceptional -= depreciation_value book_value = book_value_wo_exceptional - exceptional_value vals = { 'depreciation_date': depreciation_date, 'base_value': self.base_value, 'depreciation_value': depreciation_value, 'previous_years_accumulated_value': previous_accumulated_value, 'current_year_accumulated_value': accumulated_value - previous_accumulated_value, 'accumulated_value': accumulated_value, 'exceptional_value': exceptional_value, 'book_value': book_value, 'book_value_wo_exceptional': book_value_wo_exceptional, 'rounding': board.rounding, 'readonly': readonly, } lines.append(DepreciationBoardLine(**vals)) return lines
def _quant_create_from_move(self, cr, uid, qty, move, lot_id=False, owner_id=False, src_package_id=False, dest_package_id=False, force_location_from=False, force_location_to=False, context=None): quant_obj = self.pool.get('stock.quant') quant = super(stock_quant, self)._quant_create_from_move(cr, uid, qty, move, lot_id=lot_id, owner_id=owner_id, src_package_id=src_package_id, dest_package_id=dest_package_id, force_location_from=force_location_from, force_location_to=force_location_to, context=context) quant._account_entry_move(move) if move.product_id.valuation == 'real_time': # If the precision required for the variable quant cost is larger than the accounting # precision, inconsistencies between the stock valuation and the accounting entries # may arise. # For example, a box of 13 units is bought 15.00. If the products leave the # stock one unit at a time, the amount related to the cost will correspond to # round(15/13, 2)*13 = 14.95. To avoid this case, we split the quant in 12 + 1, then # record the difference on the new quant. # We need to make sure to able to extract at least one unit of the product. There is # an arbitrary minimum quantity set to 2.0 from which we consider we can extract a # unit and adapt the cost. curr_rounding = move.company_id.currency_id.rounding cost_rounded = float_round(quant.cost, precision_rounding=curr_rounding) cost_correct = cost_rounded if float_compare(quant.product_id.uom_id.rounding, 1.0, precision_digits=1) == 0\ and float_compare(quant.qty * quant.cost, quant.qty * cost_rounded, precision_rounding=curr_rounding) != 0\ and float_compare(quant.qty, 2.0, precision_rounding=quant.product_id.uom_id.rounding) >= 0: qty = quant.qty cost = quant.cost quant_correct = quant._quant_split(quant.qty - 1.0) cost_correct += (qty * cost) - (qty * cost_rounded) quant_obj.write(cr, SUPERUSER_ID, [quant.id], {'cost': cost_rounded}, context=context) quant_obj.write(cr, SUPERUSER_ID, [quant_correct.id], {'cost': cost_correct}, context=context) return quant
def _compute_depreciation_value(self): if self.annuity_number >= self.annuities + self.need_additional_annuity: return self.book_value - self.salvage_value if self.book_value else 0.0 return float_round(self.base_value * self._compute_depreciation_rate() / 100.0 * self._get_prorata_temporis(), precision_digits=self.rounding)
def sanitize_not_available_raw_moves(self): moves_to_detach = self.env['stock.move'] for rec in self: moves_to_check = self.env['stock.move'].search([ ('id', 'in', rec.move_lines.ids), ('state', '!=', 'assigned') ]) for move in moves_to_check: prec = move.product_id.uom_id.rounding reserved_quants = move.reserved_quant_ids if not reserved_quants: moves_to_detach |= move continue reserved_qty = sum([quant.qty for quant in reserved_quants]) if float_compare(reserved_qty, move.product_qty, precision_rounding=prec) < 0: new_move_id = move.split( move, float_round(move.product_qty - reserved_qty, precision_rounding=prec)) new_move = self.env['stock.move'].search([('id', '=', new_move_id)]) move.action_assign() moves_to_detach |= new_move moves_to_detach.write({'raw_material_production_id': False}) return moves_to_detach
def ogone_form_generate_values(self, cr, uid, id, partner_values, tx_values, context=None): base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url') acquirer = self.browse(cr, uid, id, context=context) ogone_tx_values = dict(tx_values) temp_ogone_tx_values = { 'PSPID': acquirer.ogone_pspid, 'ORDERID': tx_values['reference'], 'AMOUNT': '%d' % int(float_round(tx_values['amount'], 2) * 100), 'CURRENCY': tx_values['currency'] and tx_values['currency'].name or '', 'LANGUAGE': partner_values['lang'], 'CN': partner_values['name'], 'EMAIL': partner_values['email'], 'OWNERZIP': partner_values['zip'], 'OWNERADDRESS': partner_values['address'], 'OWNERTOWN': partner_values['city'], 'OWNERCTY': partner_values['country'] and partner_values['country'].code or '', 'OWNERTELNO': partner_values['phone'], 'ACCEPTURL': '%s' % urlparse.urljoin(base_url, OgoneController._accept_url), 'DECLINEURL': '%s' % urlparse.urljoin(base_url, OgoneController._decline_url), 'EXCEPTIONURL': '%s' % urlparse.urljoin(base_url, OgoneController._exception_url), 'CANCELURL': '%s' % urlparse.urljoin(base_url, OgoneController._cancel_url), } if ogone_tx_values.get('return_url'): temp_ogone_tx_values['PARAMPLUS'] = 'return_url=%s' % ogone_tx_values.pop('return_url') shasign = self._ogone_generate_shasign(acquirer, 'in', temp_ogone_tx_values) temp_ogone_tx_values['SHASIGN'] = shasign ogone_tx_values.update(temp_ogone_tx_values) return partner_values, ogone_tx_values
def button_validate(self, cr, uid, ids, context=None): quant_obj = self.pool.get('stock.quant') for cost in self.browse(cr, uid, ids, context=context): if cost.state != 'draft': raise UserError(_('Only draft landed costs can be validated')) if not cost.valuation_adjustment_lines or not self._check_sum(cr, uid, cost, context=context): raise UserError(_('You cannot validate a landed cost which has no valid valuation adjustments lines. Did you click on Compute?')) move_id = self._create_account_move(cr, uid, cost, context=context) for line in cost.valuation_adjustment_lines: if not line.move_id: continue per_unit = line.final_cost / line.quantity diff = per_unit - line.former_cost_per_unit # If the precision required for the variable diff is larger than the accounting # precision, inconsistencies between the stock valuation and the accounting entries # may arise. # For example, a landed cost of 15 divided in 13 units. If the products leave the # stock one unit at a time, the amount related to the landed cost will correspond to # round(15/13, 2)*13 = 14.95. To avoid this case, we split the quant in 12 + 1, then # record the difference on the new quant. # We need to make sure to able to extract at least one unit of the product. There is # an arbitrary minimum quantity set to 2.0 from which we consider we can extract a # unit and adapt the cost. curr_rounding = line.move_id.company_id.currency_id.rounding diff_rounded = float_round(diff, precision_rounding=curr_rounding) diff_correct = diff_rounded quants = line.move_id.quant_ids.sorted(key=lambda r: r.qty, reverse=True) quant_correct = False if quants\ and float_compare(quants[0].product_id.uom_id.rounding, 1.0, precision_digits=1) == 0\ and float_compare(line.quantity * diff, line.quantity * diff_rounded, precision_rounding=curr_rounding) != 0\ and float_compare(quants[0].qty, 2.0, precision_rounding=quants[0].product_id.uom_id.rounding) >= 0: # Search for existing quant of quantity = 1.0 to avoid creating a new one quant_correct = quants.filtered(lambda r: float_compare(r.qty, 1.0, precision_rounding=quants[0].product_id.uom_id.rounding) == 0) if not quant_correct: quant_correct = quant_obj._quant_split(cr, uid, quants[0], quants[0].qty - 1.0, context=context) else: quant_correct = quant_correct[0] quants = quants - quant_correct diff_correct += (line.quantity * diff) - (line.quantity * diff_rounded) diff = diff_rounded quant_dict = {} for quant in quants: quant_dict[quant.id] = quant.cost + diff if quant_correct: quant_dict[quant_correct.id] = quant_correct.cost + diff_correct for key, value in quant_dict.items(): quant_obj.write(cr, SUPERUSER_ID, key, {'cost': value}, context=context) qty_out = 0 for quant in line.move_id.quant_ids: if quant.location_id.usage != 'internal': qty_out += quant.qty self._create_accounting_entries(cr, uid, line, move_id, qty_out, context=context) self.write(cr, uid, cost.id, {'state': 'done', 'account_move_id': move_id}, context=context) self.pool.get('account.move').post(cr, uid, [move_id], context=context) return True
def button_validate(self, cr, uid, ids, context=None): quant_obj = self.pool.get('stock.quant') for cost in self.browse(cr, uid, ids, context=context): if cost.state != 'draft': raise UserError(_('Only draft landed costs can be validated')) if not cost.valuation_adjustment_lines or not self._check_sum(cr, uid, cost, context=context): raise UserError(_('You cannot validate a landed cost which has no valid valuation adjustments lines. Did you click on Compute?')) move_id = self._create_account_move(cr, uid, cost, context=context) for line in cost.valuation_adjustment_lines: if not line.move_id: continue per_unit = line.final_cost / line.quantity diff = per_unit - line.former_cost_per_unit # If the precision required for the variable diff is larger than the accounting # precision, inconsistencies between the stock valuation and the accounting entries # may arise. # For example, a landed cost of 15 divided in 13 units. If the products leave the # stock one unit at a time, the amount related to the landed cost will correspond to # round(15/13, 2)*13 = 14.95. To avoid this case, we split the quant in 12 + 1, then # record the difference on the new quant. # We need to make sure to able to extract at least one unit of the product. There is # an arbitrary minimum quantity set to 2.0 from which we consider we can extract a # unit and adapt the cost. curr_rounding = line.move_id.company_id.currency_id.rounding diff_rounded = float_round(diff, precision_rounding=curr_rounding) diff_correct = diff_rounded quants = line.move_id.quant_ids.sorted(key=lambda r: r.qty, reverse=True) quant_correct = False if quants\ and float_compare(quants[0].product_id.uom_id.rounding, 1.0, precision_digits=1) == 0\ and float_compare(line.quantity * diff, line.quantity * diff_rounded, precision_rounding=curr_rounding) != 0\ and float_compare(quants[0].qty, 2.0, precision_rounding=quants[0].product_id.uom_id.rounding) >= 0: # Search for existing quant of quantity = 1.0 to avoid creating a new one quant_correct = quants.filtered(lambda r: float_compare(r.qty, 1.0, precision_rounding=quants[0].product_id.uom_id.rounding) == 0) if not quant_correct: quant_correct = quants[0]._quant_split(quants[0].qty - 1.0) else: quant_correct = quant_correct[0] quants = quants - quant_correct diff_correct += (line.quantity * diff) - (line.quantity * diff_rounded) diff = diff_rounded quant_dict = {} for quant in quants: quant_dict[quant.id] = quant.cost + diff if quant_correct: quant_dict[quant_correct.id] = quant_correct.cost + diff_correct for key, value in quant_dict.items(): quant_obj.write(cr, SUPERUSER_ID, key, {'cost': value}, context=context) qty_out = 0 for quant in line.move_id.quant_ids: if quant.location_id.usage != 'internal': qty_out += quant.qty self._create_accounting_entries(cr, uid, line, move_id, qty_out, context=context) self.write(cr, uid, cost.id, {'state': 'done', 'account_move_id': move_id}, context=context) self.pool.get('account.move').post(cr, uid, [move_id], context=context) return True
def compute(self, cr, uid, from_currency_id, to_currency_id=False,contract_id = False,amount = 1.0,context=False, round=True): from_rate = 0 to_rate = 0 rouding = 0.010000 cr.execute("""Select rcr.id, rcr.name from res_company rc left join res_currency rcr on currency_id = rcr.id""") curs = cr.fetchone() if curs: company_curr_id = curs[0] company_curr_name = curs[1] else: company_curr_id = False company_curr_name = False from_currency_id = from_currency_id or company_curr_name to_currency_id = to_currency_id or company_curr_name if isinstance(from_currency_id,str) and isinstance(to_currency_id,str) and not contract_id: return 0 else: if contract_id: from_currency_id = self.search(cr,uid,[('contract_id','=',contract_id),('name','=',from_currency_id)]) if from_currency_id: from_currency_id=from_currency_id[0] to_currency_id = self.search(cr,uid,[('contract_id','=',contract_id),('name','=',to_currency_id)]) if to_currency_id: to_currency_id=to_currency_id[0] if from_currency_id: from_rate = self.read(cr,uid,from_currency_id,['rate']) if from_rate: from_rate = from_rate['rate'] if to_currency_id: to_list = self.read(cr,uid,to_currency_id,['rate','rounding']) to_rate = to_list['rate'] rounding = to_list['rounding'] #raise osv.ex if to_rate: result = from_rate/to_rate*amount if not to_rate: return 0 else: rate = from_rate/to_rate if round: result = float_round(amount*rate,precision_rounding=rounding) else: result = amount*rate return result
def ogone_form_generate_values(self, cr, uid, id, values, context=None): base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url') acquirer = self.browse(cr, uid, id, context=context) if not acquirer.payment_term_id: return super(PaymentAcquirerOgone, self).ogone_form_generate_values(cr, uid, id, values, context=context) ogone_tx_values = dict(values) temp_ogone_tx_values = { 'PSPID': acquirer.ogone_pspid, 'ORDERID': values['reference'], 'AMOUNT': float_repr(float_round(values['amount'], 2) * 100, 0), 'CURRENCY': values['currency'] and values['currency'].name or '', 'LANGUAGE': values.get('partner_lang'), 'CN': values.get('partner_name'), 'EMAIL': values.get('partner_email'), 'OWNERZIP': values.get('partner_zip'), 'OWNERADDRESS': values.get('partner_address'), 'OWNERTOWN': values.get('partner_city'), 'OWNERCTY': values.get('partner_country') and values.get('partner_country').code or '', 'OWNERTELNO': values.get('partner_phone'), 'ACCEPTURL': '%s' % urlparse.urljoin(base_url, OgoneController._accept_url), 'DECLINEURL': '%s' % urlparse.urljoin(base_url, OgoneController._decline_url), 'EXCEPTIONURL': '%s' % urlparse.urljoin(base_url, OgoneController._exception_url), 'CANCELURL': '%s' % urlparse.urljoin(base_url, OgoneController._cancel_url), 'PARAMPLUS': 'return_url=%s' % ogone_tx_values.pop('return_url') if ogone_tx_values.get('return_url') else False, } if values.get('type') == 'form_save': temp_ogone_tx_values.update({ 'ALIAS': 'ODOO-NEW-ALIAS-%s' % time.time(), # something unique, 'ALIASUSAGE': values.get('alias_usage') or acquirer.ogone_alias_usage, }) totlines = acquirer.payment_term_id.compute( float_round(values['amount'], 2), )[0] index = 1 for scheduled_date, amount in sorted(totlines): scheduled_date = datetime.strptime(scheduled_date, DEFAULT_SERVER_DATE_FORMAT).strftime('%d/%m/%Y') if index == 1: temp_ogone_tx_values['AMOUNT1'] = float_repr(float_round(amount, 2) * 100, 0) else: temp_ogone_tx_values['AMOUNT' + str(index)] = float_repr(float_round(amount, 2) * 100, 0) temp_ogone_tx_values['EXECUTIONDATE' + str(index)] = scheduled_date index += 1 shasign = self._ogone_generate_shasign(acquirer, 'in', temp_ogone_tx_values) temp_ogone_tx_values['SHASIGN'] = shasign ogone_tx_values.update(temp_ogone_tx_values) return ogone_tx_values
def price_get(self, product_id, qty, partner_id, uom_id): product_obj = self.env["product.product"] price_type_obj = self.env["product.price.type"] product = product_obj.browse(product_id) price = False qty_uom_id = uom_id or product.uom_id.id price_uom_id = qty_uom_id price_types = {} if self.base == -1: if self.base_pricelist_id: price_tmp = self.base_pricelist_id._price_get_multi(self.base_pricelist_id, [(product, qty, False)])[ product.id ] ptype_src = self.base_pricelist_id.currency_id price = ptype_src.compute(price_tmp, self.pricelist.currency_id, round=False) elif self.base == -2: seller = False for seller_id in product.seller_ids: if (not partner_id) or (seller_id.name.id != partner_id): continue seller = seller_id if not seller and product.seller_ids: seller = product.seller_ids[0] if seller: qty_in_seller_uom = qty for line in seller.pricelist_ids: if line.min_quantity <= qty_in_seller_uom: price = line.price else: if self.base not in price_types: price_types[self.base] = price_type_obj.browse(int(self.base)) price_type = price_types[self.base] # price_get returns the price in the context UoM, i.e. # qty_uom_id price = price_type.currency_id.compute( product.product_tmpl_id._price_get(product, price_type.field)[product.id], self.pricelist.currency_id, round=False, ) if price is not False: price_limit = price price = price * (1.0 + (self.price_discount or 0.0)) if self.price_round: price = tools.float_round(price, precision_rounding=self.price_round) convert_to_price_uom = lambda price: product.uom_id._compute_price(price_uom_id, price) if self.price_surcharge: price_surcharge = convert_to_price_uom(self.price_surcharge) price += price_surcharge if self.price_min_margin: price_min_margin = convert_to_price_uom(self.price_min_margin) price = max(price, price_limit + price_min_margin) if self.price_max_margin: price_max_margin = convert_to_price_uom(self.price_max_margin) price = min(price, price_limit + price_max_margin) # Final price conversion to target UoM uom_obj = self.env["product.uom"] price = uom_obj._compute_price(price_uom_id, price, qty_uom_id) return price
def _onchange_amount(self): if hasattr(super(account_payment, self), '_onchange_amount'): super(account_payment, self)._onchange_amount() check_amount_in_words = amount_to_text_en.amount_to_text(math.floor(self.amount), lang='en', currency='') check_amount_in_words = check_amount_in_words.replace(' and Zero Cent', '') # Ugh decimals = self.amount % 1 if decimals >= 10**-2: check_amount_in_words += _(' and %s/100') % str(int(round(float_round(decimals*100, precision_rounding=1)))) self.check_amount_in_words = check_amount_in_words
def round(self, cr, uid, currency, amount): """Return ``amount`` rounded according to ``currency``'s rounding rules. :param Record currency: currency for which we are rounding :param float amount: the amount to round :return: rounded float """ return float_round(amount, precision_rounding=currency.rounding)
def _onchange_amount(self): if hasattr(super(account_register_payments, self), '_onchange_amount'): super(account_register_payments, self)._onchange_amount() # TODO: merge, refactor and complete the amount_to_text and amount_to_text_en classes check_amount_in_words = amount_to_text_en.amount_to_text(math.floor(self.amount), lang='en', currency='') check_amount_in_words = check_amount_in_words.replace(' and Zero Cent', '') # Ugh decimals = self.amount % 1 if decimals >= 10**-2: check_amount_in_words += _(' and %s/100') % str(int(round(float_round(decimals*100, precision_rounding=1)))) self.check_amount_in_words = check_amount_in_words
def adyen_form_generate_values(self, cr, uid, id, values, context=None): base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url') acquirer = self.browse(cr, uid, id, context=context) # tmp import datetime from dateutil import relativedelta if acquirer.provider == 'adyen' and len(acquirer.adyen_skin_hmac_key) == 64: tmp_date = datetime.datetime.today() + relativedelta.relativedelta(days=1) values.update({ 'merchantReference': values['reference'], 'paymentAmount': '%d' % int(float_round(values['amount'], 2) * 100), 'currencyCode': values['currency'] and values['currency'].name or '', 'shipBeforeDate': tmp_date.strftime('%Y-%m-%d'), 'skinCode': acquirer.adyen_skin_code, 'merchantAccount': acquirer.adyen_merchant_account, 'shopperLocale': values.get('partner_lang', ''), 'sessionValidity': tmp_date.isoformat('T')[:19] + "Z", 'resURL': '%s' % urlparse.urljoin(base_url, AdyenController._return_url), 'merchantReturnData': json.dumps({'return_url': '%s' % values.pop('return_url')}) if values.get('return_url', '') else False, 'shopperEmail': values.get('partner_email', ''), }) values['merchantSig'] = self._adyen_generate_merchant_sig_sha256(acquirer, 'in', values) else: tmp_date = datetime.date.today() + relativedelta.relativedelta(days=1) values.update({ 'merchantReference': values['reference'], 'paymentAmount': '%d' % int(float_round(values['amount'], 2) * 100), 'currencyCode': values['currency'] and values['currency'].name or '', 'shipBeforeDate': tmp_date, 'skinCode': acquirer.adyen_skin_code, 'merchantAccount': acquirer.adyen_merchant_account, 'shopperLocale': values.get('partner_lang'), 'sessionValidity': tmp_date, 'resURL': '%s' % urlparse.urljoin(base_url, AdyenController._return_url), 'merchantReturnData': json.dumps({'return_url': '%s' % values.pop('return_url')}) if values.get('return_url') else False, 'merchantSig': self._adyen_generate_merchant_sig(acquirer, 'in', values), }) return values
def calc_new_price( self, old_price, price_discount, price_surcharge, price_round): new_price = old_price * \ (1.0 + (price_discount or 0.0)) if price_round: new_price = tools.float_round( new_price, precision_rounding=price_round) if price_surcharge: new_price += price_surcharge return new_price
def onchange_tax_id(self, cr, uid, ids, taxes, currency_id, amount,): tax_amount = 0 tax_obj = self.pool.get('account.tax') curr_rounding = self.pool.get('res.currency').read(cr, uid, currency_id,['rounding'])['rounding'] for taxids in taxes: for tax in tax_obj.browse(cr, uid, taxids[2]): if tax.type=='percent': tax_amount+=float_round(amount*tax.amount,precision_rounding=curr_rounding) elif tax.type=='fixed': tax_amount+=tax.amount return {'value':{'tax_amount':tax_amount}}
def float_round(cr,f_val,application = None): """ 使用decimal precision 设置ktv_fee,四舍五入给定的float """ dp_name = application if application else "ktv_fee" dp_compute = dp.get_precision(dp_name) precision,scale = dp_compute(cr) ret = tools.float_round(f_val,precision_digits=scale) return ret
def get_periodical_lines(self, board): # TODO: improve me if board.depreciation_period == 12: return [self] period_depreciation_start_date = get_period_start_date(self.depreciation_date, board.fiscalyear_start_day, 12) if period_depreciation_start_date < board.depreciation_start_date: period_depreciation_start_date = board.depreciation_start_date period_depreciation_stop_date = self.depreciation_date if board.board_stop_date and period_depreciation_stop_date > board.board_stop_date: period_depreciation_stop_date = board.board_stop_date prorata_temporis_by_period = get_prorata_temporis_by_period(period_depreciation_start_date, period_depreciation_stop_date, board.fiscalyear_start_day, board.depreciation_period) if not prorata_temporis_by_period: return [] lines = [] total = sum(prorata_temporis_by_period.values()) previous_accumulated_value = accumulated_value = self.accumulated_value - self.depreciation_value book_value_wo_exceptional = self.book_value_wo_exceptional + self.depreciation_value book_value = self.book_value_wo_exceptional + self.exceptional_value exceptional_value = gap = accumulated_value_in_period = 0.0 depreciation_number = len(prorata_temporis_by_period) for depreciation_index, depreciation_date in enumerate(sorted(prorata_temporis_by_period)): readonly_depreciation_value, readonly = self._get_readonly_value(board) depreciation_value = float_round(self.depreciation_value * prorata_temporis_by_period[depreciation_date] / total, precision_digits=board.rounding) if readonly: gap += depreciation_value - readonly_depreciation_value depreciation_value = readonly_depreciation_value elif gap: depreciation_value += gap if depreciation_index + 1 == depreciation_number: depreciation_value = self.depreciation_value - accumulated_value_in_period else: accumulated_value_in_period += depreciation_value accumulated_value += depreciation_value exceptional_value = self._get_exceptional_value(board) book_value_wo_exceptional -= depreciation_value book_value = book_value_wo_exceptional - exceptional_value vals = { 'depreciation_date': depreciation_date, 'base_value': self.base_value, 'depreciation_value': depreciation_value, 'previous_years_accumulated_value': previous_accumulated_value, 'current_year_accumulated_value': accumulated_value - previous_accumulated_value, 'accumulated_value': accumulated_value, 'exceptional_value': exceptional_value, 'book_value': book_value, 'book_value_wo_exceptional': book_value_wo_exceptional, 'rounding': board.rounding, 'readonly': readonly, } lines.append(DepreciationBoardLine(**vals)) return lines
def ret(comparator, amount, p=precision, f=field, c=currency): if comparator == '<': if amount < 0: domain = [(f, '<', 0), (f, '>', amount)] else: domain = [(f, '>', 0), (f, '<', amount)] elif comparator == '=': domain = [(f, '=', float_round(amount, precision_digits=p))] else: raise UserError(_("Programmation error : domain_maker_move_line_amount requires comparator '=' or '<'")) domain += [('currency_id', '=', c)] return domain
def _check_unit_price_discount(self): for line in self.order_line: if line.product_uom_qty: raw_price = line.price_subtotal / line.product_uom_qty round_price = float_round(line.price_subtotal / line.product_uom_qty, 2) if float_compare(raw_price, round_price, 4) != 0: raise ValidationError( _("%s\nYour discount %s%% result in unit price after " "discount = %s (> 2 decimal points).\n" "You should adjust unit price manually!") % (line.name, line.discount, raw_price, ))
def ret(comparator, amount, p=precision, f=field, c=currency): if comparator == '<': if amount < 0: domain = [(f, '<', 0), (f, '>', amount)] else: domain = [(f, '>', 0), (f, '<', amount)] elif comparator == '=': if f == 'amount_residual': domain = [ '|', (f, '=', float_round(amount, precision_digits=p)), '&', ('account_id.internal_type', '=', 'liquidity'), '|', ('debit', '=', amount), ('credit', '=', amount), ] else: domain = [ '|', (f, '=', float_round(amount, precision_digits=p)), '&', ('account_id.internal_type', '=', 'liquidity'), ('amount_currency', '=', amount), ] else: raise UserError(_("Programmation error : domain_maker_move_line_amount requires comparator '=' or '<'")) domain += [('currency_id', '=', c)] return domain
def __init__(self, depreciation_date, base_value, depreciation_value, accumulated_value, book_value, exceptional_value=0.0, book_value_wo_exceptional=0.0, readonly=False, rounding=2, **optional_args): self.depreciation_date = depreciation_date self.base_value = float_round(base_value, precision_digits=rounding) self.depreciation_value = float_round(depreciation_value, precision_digits=rounding) self.accumulated_value = float_round(accumulated_value, precision_digits=rounding) self.book_value = float_round(book_value, precision_digits=rounding) self.exceptional_value = float_round(exceptional_value, precision_digits=rounding) self.book_value_wo_exceptional = float_round(book_value_wo_exceptional or book_value, precision_digits=rounding) self.readonly = readonly self.current_year_accumulated_value = float_round(optional_args.get('current_year_accumulated_value', self.depreciation_value + self.exceptional_value), precision_digits=rounding) self.previous_years_accumulated_value = float_round(optional_args.get('previous_years_accumulated_value', self.accumulated_value - self.depreciation_value + self.book_value_wo_exceptional - self.book_value - self.exceptional_value), precision_digits=rounding)
def ogonedadi_form_generate_values(self, cr, uid, id, partner_values, tx_values, context=None): base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url') acquirer = self.browse(cr, uid, id, context=context) ogonedadi_tx_values = dict(tx_values) # AMOUNT calculation changed! see: https://github.com/odoo/odoo/commit/7c2521a79bc9443adab1bc63007e70661a8c22b7 temp_ogonedadi_tx_values = { 'PSPID': acquirer.ogonedadi_pspid, 'ORDERID': tx_values['reference'], 'AMOUNT': float_repr(float_round(tx_values['amount'], 2) * 100, 0), 'CURRENCY': tx_values['currency'] and tx_values['currency'].name or '', 'LANGUAGE': partner_values['lang'], 'CN': partner_values['name'], 'EMAIL': partner_values['email'], 'OWNERZIP': partner_values['zip'], 'OWNERADDRESS': partner_values['address'], 'OWNERTOWN': partner_values['city'], 'OWNERCTY': partner_values['country'] and partner_values['country'].code or '', 'OWNERTELNO': partner_values['phone'], 'ACCEPTURL': '%s' % urlparse.urljoin(base_url, OgonedadiController._accept_url), 'DECLINEURL': '%s' % urlparse.urljoin(base_url, OgonedadiController._decline_url), 'EXCEPTIONURL': '%s' % urlparse.urljoin(base_url, OgonedadiController._exception_url), 'CANCELURL': '%s' % urlparse.urljoin(base_url, OgonedadiController._cancel_url), } if ogonedadi_tx_values.get('return_url'): temp_ogonedadi_tx_values['PARAMPLUS'] = 'return_url=%s' % ogonedadi_tx_values.pop('return_url') # By Mike: extra values to submit to ogone if set in payment.acquirer form if acquirer.ogonedadi_pm: temp_ogonedadi_tx_values['PM'] = acquirer.ogonedadi_pm if acquirer.ogonedadi_brand: temp_ogonedadi_tx_values['BRAND'] = acquirer.ogonedadi_brand if acquirer.ogonedadi_tp: temp_ogonedadi_tx_values['TP'] = acquirer.ogonedadi_tp shasign = self._ogonedadi_generate_shasign(acquirer, 'in', temp_ogonedadi_tx_values) temp_ogonedadi_tx_values['SHASIGN'] = shasign ogonedadi_tx_values.update(temp_ogonedadi_tx_values) return partner_values, ogonedadi_tx_values