Merge branch 'odoo/8.0' into master-wmsstaging4-jco

This commit is contained in:
Josse Colpaert 2014-07-07 23:34:42 +02:00
commit beb12f71f1
27 changed files with 265 additions and 445 deletions

View File

@ -98,7 +98,7 @@ class account_invoice(models.Model):
def _compute_reconciled(self):
self.reconciled = self.test_paid()
if not self.reconciled and self.state == 'paid':
self.signal_open_test()
self.signal_workflow('open_test')
@api.model
def _get_reference_type(self):

View File

@ -104,7 +104,7 @@ class account_fiscal_position(osv.osv):
# partner manually set fiscal position always win
if partner.property_account_position:
return part.property_account_position.id
return partner.property_account_position.id
# if no delivery use invocing
if delivery_id:

View File

@ -1,3 +1,3 @@
.oe_systray #oe_attendance_sign_in_out_icon {
font-color: white;
color: white;
}

View File

@ -14,7 +14,6 @@
/* button */
.oe_systray #oe_topbar_imbutton_icon {
color: white;
margin-right: 10px;
}
.oe_topbar_item.oe_topbar_imbutton .oe_e {
position: relative;

View File

@ -884,7 +884,7 @@ class mrp_production(osv.osv):
production = self.browse(cr, uid, production_id, context=context)
if not production.move_lines and production.state == 'ready':
# trigger workflow if not products to consume (eg: services)
self.signal_button_produce(cr, uid, [production_id])
self.signal_workflow(cr, uid, [production_id], 'button_produce')
produced_qty = self._get_produced_qty(cr, uid, production, context=context)
@ -944,7 +944,7 @@ class mrp_production(osv.osv):
stock_mov_obj.action_done(cr, uid, [extra_move_id], context=context)
self.message_post(cr, uid, production_id, body=_("%s produced") % self._description, context=context)
self.signal_button_produce_done(cr, uid, [production_id])
self.signal_workflow(cr, uid, [production_id], 'button_produce_done')
return True
def _costs_generate(self, cr, uid, production):

View File

@ -114,7 +114,7 @@ class procurement_order(osv.osv):
procurement.refresh()
self.production_order_create_note(cr, uid, procurement, context=context)
production_obj.action_compute(cr, uid, [produce_id], properties=[x.id for x in procurement.property_ids])
production_obj.signal_button_confirm(cr, uid, [produce_id])
production_obj.signal_workflow(cr, uid, [produce_id], 'button_confirm')
else:
res[procurement.id] = False
self.message_post(cr, uid, [procurement.id], body=_("No BoM exists for this product!"), context=context)

View File

@ -160,7 +160,7 @@ class StockMove(osv.osv):
'consumed_for': consumed_for}, context=context)
self.action_done(cr, uid, res, context=context)
production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])])
production_obj.signal_button_produce(cr, uid, production_ids)
production_obj.signal_workflow(cr, uid, production_ids, 'button_produce')
for new_move in res:
if new_move != move.id:
#This move is not already there in move lines of production order
@ -182,7 +182,7 @@ class StockMove(osv.osv):
#If we are not scrapping our whole move, tracking and lot references must not be removed
production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])])
for prod_id in production_ids:
production_obj.signal_button_produce(cr, uid, [prod_id])
production_obj.signal_workflow(cr, uid, [prod_id], 'button_produce')
for new_move in new_moves:
production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]})
res.append(new_move)

View File

@ -497,7 +497,7 @@ class pos_session(osv.osv):
_('Error!'),
_("You cannot confirm all orders of this session, because they have not the 'paid' status"))
else:
pos_order_obj.signal_done(cr, uid, [order.id])
pos_order_obj.signal_workflow(cr, uid, [order.id], 'done')
return True
@ -581,14 +581,14 @@ class pos_order(osv.osv):
order_ids.append(order_id)
try:
self.signal_paid(cr, uid, [order_id])
self.signal_workflow(cr, uid, [order_id], 'paid')
except Exception as e:
_logger.error('Could not fully process the POS Order: %s', tools.ustr(e))
if to_invoice:
self.action_invoice(cr, uid, [order_id], context)
order_obj = self.browse(cr, uid, order_id, context)
self.pool['account.invoice'].signal_invoice_open(cr, uid, [order_obj.invoice_id.id])
self.pool['account.invoice'].signal_workflow(cr, uid, [order_obj.invoice_id.id], 'invoice_open')
return order_ids
@ -933,8 +933,8 @@ class pos_order(osv.osv):
inv_line['invoice_line_tax_id'] = [(6, 0, [x.id for x in line.product_id.taxes_id] )]
inv_line_ref.create(cr, uid, inv_line, context=context)
inv_ref.button_reset_taxes(cr, uid, [inv_id], context=context)
self.signal_invoice(cr, uid, [order.id])
inv_ref.signal_validate(cr, uid, [inv_id])
self.signal_workflow(cr, uid, [order.id], 'invoice')
inv_ref.signal_workflow(cr, uid, [inv_id], 'validate')
if not inv_ids: return {}

View File

@ -328,7 +328,7 @@ class purchase_order(osv.osv):
raise osv.except_osv(_('Invalid Action!'), _('In order to delete a purchase order, you must cancel it first.'))
# automatically sending subflow.delete upon deletion
self.signal_purchase_cancel(cr, uid, unlink_ids)
self.signal_workflow(cr, uid, unlink_ids, 'purchase_cancel')
return super(purchase_order, self).unlink(cr, uid, unlink_ids, context=context)
@ -519,7 +519,7 @@ class purchase_order(osv.osv):
This function prints the request for quotation and mark it as sent, so that we can see more easily the next step of the workflow
'''
assert len(ids) == 1, 'This option should only be used for a single id at a time'
self.signal_send_rfq(cr, uid, ids)
self.signal_workflow(cr, uid, ids, 'send_rfq')
return self.pool['report'].get_action(cr, uid, ids, 'purchase.report_purchasequotation', context=context)
def wkf_confirm_order(self, cr, uid, ids, context=None):
@ -680,19 +680,19 @@ class purchase_order(osv.osv):
_('Unable to cancel the purchase order %s.') % (purchase.name),
_('First cancel all receptions related to this purchase order.'))
self.pool.get('stock.picking') \
.signal_button_cancel(cr, uid, map(attrgetter('id'), purchase.picking_ids))
.signal_workflow(cr, uid, map(attrgetter('id'), purchase.picking_ids), 'button_cancel')
for inv in purchase.invoice_ids:
if inv and inv.state not in ('cancel', 'draft'):
raise osv.except_osv(
_('Unable to cancel this purchase order.'),
_('You must first cancel all invoices related to this purchase order.'))
self.pool.get('account.invoice') \
.signal_invoice_cancel(cr, uid, map(attrgetter('id'), purchase.invoice_ids))
.signal_workflow(cr, uid, map(attrgetter('id'), purchase.invoice_ids), 'invoice_cancel')
self.pool['purchase.order.line'].write(cr, uid, [l.id for l in purchase.order_line],
{'state': 'cancel'})
self.write(cr, uid, ids, {'state': 'cancel'})
self.set_order_line_status(cr, uid, ids, 'cancel', context=context)
self.signal_purchase_cancel(cr, uid, ids)
self.signal_workflow(cr, uid, ids, 'purchase_cancel')
return True
def _prepare_order_line_move(self, cr, uid, order, order_line, picking_id, group_id, context=None):
@ -933,7 +933,7 @@ class purchase_order(osv.osv):
# make triggers pointing to the old orders point to the new order
for old_id in old_ids:
self.redirect_workflow(cr, uid, [(old_id, neworder_id)])
self.signal_purchase_cancel(cr, uid, [old_id])
self.signal_workflow(cr, uid, [old_id], 'purchase_cancel')
return orders_info
@ -1370,7 +1370,7 @@ class mail_mail(osv.Model):
if mail_sent and mail.model == 'purchase.order':
obj = self.pool.get('purchase.order').browse(cr, uid, mail.res_id, context=context)
if obj.state == 'draft':
self.pool.get('purchase.order').signal_send_rfq(cr, uid, [mail.res_id])
self.pool.get('purchase.order').signal_workflow(cr, uid, [mail.res_id], 'send_rfq')
return super(mail_mail, self)._postprocess_sent_message(cr, uid, mail=mail, context=context, mail_sent=mail_sent)
@ -1431,7 +1431,7 @@ class mail_compose_message(osv.Model):
context = context or {}
if context.get('default_model') == 'purchase.order' and context.get('default_res_id'):
context = dict(context, mail_post_autofollow=True)
self.pool.get('purchase.order').signal_send_rfq(cr, uid, [context['default_res_id']])
self.pool.get('purchase.order').signal_workflow(cr, uid, [context['default_res_id']], 'send_rfq')
return super(mail_compose_message, self).send_mail(cr, uid, ids, context=context)

View File

@ -245,7 +245,7 @@ class purchase_requisition(osv.osv):
for quotation in tender.purchase_ids:
if (self.check_valid_quotation(cr, uid, quotation, context=context)):
#use workflow to set PO state to confirm
po.signal_purchase_confirm(cr, uid, [quotation.id])
po.signal_workflow(cr, uid, [quotation.id], 'purchase_confirm')
#get other confirmed lines per supplier
for po_line in tender.po_line_ids:
@ -268,13 +268,13 @@ class purchase_requisition(osv.osv):
vals = self._prepare_po_line_from_tender(cr, uid, tender, line, new_po, context=context)
poline.copy(cr, uid, line.id, default=vals, context=context)
#use workflow to set new PO state to confirm
po.signal_purchase_confirm(cr, uid, [new_po])
po.signal_workflow(cr, uid, [new_po], 'purchase_confirm')
#cancel other orders
self.cancel_unconfirmed_quotations(cr, uid, tender, context=context)
#set tender to state done
self.signal_done(cr, uid, [tender.id])
self.signal_workflow(cr, uid, [tender.id], 'done')
return True
def cancel_unconfirmed_quotations(self, cr, uid, tender, context=None):
@ -282,7 +282,7 @@ class purchase_requisition(osv.osv):
po = self.pool.get('purchase.order')
for quotation in tender.purchase_ids:
if quotation.state in ['draft', 'sent', 'bid']:
self.pool.get('purchase.order').signal_purchase_cancel(cr, uid, [quotation.id])
self.pool.get('purchase.order').signal_workflow(cr, uid, [quotation.id], 'purchase_cancel')
po.message_post(cr, uid, [quotation.id], body=_('Cancelled by the call for bids associated to this request for quotation.'), context=context)
return True

View File

@ -328,7 +328,7 @@ msgstr "Cancelada"
#. module: sale
#: view:sale.order.line:0
msgid "Sales Order Lines related to a Sales Order of mine"
msgstr "Linhas da ordem de vendas relacionadas com uma ordem de vendas minha"
msgstr "Linhas da ordem de venda relacionadas com uma ordem de venda minha"
#. module: sale
#: selection:sale.order,state:0
@ -589,7 +589,7 @@ msgstr "Ordem de venda confirmada"
#. module: sale
#: view:sale.order:0
msgid "Sales Order that haven't yet been confirmed"
msgstr "Ordem de Vendas que ainda não foram confirmadas"
msgstr "Ordens de Venda que ainda não foram confirmadas"
#. module: sale
#: view:sale.order:0
@ -898,11 +898,11 @@ msgid ""
"1.The state of this sales order line is either \"draft\" or \"cancel\"!\n"
"2.The Sales Order Line is Invoiced!"
msgstr ""
"Fatura não pode ser criada para esta linha de Ordem de vendas devido a uma "
"Fatura não pode ser criada para esta linha de Ordem de venda devido a uma "
"das seguintes razões:\n"
"1.O estado desta linha ordem de vendas esteja como \"Projeto\" ou "
"1.O estado desta linha de ordem de venda seja \"Projeto\" ou "
"\"cancelada\"!\n"
"2.A linha da ordem de vendas é faturada!"
"2.A linha da ordem de venda é faturada!"
#. module: sale
#: view:sale.order.line.make.invoice:0
@ -1092,7 +1092,7 @@ msgstr "Termos e condições"
#: model:ir.ui.menu,name:sale.menu_sale_order
#: view:sale.order:0
msgid "Sales Orders"
msgstr "Ordens de Vendas"
msgstr "Ordens de Venda"
#. module: sale
#: help:sale.order,amount_tax:0
@ -1230,7 +1230,7 @@ msgid ""
"if the shipping policy is 'Payment before Delivery'."
msgstr ""
"O vendedor cria uma fatura manualmente, se a política de entrega da ordem de "
"vendas é 'Entrega Manual em Processamento'. A fatura é criada "
" é 'Entrega Manual em Processamento'. A fatura é criada "
"automaticamente se a política de entrega é 'Pagamento depois da Entrega'."
#. module: sale
@ -1336,7 +1336,7 @@ msgstr ""
#. module: sale
#: help:sale.order,origin:0
msgid "Reference of the document that generated this sales order request."
msgstr "Da referência do documento que gerou a ordem do pedido de vendas."
msgstr "Da referência do documento que gerou a ordem do pedido de ."
#. module: sale
#: code:addons/sale/sale.py:955
@ -1431,7 +1431,7 @@ msgstr "Faturas de clientes"
#. module: sale
#: model:process.node,note:sale.process_node_order0
msgid "Confirmed sales order to invoice."
msgstr "Confirmação da fatura da ordem de vendas."
msgstr "Confirmação da fatura da ordem de venda."
#. module: sale
#: field:sale.order.line,sequence:0
@ -1505,7 +1505,7 @@ msgstr "Fatura"
#. module: sale
#: view:sale.order.line:0
msgid "My Sales Order Lines"
msgstr "Minhas linhas da ordem de vendas"
msgstr "Minhas linhas da ordens de venda"
#. module: sale
#: model:process.transition.action,name:sale.process_transition_action_cancel0
@ -2034,7 +2034,7 @@ msgstr ""
#. module: sale
#: view:sale.report:0
msgid "Ordered month of the sales order"
msgstr "Ordenado pelo mês da ordem de vendas"
msgstr "Ordenado pelo mês da ordem de venda"
#. module: sale
#: model:process.transition,name:sale.process_transition_saleinvoice0
@ -2054,7 +2054,7 @@ msgid ""
"generates an invoice or a delivery order as soon as it is confirmed by the "
"salesman."
msgstr ""
"Dependendo da ordem de vendas e controle das faturas, estas pode ser "
"Dependendo da ordem de venda e controle das faturas, estas pode ser "
"baseadas em entregas ou em quantidades encomendadas. Assim, uma ordem de "
"venda pode gerar uma fatura ou uma ordem de entrega, assim que é confirmada "
"pelo vendedor."
@ -2084,7 +2084,7 @@ msgstr "Termo do Pagamento"
#. module: sale
#: view:sale.order:0
msgid "Sales Order ready to be invoiced"
msgstr "Ordem de vendas pronta a ser faturada"
msgstr "Ordem de venda pronta a ser faturada"
#. module: sale
#: field:sale.config.settings,group_invoice_so_lines:0
@ -2170,7 +2170,7 @@ msgstr ""
#. module: sale
#: view:sale.report:0
msgid "Ordered date of the sales order"
msgstr "Data do Pedido da ordem de vendas"
msgstr "Data do Pedido da ordem de venda"
#~ msgid "Quantity (UoM)"
#~ msgstr "Quantidade (UdM)"
@ -2474,7 +2474,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ msgstr "Contas de Pagamento"
#~ msgid "Sales orders"
#~ msgstr "Ordens de Vendas"
#~ msgstr "Ordens de Venda"
#~ msgid "Draft Invoice"
#~ msgstr "Factura Rascunho"
@ -2598,7 +2598,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ msgstr "Somente Entregar Ordem de Venda"
#~ msgid "Sales order lines"
#~ msgstr "Linhas da ordens de vendas"
#~ msgstr "Linhas de ordens de venda"
#~ msgid "Packing OUT is created for stockable products."
#~ msgstr "Saída de Embalagem é criada para produtos armazenáveis."
@ -2774,7 +2774,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ msgstr "Tem de associar um lote de produção a este artigo"
#~ msgid "Margins in Sales Orders"
#~ msgstr "Fusão de ordens de vendas"
#~ msgstr "Fusão de ordens de venda"
#~ msgid "You invoice has been successfully created!"
#~ msgstr "A sua fatura foi criada com êxito!"
@ -2830,7 +2830,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ msgstr "Aprovisionamento do material vendido"
#~ msgid "Sales Order Dates"
#~ msgstr "Datas da Ordem de Vendas"
#~ msgstr "Datas da Ordem de Venda"
#~ msgid "Sales Application Configuration"
#~ msgstr "Configuração da Aplicação de Vendas"
@ -2956,7 +2956,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ "directamente e aguardar que o utilizador clique no botão 'Factura' para "
#~ "gerar a factura do projecto. \n"
#~ " - A escolha 'Factura contra Entrega' irá gerar a factura com base em "
#~ "ordens de vendas, quando todas as listas de recolha forem concluídas.\n"
#~ "ordens de venda, quando todas as listas de recolha forem concluídas.\n"
#~ " - A escolha 'Factura da Recolha' é usada para criar uma factura durante o "
#~ "processo de recolha."
@ -2974,7 +2974,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ "For every sales order line, a procurement order is created to supply the "
#~ "sold product."
#~ msgstr ""
#~ "Para cada linha de pedido de vendas, uma ordem de aquisição é criada para "
#~ "Para cada linha de pedido de venda, uma ordem de aquisição é criada para "
#~ "fornecer o artigo vendido."
#~ msgid "Setup your sales workflow and default values."
@ -3008,10 +3008,10 @@ msgstr "Data do Pedido da ordem de vendas"
#~ " "
#~ msgstr ""
#~ "\n"
#~ " O módulo base para gerir cotações e pedidos de vendas.\n"
#~ " O módulo base para gerir cotações e pedidos de venda.\n"
#~ "\n"
#~ " * Fluxo de trabalho com etapas de validação:\n"
#~ " - Cotação -> Ordem de Vendas -> Factura\n"
#~ " - Cotação -> Ordem de Venda -> Factura\n"
#~ " * Métodos de facturação:\n"
#~ " - Facturas ordenadas (antes ou depois do envio)\n"
#~ " - Factura na entrega\n"
@ -3159,7 +3159,7 @@ msgstr "Data do Pedido da ordem de vendas"
#, python-format
#~ msgid "The sales order '%s' has been cancelled."
#~ msgstr "A ordem de vendas '%s' foi cancelada"
#~ msgstr "A ordem de venda '%s' foi cancelada"
#~ msgid ""
#~ "* The 'Draft' state is set when the related sales order in draft state. "
@ -3172,13 +3172,13 @@ msgstr "Data do Pedido da ordem de vendas"
#~ " \n"
#~ "* The 'Cancelled' state is set when a user cancel the sales order related."
#~ msgstr ""
#~ "* O estado 'Rascunho' é definido quando a ordem de vendas relacionada se "
#~ "* O estado 'Rascunho' é definido quando a ordem de venda relacionada se "
#~ "encontra em estado 'Rascunho'. \n"
#~ "* O estado 'Confirmado' é definido quando a ordem de vendas relacionada é "
#~ "* O estado 'Confirmado' é definido quando a ordem de venda relacionada é "
#~ "confirmada. \n"
#~ "* O estado 'Excepção' é definido quando a ordem relacionada é definida como "
#~ "uma excepção. \n"
#~ "* O estado 'Feito' é definido quando a linha da ordem de vendas foi "
#~ "* O estado 'Feito' é definido quando a linha da ordem de venda foi "
#~ "escolhida. \n"
#~ "* O estado 'Cancelado' é definido quando o utilizador cancela a ordem de "
#~ "vendar relacionada."
@ -3193,23 +3193,23 @@ msgstr "Data do Pedido da ordem de vendas"
#~ msgstr "Configure a aplicação da gerência de vendas"
#~ msgid "Sales Order Layout Improvement"
#~ msgstr "Melhoria do Layout da Ordem vendas"
#~ msgstr "Melhoria do Layout da Ordem de venda"
#~ msgid ""
#~ "One Procurement order for each sales order line and for each of the "
#~ "components."
#~ msgstr ""
#~ "Uma ordem de Aquisições para cada linha de pedido de vendas e para cada um "
#~ "Uma ordem de Aquisições para cada linha de pedido de venda e para cada um "
#~ "dos componentes."
#, python-format
#~ msgid "Cannot delete Sales Order(s) which are already confirmed !"
#~ msgstr ""
#~ "Não é possível eliminar a(s) ordem(s) de vendas que já foram confirmadas !"
#~ "Não é possível eliminar a(s) ordem(s) de venda que já foram confirmadas !"
#, python-format
#~ msgid "The sales order '%s' has been set in draft state."
#~ msgstr "A ordem de vendas '%s' foi definida com o estado rascunho."
#~ msgstr "A ordem de venda '%s' foi definida com o estado rascunho."
#~ msgid ""
#~ "If you have more than one shop reselling your company products, you can "
@ -3243,7 +3243,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ "Provides some features to improve the layout of the Sales Order reports."
#~ msgstr ""
#~ "Fornece alguns recursos para melhorar a apresentação dos relatórios da Ordem "
#~ "de vendas."
#~ "de venda."
#~ msgid "Based on Tasks' Work"
#~ msgstr "Baseada nas tarefas' Trabalho"
@ -3264,7 +3264,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ "Sale Order Lines that are confirmed, done or in exception state and haven't "
#~ "yet been invoiced"
#~ msgstr ""
#~ "Linhas da ordem de vendas estão confirmadas, concluídas ou em estado de "
#~ "Linhas da ordem de venda estão confirmadas, concluídas ou em estado de "
#~ "exceção e ainda não foram faturados"
#~ msgid "Invoice based on deliveries"
@ -3304,7 +3304,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ "'para gerar o rascunho da fatura com base na ordem de venda ou as linhas da "
#~ "ordem de venda.\n"
#~ " - A opção 'Fatura após Entrega' irá gerar o rascunho da fatura baseada na "
#~ "ordem de vendas depois de todas as listas de picking terem sido terminadas.\n"
#~ "ordem de venda depois de todas as listas de picking terem sido terminadas.\n"
#~ " - A opção 'Fatura baseada nas entregas' é usada para criar uma fatura "
#~ "durante o processo de picking."
@ -3328,7 +3328,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ msgstr "Não pode mover os artigos de ou para um local de tipo vista."
#~ msgid "Based on Sales Orders"
#~ msgstr "Baseado na ordem de vendas"
#~ msgstr "Baseado na ordem de venda"
#~ msgid "Line Sequence"
#~ msgstr "Sequência da linha"
@ -3371,7 +3371,7 @@ msgstr "Data do Pedido da ordem de vendas"
#, python-format
#~ msgid "Cannot delete a sales order line which is in state '%s'!"
#~ msgstr ""
#~ "Não é possível excluir uma linha da ordem de vendas que esteja no estado "
#~ "Não é possível excluir uma linha da ordem de venda que esteja no estado "
#~ "'%s'!"
#, python-format
@ -3382,7 +3382,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ msgstr "Cobram a entrega?"
#~ msgid "Sales order created in current month"
#~ msgstr "Ordens de vendas criadas este mês"
#~ msgstr "Ordens de venda criadas este mês"
#~ msgid ""
#~ "If 'on order', it triggers a procurement when the sale order is confirmed to "
@ -3403,7 +3403,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ msgstr "${object.company_id.name} Order (Ref ${object.name or 'n/a' })"
#~ msgid "Confirmed sale order lines, not yet delivered"
#~ msgstr "Linhas da ordem de vendas confirmadas, mas ainda não foram entregues"
#~ msgstr "Linhas da ordem de venda confirmadas, mas ainda não entregues"
#~ msgid "Setup your Invoicing Method"
#~ msgstr "Configure o seu método de faturação"
@ -3415,19 +3415,19 @@ msgstr "Data do Pedido da ordem de vendas"
#~ msgstr "Ordem de Impressão"
#~ msgid "Sale order lines done"
#~ msgstr "Linhas da ordem de vendas concluídas"
#~ msgstr "Linhas da ordem de venda concluídas"
#~ msgid "Sale Order Lines ready to be invoiced"
#~ msgstr "Linhas da ordem de vendas prontas para serem faturadas"
#~ msgstr "Linhas da ordem de venda prontas para serem faturadas"
#~ msgid "Sale Order Lines that are in 'done' state"
#~ msgstr "Linhas da ordem de vendas que estejam no estado 'Concluído'"
#~ msgstr "Linhas da ordem de venda que estejam no estado 'Concluído'"
#~ msgid "Main Method Based On"
#~ msgstr "Métodos principais baseados"
#~ msgid "Sales order created in current year"
#~ msgstr "Ordens de Vendas criadas este ano"
#~ msgstr "Ordens de Venda criadas este ano"
#~ msgid "Contract/Analytic Account"
#~ msgstr "Contrato / Conta Analítica"
@ -3450,7 +3450,7 @@ msgstr "Data do Pedido da ordem de vendas"
#~ msgstr "Sem stock suficiente ! : "
#~ msgid "Sales order created in last month"
#~ msgstr "Ordem de vendas criadas no mês passado"
#~ msgstr "Ordem de venda criadas no mês passado"
#~ msgid "Deliver & invoice on demand"
#~ msgstr "Entrega & Fatura a pedido"
@ -3467,8 +3467,8 @@ msgstr "Data do Pedido da ordem de vendas"
#~ "sales orders partially, by lines of sales order. You do not need this list "
#~ "if you invoice from the delivery orders or if you invoice sales totally."
#~ msgstr ""
#~ "Aqui está uma lista de cada pedido de vendas a ser faturado. Pode faturar "
#~ "ordens de venda parcialmente, por linhas de pedido de vendas. Não precisa "
#~ "Aqui está uma lista de cada pedido de venda a ser faturado. Pode faturar "
#~ "ordens de venda parcialmente, por linhas de pedido de venda. Não precisa "
#~ "desta lista se faturar os pedidos de entrega ou se facturar a venda "
#~ "totalmente."
@ -3488,12 +3488,12 @@ msgstr "Data do Pedido da ordem de vendas"
#~ "configuration of the sales order, a draft invoice will be generated so that "
#~ "you just have to confirm it when you want to bill your customer."
#~ msgstr ""
#~ "Pedidos de Vendas ajudá-lo a gerir citações e ordens de seus clientes. "
#~ "Ordens de Venda ajudam-no a gerir citações e ordens de seus clientes. "
#~ "OpenERP sugere que se comece a criar um orçamento. Uma vez confirmada, a "
#~ "cotação será convertida numa ordem de venda. O OpenERP pode gerir vários "
#~ "tipos de artigos, possibilitando que uma ordem de venda desencadeie tarefas, "
#~ "ordens de entrega, ordens de produção, compras e assim por diante. Com base "
#~ "na configuração da ordem de vendas, uma fatura projeto será gerada para que "
#~ "na configuração da ordem de venda, uma fatura projeto será gerada para que "
#~ "só tenha que confirmar isso quando quiser faturar o cliente."
#~ msgid "Order Line"
@ -3788,10 +3788,10 @@ msgstr "Data do Pedido da ordem de vendas"
#~ "parts to the sales order. There is 1 pick list by sales order line which "
#~ "evolves with the availability of parts."
#~ msgstr ""
#~ "O formulário da Lista Pick é criado assim que a ordem de vendas é "
#~ "O formulário da Lista Pick é criado assim que a ordem de venda é "
#~ "confirmada, ao mesmo tempo que a ordem de aquisição. Ele representa a "
#~ "atribuição de peças para a ordem de vendas. Há uma lista de seleção de linha "
#~ "da ordem de vendas que evolui com a disponibilidade das peças."
#~ "atribuição de peças para a ordem de venda. Há uma lista de seleção de linha "
#~ "da ordem de venda que evolui com a disponibilidade das peças."
#~ msgid "Sales by Month"
#~ msgstr "Vendas por mês"
@ -3802,14 +3802,14 @@ msgstr "Data do Pedido da ordem de vendas"
#~ "production of products regarding to the rules and to the sales order's "
#~ "parameters. "
#~ msgstr ""
#~ "A ordem de aquisição é criada automaticamente, logo que uma ordem de vendas "
#~ "A ordem de aquisição é criada automaticamente, logo que uma ordem de venda "
#~ "é confirmada ou a fatura é paga. Que impulsiona a compra e a produção de "
#~ "artigos em relação às regras e aos parâmetros da ordem de vendas. "
#~ "artigos em relação às regras e aos parâmetros da ordem de venda. "
#, python-format
#~ msgid "You must first cancel all invoices attached to this sales order."
#~ msgstr ""
#~ "É necessário cancelar todas as faturas ligadas a esta ordem de vendas."
#~ "É necessário cancelar todas as faturas ligadas a esta ordem de venda."
#~ msgid "Invoice Based on Deliveries"
#~ msgstr "Fatura Baseada em Entregas"

View File

@ -60,7 +60,7 @@ class sale_make_invoice(osv.osv_memory):
for i in o.invoice_ids:
newinv.append(i.id)
# Dummy call to workflow, will not create another invoice but bind the new invoice to the subflow
order_obj.signal_manual_invoice(cr, uid, [o.id for o in orders if o.order_policy == 'manual'])
order_obj.signal_workflow(cr, uid, [o.id for o in orders if o.order_policy == 'manual'], 'manual_invoice')
result = mod_obj.get_object_reference(cr, uid, 'account', 'action_invoice_tree1')
id = result and result[1] or False
result = act_obj.read(cr, uid, [id], context=context)[0]

View File

@ -159,7 +159,7 @@ class sale_order(osv.osv):
raise osv.except_osv(
_('Cannot cancel sales order!'),
_('You must first cancel all delivery order(s) attached to this sales order.'))
stock_obj.signal_button_cancel(cr, uid, [p.id for p in sale.picking_ids])
stock_obj.signal_workflow(cr, uid, [p.id for p in sale.picking_ids], 'button_cancel')
return super(sale_order, self).action_cancel(cr, uid, ids, context=context)
def action_wait(self, cr, uid, ids, context=None):
@ -356,7 +356,7 @@ class stock_move(osv.osv):
if move.procurement_id and move.procurement_id.sale_line_id:
sale_ids.append(move.procurement_id.sale_line_id.order_id.id)
if sale_ids:
self.pool.get('sale.order').signal_ship_except(cr, uid, sale_ids)
self.pool.get('sale.order').signal_workflow(cr, uid, sale_ids, 'ship_except')
return super(stock_move, self).action_cancel(cr, uid, ids, context=context)
def _create_invoice_line_from_vals(self, cr, uid, move, invoice_line_vals, context=None):

View File

@ -76,7 +76,7 @@
!python {model: sale.order}: |
invoice_ids = self.browse(cr, uid, ref("sale.sale_order_8")).invoice_ids
first_invoice_id = invoice_ids[0]
self.pool.get('account.invoice').signal_invoice_cancel(cr, uid, [first_invoice_id.id])
self.pool.get('account.invoice').signal_workflow(cr, uid, [first_invoice_id.id], 'invoice_cancel')
-
I check order status in "Invoice Exception" and related invoice is in cancel state.
-

View File

@ -190,7 +190,7 @@
so = self.browse(cr, uid, ref("sale_order_service"))
account_invoice_obj = self.pool.get('account.invoice')
for invoice in so.invoice_ids:
account_invoice_obj.signal_invoice_open(cr, uid, [invoice.id])
account_invoice_obj.signal_workflow(cr, uid, [invoice.id], 'invoice_open')
-
I pay the invoice
-

View File

@ -76,7 +76,7 @@ class make_procurement(osv.osv_memory):
'location_id': wh.lot_stock_id.id,
'company_id': wh.company_id.id,
})
procurement_obj.signal_button_confirm(cr, uid, [procure_id])
procurement_obj.signal_workflow(cr, uid, [procure_id], 'button_confirm')
id2 = data_obj._get_id(cr, uid, 'procurement', 'procurement_tree_view')
id3 = data_obj._get_id(cr, uid, 'procurement', 'procurement_form_view')

View File

@ -8,7 +8,6 @@
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "EntypoRegular";
src: url("/web/static/src/font/entypo-webfont.eot") format("eot");
@ -19,7 +18,6 @@
font-weight: normal;
font-style: normal;
}
#oe_main_menu_navbar {
min-height: 34px;
z-index: 1001;
@ -39,6 +37,39 @@
margin-bottom: 0px;
}
.oe_systray {
margin-right: 0px !important;
}
.oe_notification {
z-index: 1600;
}
.oe_webclient_timezone_notification a {
color: white;
text-decoration: underline;
}
.oe_webclient_timezone_notification p {
margin-top: 1em;
}
.oe_webclient_timezone_notification dt {
font-weight: bold;
}
.oe_timezone_systray span {
margin-top: 1px;
background-color: #f6cf3b;
}
.navbar .oe_topbar_name {
max-width: 150px;
display: inline-block;
height: 15px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.openerp {
padding: 0;
margin: 0;
@ -800,23 +831,6 @@
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
}
.openerp .oe_notification {
z-index: 1500;
}
.openerp .oe_webclient_timezone_notification a {
color: white;
text-decoration: underline;
}
.openerp .oe_webclient_timezone_notification p {
margin-top: 1em;
}
.openerp .oe_webclient_timezone_notification dt {
font-weight: bold;
}
.openerp .oe_timezone_systray span {
margin-top: 1px;
background-color: #f6cf3b;
}
.openerp .oe_dialog_warning {
width: 100%;
}
@ -847,133 +861,6 @@
.openerp .oe_content_full_screen .oe_topbar, .openerp .oe_content_full_screen .oe_leftbar {
display: none;
}
.openerp .navbar .oe_topbar_anonymous_login {
background-color: #dc5f59;
color: #eeeeee;
background-color: #be4343;
background-image: -webkit-gradient(linear, left top, left bottom, from(#fc8787), to(maroon));
background-image: -webkit-linear-gradient(top, #fc8787, maroon);
background-image: -moz-linear-gradient(top, #fc8787, maroon);
background-image: -ms-linear-gradient(top, #fc8787, maroon);
background-image: -o-linear-gradient(top, #fc8787, maroon);
background-image: linear-gradient(to bottom, #fc8787, #800000);
}
.openerp .navbar .oe_topbar_anonymous_login a {
display: block;
padding: 5px 10px 7px;
line-height: 20px;
height: 30px;
text-decoration: none;
color: white;
background: transparent;
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
.openerp .navbar .oe_topbar_anonymous_login a:hover {
background: rgba(0, 0, 0, 0.1);
color: white;
text-shadow: 0px 0px 3px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset;
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset;
}
.openerp .navbar .oe_topbar_item {
display: block;
padding: 5px 10px 26px;
line-height: 20px;
height: 20px;
text-decoration: none;
color: #eeeeee;
vertical-align: top;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
.openerp .navbar .oe_topbar_item:hover {
background: rgba(0, 0, 0, 0.2);
text-shadow: black 0px 0px 3px;
color: white;
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) inset;
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) inset;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) inset;
}
.openerp .navbar .oe_topbar_avatar {
width: 24px;
height: 24px;
margin: -2px 2px 0 0;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
}
.openerp .navbar .oe_topbar_avatar {
vertical-align: top;
}
.openerp .navbar .oe_dropdown_arrow:after {
border-top: 4px solid white;
}
.openerp .navbar .dropdown_menu {
top: 32px;
background: #333333;
background: rgba(37, 37, 37, 0.9);
border-color: #999999;
border-color: rgba(0, 0, 0, 0.2);
border-style: solid;
border-width: 0 2px 1px;
-moz-border-radius: 0 0 6px 6px;
-webkit-border-radius: 0 0 6px 6px;
border-radius: 0 0 6px 6px;
-webkit-background-clip: padding-box;
-moz-background-clip: padding-box;
background-clip: padding-box;
}
.openerp .navbar .dropdown_menu li {
float: none;
padding: 3px 12px;
}
.openerp .navbar .dropdown_menu li a {
color: #eeeeee;
}
.openerp .navbar .dropdown_menu li:hover {
background-color: #212121;
background-image: -webkit-gradient(linear, left top, left bottom, from(#292929), to(#191919));
background-image: -webkit-linear-gradient(top, #292929, #191919);
background-image: -moz-linear-gradient(top, #292929, #191919);
background-image: -ms-linear-gradient(top, #292929, #191919);
background-image: -o-linear-gradient(top, #292929, #191919);
background-image: linear-gradient(to bottom, #292929, #191919);
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
.openerp .navbar .oe_topbar_name {
max-width: 150px;
display: inline-block;
height: 15px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.openerp .nav li a {
padding: 6px 8px 4px 8px;
}
.openerp .oe_user_menu {
float: right;
padding: 0;
margin: 0;
}
.openerp .oe_user_menu li {
list-style-type: none;
float: left;
}
.openerp .oe_user_menu .oe_dropdown_menu {
right: -1px;
}
.openerp .oe_leftbar {
display: none;
width: 220px;
@ -3114,7 +3001,6 @@
top: 0px;
}
}
.kitten-mode-activated {
background-size: cover;
background-attachment: fixed;

View File

@ -158,6 +158,37 @@ $sheet-padding: 16px
#oe_main_menu_navbar.navbar
margin-bottom: 0px
.oe_systray
margin-right: 0px !important
// Notifications {{{
.oe_notification
z-index: 1600
.oe_webclient_timezone_notification
a
color: white
text-decoration: underline
p
margin-top: 1em
dt
font-weight: bold
.oe_timezone_systray
span
margin-top: 1px
background-color: #f6cf3b
// }}}
// Top Menu {{{
.navbar
.oe_topbar_name
max-width: 150px
display: inline-block
height: 15px // Customize to manage caret when topbar_name is over sized.
text-overflow: ellipsis
white-space: nowrap
overflow: hidden // Customize to bring ellipsis when topbar_name is over sized.
// }}}
.openerp
// Global style {{{
padding: 0
@ -690,23 +721,6 @@ $sheet-padding: 16px
border-bottom-right-radius: 8px
border-bottom-left-radius: 8px
// }}}
// Notifications {{{
.oe_notification
z-index: 1500
.oe_webclient_timezone_notification
a
color: white
text-decoration: underline
p
margin-top: 1em
dt
font-weight: bold
.oe_timezone_systray
span
margin-top: 1px
background-color: #f6cf3b
// }}}
// CrashManager {{{
.oe_dialog_warning
width: 100%
@ -738,95 +752,6 @@ $sheet-padding: 16px
.oe_topbar, .oe_leftbar
display: none
// }}}
// Top Menu {{{
.navbar
.oe_topbar_anonymous_login
background-color: #dc5f59
color: #eeeeee
@include vertical-gradient(#FC8787, #800000)
a
display: block
padding: 5px 10px 7px
line-height: 20px
height: 30px
text-decoration: none
color: white
background: transparent
@include transition(all 0.2s ease-out)
a:hover
background: rgba(0,0,0,0.1)
color: white
text-shadow: 0px 0px 3px rgba(0,0,0,0.2)
@include box-shadow(0 1px 2px rgba(0,0,0,0.2) inset)
.oe_topbar_item
display: block
padding: 5px 10px 26px
line-height: 20px
height: 20px
text-decoration: none
color: #eee
vertical-align: top
text-shadow: 0 1px 1px rgba(0,0,0,0.2)
@include transition(all 0.2s ease-out)
&:hover
background: rgba(0,0,0,0.2)
text-shadow: black 0px 0px 3px
color: white
@include box-shadow(0 1px 2px rgba(0,0,0,0.4) inset)
.oe_topbar_avatar
width: 24px
height: 24px
margin: -2px 2px 0 0
@include radius(3px)
.oe_topbar_avatar
vertical-align: top
.oe_dropdown_arrow:after
border-top: 4px solid white
.dropdown_menu
top: 32px
background: #333
background: rgba(37,37,37,0.9)
border-color: #999
border-color: rgba(0, 0, 0, 0.2)
border-style: solid
border-width: 0 2px 1px
@include radius(0 0 6px 6px)
@include background-clip()
li
float: none
padding: 3px 12px
a
color: #eee
&:hover
@include vertical-gradient(#292929, #191919)
@include box-shadow(none)
.oe_topbar_name
max-width: 150px
display: inline-block
height: 15px // Customize to manage caret when topbar_name is over sized.
text-overflow: ellipsis
white-space: nowrap
overflow: hidden // Customize to bring ellipsis when topbar_name is over sized.
// oe menu is the list of the buttons on the left side of the bar.
// So why aren't the buttons oe_topbar_items ? This sad state of affairs
// is a leftover from an uncomplete refactoring when the left and top menu
// were merged. You are welcome to refactor and clean this up
.nav li a
padding: 6px 8px 4px 8px
.oe_user_menu
float: right
padding: 0
margin: 0
li
list-style-type: none
float: left
.oe_dropdown_menu
right: -1px
// }}}
// Webclient.leftbar {{{
.oe_leftbar
display: none

View File

@ -65,7 +65,7 @@ class sale_quote(http.Controller):
if token != order.access_token:
return request.website.render('website.404')
attachments=sign and [('signature.png', sign.decode('base64'))] or []
order_obj.signal_order_confirm(request.cr, SUPERUSER_ID, [order_id], context=request.context)
order_obj.signal_workflow(request.cr, SUPERUSER_ID, [order_id], 'order_confirm', context=request.context)
message = _('Order signed by %s') % (signer,)
self.__message_post(message, order_id, type='comment', subtype='mt_comment', attachments=attachments)
return True

View File

@ -8,7 +8,7 @@ msgstr ""
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
"PO-Revision-Date: 2013-11-24 14:57+0000\n"
"Last-Translator: krnkris <Unknown>\n"
"Last-Translator: krnkris <krnkris@freemail.hu>\n"
"Language-Team: Hungarian <openerp-hungarian-team@lists.launchpad.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -103,7 +103,7 @@ msgstr "Indiai bérszámfejtés"
#: help:ir.cron,model:0
msgid ""
"Model name on which the method to be called is located, e.g. 'res.partner'."
msgstr "Modell név ahogyan az megnevezve megtalálható, p.l. 'res.partner'."
msgstr "Modell név elnevezése szerint megtalálható, p.l. 'res.partner'."
#. module: base
#: view:ir.module.module:0
@ -4000,7 +4000,7 @@ msgstr "Időszakos értékelések, Felbecsülések, Felmérések"
#: model:ir.actions.act_window,name:base.ir_property_form
#: model:ir.ui.menu,name:base.menu_ir_property_form_all
msgid "Configuration Parameters"
msgstr "Konfiguráció Paraméterek"
msgstr "Beállítási Paaraméterek"
#. module: base
#: constraint:ir.cron:0
@ -4171,9 +4171,9 @@ msgid ""
"separated list of valid field names (optionally followed by asc/desc for the "
"direction)"
msgstr ""
"Invalid \"order\" specified. A valid \"order\" specification is a comma-"
"separated list of valid field names (optionally followed by asc/desc for the "
"direction)"
"Érvénytelen \"megrendelés\" meghatározás. Az érvénnyes \"megrendelés\" egy vesszővel"
"elválasztott lista érvényes mező nevekkel (választhatóan növekvő/csökkenő sorrendbe "
"állítva)"
#. module: base
#: model:ir.model,name:base.model_ir_module_module_dependency
@ -4217,7 +4217,7 @@ msgstr ""
#. module: base
#: model:res.groups,name:base.group_survey_user
msgid "Survey / User"
msgstr "Felmérés / felhasználó"
msgstr "Felmérés / Felhasználó"
#. module: base
#: view:ir.module.module:0

View File

@ -848,9 +848,9 @@ class ir_actions_server(osv.osv):
def run_action_trigger(self, cr, uid, action, eval_context=None, context=None):
""" Trigger a workflow signal, depending on the use_relational_model:
- `base`: base_model_pool.signal_<TRIGGER_NAME>(cr, uid, context.get('active_id'))
- `base`: base_model_pool.signal_workflow(cr, uid, context.get('active_id'), <TRIGGER_NAME>)
- `relational`: find the related model and object, using the relational
field, then target_model_pool.signal_<TRIGGER_NAME>(cr, uid, target_id)
field, then target_model_pool.signal_workflow(cr, uid, target_id, <TRIGGER_NAME>)
"""
obj_pool = self.pool[action.model_id.model]
if action.use_relational_model == 'base':

View File

@ -756,7 +756,7 @@ class Environment(object):
"""
if not spec:
return
for env in list(self.all):
for env in list(iter(self.all)):
c = env.cache
for field, ids in spec:
if ids is None:
@ -769,7 +769,7 @@ class Environment(object):
def invalidate_all(self):
""" Clear the cache of all environments. """
for env in list(self.all):
for env in list(iter(self.all)):
env.cache.clear()
env.prefetch.clear()
env.computed.clear()

View File

@ -1145,11 +1145,14 @@ class Root(object):
"""Root WSGI application for the OpenERP Web Client.
"""
def __init__(self):
self._loaded = False
@lazy_property
def session_store(self):
# Setup http sessions
path = openerp.tools.config.session_dir
_logger.debug('HTTP sessions stored in: %s', path)
self.session_store = werkzeug.contrib.sessions.FilesystemSessionStore(path, session_class=OpenERPSession)
self._loaded = False
return werkzeug.contrib.sessions.FilesystemSessionStore(path, session_class=OpenERPSession)
@lazy_property
def nodb_routing_map(self):

View File

@ -629,76 +629,8 @@ class BaseModel(object):
if col._type == 'float':
cls._columns[key] = copy.copy(col)
# link the class to the registry, and update the registry
cls.pool = pool
# Note: we have to insert an instance into the registry now, because it
# can trigger some stuff on other models which expect this new instance
# (like method _inherits_reload_src())
# instantiate the model, and initialize it
model = object.__new__(cls)
cls._model = model # backward compatibility
pool.add(name, model)
# determine description, table, sequence and log_access
if not cls._description:
cls._description = cls._name
if not cls._table:
cls._table = cls._name.replace('.', '_')
if not cls._sequence:
cls._sequence = cls._table + '_id_seq'
if not hasattr(cls, '_log_access'):
# If _log_access is not specified, it is the same value as _auto.
cls._log_access = cls._auto
# Transience
if cls.is_transient():
cls._transient_check_count = 0
cls._transient_max_count = config.get('osv_memory_count_limit')
cls._transient_max_hours = config.get('osv_memory_age_limit')
assert cls._log_access, \
"TransientModels must have log_access turned on, " \
"in order to implement their access rights policy"
# retrieve new-style fields and duplicate them (to avoid clashes with
# inheritance between different models)
cls._fields = {}
for attr, field in getmembers(cls, Field.__instancecheck__):
if not field._origin:
cls._add_field(attr, field.copy())
# introduce magic fields
cls._add_magic_fields()
# register stuff about low-level function fields and custom fields
cls._init_function_fields(pool, cr)
cls._init_manual_fields(pool, cr)
# process _inherits
cls._inherits_check()
cls._inherits_reload()
# register constraints and onchange methods
cls._init_constraints_onchanges()
# check defaults
for k in cls._defaults:
assert k in cls._fields, \
"Model %s has a default for nonexiting field %s" % (cls._name, k)
# restart columns
for column in cls._columns.itervalues():
column.restart()
# validate rec_name
if cls._rec_name:
assert cls._rec_name in cls._fields, \
"Invalid rec_name %s for model %s" % (cls._rec_name, cls._name)
elif 'name' in cls._fields:
cls._rec_name = 'name'
# prepare ormcache, which must be shared by all instances of the model
cls._ormcache = {}
# complete the initialization of model
model.__init__(pool, cr)
return model
@ -818,8 +750,81 @@ class BaseModel(object):
return None
def __init__(self, pool, cr):
# this method no longer does anything; kept for backward compatibility
pass
""" Initialize a model and make it part of the given registry.
- copy the stored fields' functions in the registry,
- retrieve custom fields and add them in the model,
- ensure there is a many2one for each _inherits'd parent,
- update the children's _columns,
- give a chance to each field to initialize itself.
"""
cls = type(self)
# link the class to the registry, and update the registry
cls.pool = pool
cls._model = self # backward compatibility
pool.add(cls._name, self)
# determine description, table, sequence and log_access
if not cls._description:
cls._description = cls._name
if not cls._table:
cls._table = cls._name.replace('.', '_')
if not cls._sequence:
cls._sequence = cls._table + '_id_seq'
if not hasattr(cls, '_log_access'):
# If _log_access is not specified, it is the same value as _auto.
cls._log_access = cls._auto
# Transience
if cls.is_transient():
cls._transient_check_count = 0
cls._transient_max_count = config.get('osv_memory_count_limit')
cls._transient_max_hours = config.get('osv_memory_age_limit')
assert cls._log_access, \
"TransientModels must have log_access turned on, " \
"in order to implement their access rights policy"
# retrieve new-style fields and duplicate them (to avoid clashes with
# inheritance between different models)
cls._fields = {}
for attr, field in getmembers(cls, Field.__instancecheck__):
if not field._origin:
cls._add_field(attr, field.copy())
# introduce magic fields
cls._add_magic_fields()
# register stuff about low-level function fields and custom fields
cls._init_function_fields(pool, cr)
cls._init_manual_fields(pool, cr)
# process _inherits
cls._inherits_check()
cls._inherits_reload()
# register constraints and onchange methods
cls._init_constraints_onchanges()
# check defaults
for k in cls._defaults:
assert k in cls._fields, \
"Model %s has a default for nonexiting field %s" % (cls._name, k)
# restart columns
for column in cls._columns.itervalues():
column.restart()
# validate rec_name
if cls._rec_name:
assert cls._rec_name in cls._fields, \
"Invalid rec_name %s for model %s" % (cls._rec_name, cls._name)
elif 'name' in cls._fields:
cls._rec_name = 'name'
# prepare ormcache, which must be shared by all instances of the model
cls._ormcache = {}
def __export_xml_id(self):
""" Return a valid xml_id for the record `self`. """
@ -3013,7 +3018,7 @@ class BaseModel(object):
if not fields:
fields = filter(valid, self._fields)
else:
invalid_fields = list(set(filter(lambda name: not valid(name), fields)))
invalid_fields = set(filter(lambda name: not valid(name), fields))
if invalid_fields:
_logger.warning('Access Denied by ACLs for operation: %s, uid: %s, model: %s, fields: %s',
operation, user, self._name, ', '.join(invalid_fields))
@ -3231,8 +3236,16 @@ class BaseModel(object):
record._cache.update(record._convert_to_cache(vals))
# store failed values in cache for the records that could not be read
missing = self - self.browse(ids)
fetched = self.browse(ids)
missing = self - fetched
if missing:
extras = fetched - self
if extras:
raise AccessError(
_("Database fetch misses ids ({}) and has extra ids ({}), may be caused by a type incoherence in a previous request").format(
', '.join(map(repr, missing._ids)),
', '.join(map(repr, extras._ids)),
))
# store an access error exception in existing records
exc = AccessError(
_('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') % \
@ -3273,7 +3286,7 @@ class BaseModel(object):
self._cr.execute(query, (self._name, tuple(self.ids)))
res = self._cr.dictfetchall()
uids = list(set(r[k] for r in res for k in ['write_uid', 'create_uid'] if r.get(k)))
uids = set(r[k] for r in res for k in ['write_uid', 'create_uid'] if r.get(k))
names = dict(self.env['res.users'].browse(uids).name_get())
for r in res:
@ -3496,7 +3509,7 @@ class BaseModel(object):
for order, obj_name, store_ids, fields in result_store:
if obj_name == self._name:
effective_store_ids = list(set(store_ids) - set(ids))
effective_store_ids = set(store_ids) - set(ids)
else:
effective_store_ids = store_ids
if effective_store_ids:
@ -4937,19 +4950,6 @@ class BaseModel(object):
""" stuff to do right after the registry is built """
pass
def __getattr__(self, name):
if name.startswith('signal_'):
# self.signal_XXX() sends signal XXX to the record's workflow
signal_name = name[7:]
assert signal_name
return (lambda *args, **kwargs:
self.signal_workflow(*args, signal=signal_name, **kwargs))
get = getattr(super(BaseModel, self), '__getattr__', None)
if get is None:
raise AttributeError("%r has no attribute %r" % (type(self).__name__, name))
return get(name)
def _patch_method(self, name, method):
""" Monkey-patch a method for all instances of this model. This replaces
the method called `name` by `method` in `self`'s class.
@ -5407,7 +5407,7 @@ class BaseModel(object):
""" If `field` must be recomputed on some record in `self`, return the
corresponding records that must be recomputed.
"""
for env in [self.env] + list(self.env.all):
for env in [self.env] + list(iter(self.env.all)):
if env.todo.get(field) and env.todo[field] & self:
return env.todo[field]
@ -5429,7 +5429,7 @@ class BaseModel(object):
""" Recompute stored function fields. The fields and records to
recompute have been determined by method :meth:`modified`.
"""
for env in list(self.env.all):
for env in list(iter(self.env.all)):
while env.todo:
field, recs = next(env.todo.iteritems())
# evaluate the fields to recompute, and save them to database

View File

@ -43,7 +43,7 @@ MANIFEST = '__openerp__.py'
_logger = logging.getLogger(__name__)
# addons path as a list
ad_paths = [tools.config.addons_data_dir]
ad_paths = []
hooked = False
# Modules already loaded
@ -89,6 +89,10 @@ def initialize_sys_path():
global ad_paths
global hooked
dd = tools.config.addons_data_dir
if dd not in ad_paths:
ad_paths.append(dd)
for ad in tools.config['addons_path'].split(','):
ad = os.path.abspath(tools.ustr(ad.strip()))
if ad not in ad_paths:

View File

@ -30,7 +30,7 @@ RELEASE_LEVELS_DISPLAY = {ALPHA: ALPHA,
# properly comparable using normal operarors, for example:
# (6,1,0,'beta',0) < (6,1,0,'candidate',1) < (6,1,0,'candidate',2)
# (6,1,0,'candidate',2) < (6,1,0,'final',0) < (6,1,2,'final',0)
version_info = (8, 0, 0, ALPHA, 1)
version_info = (8, 0, 0, RELEASE_CANDIDATE, 1)
version = '.'.join(map(str, version_info[:2])) + RELEASE_LEVELS_DISPLAY[version_info[3]] + str(version_info[4] or '')
series = serie = major_version = '.'.join(map(str, version_info[:2]))

View File

@ -61,7 +61,10 @@ def check_ssl():
DEFAULT_LOG_HANDLER = [':INFO']
def _get_default_datadir():
return appdirs.user_data_dir(appname='OpenERP', appauthor=release.author)
home = os.path.expanduser('~')
func = appdirs.user_data_dir if os.path.exists(home) else appdirs.site_data_dir
# No "version" kwarg as session and filestore paths are shared against series
return func(appname='Odoo', appauthor=release.author)
class configmanager(object):
def __init__(self, fname=None):
@ -649,7 +652,7 @@ class configmanager(object):
@property
def session_dir(self):
d = os.path.join(self['data_dir'], 'sessions', release.series)
d = os.path.join(self['data_dir'], 'sessions')
if not os.path.exists(d):
os.makedirs(d, 0700)
else: