diff --git a/addons/account/partner.py b/addons/account/partner.py
index f582da6b765..a7df31b2f32 100644
--- a/addons/account/partner.py
+++ b/addons/account/partner.py
@@ -189,44 +189,34 @@ class res_partner(osv.osv):
'debit': fields.function(_credit_debit_get, fnct_search=_debit_search, string='Total Payable', multi='dc', help="Total amount you have to pay to this supplier."),
'debit_limit': fields.float('Payable Limit'),
'property_account_payable': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Account Payable",
- view_load=True,
domain="[('type', '=', 'payable')]",
help="This account will be used instead of the default one as the payable account for the current partner",
required=True),
'property_account_receivable': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Account Receivable",
- view_load=True,
domain="[('type', '=', 'receivable')]",
help="This account will be used instead of the default one as the receivable account for the current partner",
required=True),
'property_account_position': fields.property(
- 'account.fiscal.position',
type='many2one',
relation='account.fiscal.position',
string="Fiscal Position",
- view_load=True,
help="The fiscal position will determine taxes and accounts used for the partner.",
),
'property_payment_term': fields.property(
- 'account.payment.term',
type='many2one',
relation='account.payment.term',
string ='Customer Payment Term',
- view_load=True,
help="This payment term will be used instead of the default one for sale orders and customer invoices"),
'property_supplier_payment_term': fields.property(
- 'account.payment.term',
type='many2one',
relation='account.payment.term',
string ='Supplier Payment Term',
- view_load=True,
help="This payment term will be used instead of the default one for purchase orders and supplier invoices"),
'ref_companies': fields.one2many('res.company', 'partner_id',
'Companies that refers to partner'),
diff --git a/addons/account/product.py b/addons/account/product.py
index 3df3ad9bd17..b7bffee43a9 100644
--- a/addons/account/product.py
+++ b/addons/account/product.py
@@ -25,18 +25,14 @@ class product_category(osv.osv):
_inherit = "product.category"
_columns = {
'property_account_income_categ': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Income Account",
- view_load=True,
help="This account will be used for invoices to value sales."),
'property_account_expense_categ': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Expense Account",
- view_load=True,
help="This account will be used for invoices to value expenses."),
}
@@ -54,18 +50,14 @@ class product_template(osv.osv):
'product_supplier_taxes_rel', 'prod_id', 'tax_id',
'Supplier Taxes', domain=[('parent_id', '=', False),('type_tax_use','in',['purchase','all'])]),
'property_account_income': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Income Account",
- view_load=True,
help="This account will be used for invoices instead of the default one to value sales for the current product."),
'property_account_expense': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Expense Account",
- view_load=True,
help="This account will be used for invoices instead of the default one to value expenses for the current product."),
}
diff --git a/addons/account_anglo_saxon/__openerp__.py b/addons/account_anglo_saxon/__openerp__.py
index 7ac4bdbd71e..4fc15bba4f5 100644
--- a/addons/account_anglo_saxon/__openerp__.py
+++ b/addons/account_anglo_saxon/__openerp__.py
@@ -44,7 +44,7 @@ account.""",
'category': 'Accounting & Finance',
'demo': [],
'data': ['product_view.xml'],
- 'test': ['test/anglo_saxon.yml'],
+ 'test': ['test/anglo_saxon.yml', 'test/anglo_saxon_avg_fifo.yml'],
'auto_install': False,
'installable': True,
}
diff --git a/addons/account_anglo_saxon/invoice.py b/addons/account_anglo_saxon/invoice.py
index f27d9b3ae72..8b31a48b92b 100644
--- a/addons/account_anglo_saxon/invoice.py
+++ b/addons/account_anglo_saxon/invoice.py
@@ -117,21 +117,27 @@ class account_invoice_line(osv.osv):
for line in res:
if a == line['account_id'] and i_line.product_id.id == line['product_id']:
uom = i_line.product_id.uos_id or i_line.product_id.uom_id
- standard_price = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, i_line.product_id.standard_price, i_line.uos_id.id)
- if standard_price != i_line.price_unit and line['price_unit'] == i_line.price_unit and acc:
- price_diff = i_line.price_unit - standard_price
- line.update({'price':standard_price * line['quantity']})
+ valuation_price_unit = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, i_line.product_id.standard_price, i_line.uos_id.id)
+ if i_line.product_id.cost_method != 'standard' and i_line.purchase_line_id:
+ #for average/fifo/lifo costing method, fetch real cost price from incomming moves
+ stock_move_obj = self.pool.get('stock.move')
+ valuation_stock_move = stock_move_obj.search(cr, uid, [('purchase_line_id', '=', i_line.purchase_line_id.id)], limit=1, context=context)
+ if valuation_stock_move:
+ valuation_price_unit = stock_move_obj.browse(cr, uid, valuation_stock_move[0], context=context).price_unit
+ if valuation_price_unit != i_line.price_unit and line['price_unit'] == i_line.price_unit and acc:
+ price_diff = i_line.price_unit - valuation_price_unit
+ line.update({'price': valuation_price_unit * line['quantity']})
diff_res.append({
- 'type':'src',
+ 'type': 'src',
'name': i_line.name[:64],
- 'price_unit':price_diff,
- 'quantity':line['quantity'],
+ 'price_unit': price_diff,
+ 'quantity': line['quantity'],
'price': price_diff * line['quantity'],
- 'account_id':acc,
- 'product_id':line['product_id'],
- 'uos_id':line['uos_id'],
- 'account_analytic_id':line['account_analytic_id'],
- 'taxes':line.get('taxes',[]),
+ 'account_id': acc,
+ 'product_id': line['product_id'],
+ 'uos_id': line['uos_id'],
+ 'account_analytic_id': line['account_analytic_id'],
+ 'taxes': line.get('taxes', []),
})
res += diff_res
return res
diff --git a/addons/account_anglo_saxon/product.py b/addons/account_anglo_saxon/product.py
index b52d9ed3bbd..1c9e8ee3673 100644
--- a/addons/account_anglo_saxon/product.py
+++ b/addons/account_anglo_saxon/product.py
@@ -24,27 +24,21 @@ class product_category(osv.osv):
_inherit = "product.category"
_columns = {
'property_account_creditor_price_difference_categ': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Price Difference Account",
- view_load=True,
help="This account will be used to value price difference between purchase price and cost price."),
#Redefine fields to change help text for anglo saxon methodology.
'property_account_income_categ': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Income Account",
- view_load=True,
help="This account will be used to value outgoing stock using sale price."),
'property_account_expense_categ': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Expense Account",
- view_load=True,
help="This account will be used to value outgoing stock using cost price."),
}
@@ -53,27 +47,21 @@ class product_template(osv.osv):
_inherit = "product.template"
_columns = {
'property_account_creditor_price_difference': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Price Difference Account",
- view_load=True,
help="This account will be used to value price difference between purchase price and cost price."),
#Redefine fields to change help text for anglo saxon methodology.
'property_account_income': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Income Account",
- view_load=True,
help="This account will be used to value outgoing stock using sale price."),
'property_account_expense': fields.property(
- 'account.account',
type='many2one',
relation='account.account',
string="Expense Account",
- view_load=True,
help="This account will be used to value outgoing stock using cost price."),
}
diff --git a/addons/account_anglo_saxon/purchase.py b/addons/account_anglo_saxon/purchase.py
index c10a2a97d80..fc36dab41c2 100644
--- a/addons/account_anglo_saxon/purchase.py
+++ b/addons/account_anglo_saxon/purchase.py
@@ -26,16 +26,15 @@ class purchase_order(osv.osv):
_inherit = "purchase.order"
_description = "Purchase Order"
- def _prepare_inv_line(self, cr, uid, account_id, order_line, context=None):
- line = super(purchase_order, self)._prepare_inv_line(cr, uid, account_id, order_line, context=context)
+ def _choose_account_from_po_line(self, cr, uid, order_line, context=None):
+ account_id = super(purchase_order, self)._choose_account_from_po_line(cr, uid, order_line, context=context)
if order_line.product_id and not order_line.product_id.type == 'service':
acc_id = order_line.product_id.property_stock_account_input and order_line.product_id.property_stock_account_input.id
if not acc_id:
acc_id = order_line.product_id.categ_id.property_stock_account_input_categ and order_line.product_id.categ_id.property_stock_account_input_categ.id
if acc_id:
fpos = order_line.order_id.fiscal_position or False
- new_account_id = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, acc_id)
- line.update({'account_id': new_account_id})
- return line
+ account_id = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, acc_id)
+ return account_id
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_anglo_saxon/test/anglo_saxon.yml b/addons/account_anglo_saxon/test/anglo_saxon.yml
index 9e46aa52b12..6e9ebc0068e 100644
--- a/addons/account_anglo_saxon/test/anglo_saxon.yml
+++ b/addons/account_anglo_saxon/test/anglo_saxon.yml
@@ -109,7 +109,7 @@
-
!record {model: purchase.order, id: purchase_order_001}:
partner_id: base.res_partner_3
- location_id: stock.stock_location_3
+ location_id: stock.stock_location_stock
pricelist_id: 1
order_line:
- product_id: product.product_product_3
@@ -128,12 +128,12 @@
partial_id = self.create(cr, uid, {},context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]})
self.do_partial(cr, uid, [partial_id])
-
- I check the Stock Interim account (Received) is credit successfully.
+ I check the Stock Interim account (Received) is credited successfully.
-
!assert {model: account.account, id : account_anglo_stock_input, string : Stock Interim account (Received) is not credited successfully.}:
- credit == 9
-
- I check the Stock valuation account is debit sucessfully.
+ I check the Stock valuation account is debited sucessfully.
-
!assert {model: account.account, id : account_anglo_stock_valuation, string : Stock valuation account is not debited successfully.}:
- debit == 9
@@ -192,7 +192,7 @@
invoice_state: 2binvoiced
move_lines:
- company_id: base.main_company
- location_id: stock.stock_location_3
+ location_id: stock.stock_location_stock
product_id: product.product_product_3
product_qty: 1.0
product_uom: product.product_uom_unit
diff --git a/addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml b/addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml
new file mode 100644
index 00000000000..f7d52f4f5a8
--- /dev/null
+++ b/addons/account_anglo_saxon/test/anglo_saxon_avg_fifo.yml
@@ -0,0 +1,304 @@
+-
+ In order to test anglo_saxon Configure Different Accounts.
+-
+ !record {model: account.account, id: account_anglo_stock_valuation_fifo}:
+ code: X3000f
+ name: Stock Valuation Account- (test)
+ parent_id: account.cas
+ type: other
+ user_type: account.data_account_type_asset
+-
+ Configure Stock Interim account (Received).
+-
+ !record {model: account.account, id: account_anglo_stock_input_fifo}:
+ code: X2800f
+ name: Stock Interim account (Received)
+ parent_id: account.cos
+ type: other
+ user_type: account.data_account_type_expense
+-
+ Configure Stock Interim account (Delivered).
+-
+ !record {model: account.account, id: account_anglo_stock_output_fifo}:
+ code: X2801f
+ name: Stock Interim account (Delivered)
+ parent_id: account.rev
+ type: other
+ user_type: account.data_account_type_income
+-
+ Configure Price difference creditor Account.
+-
+ !record {model: account.account, id: account_anglo_price_difference_fifo}:
+ code: X7095f
+ name: Price difference creditor Account
+ parent_id: account.cos
+ type: other
+ user_type: account.data_account_type_expense
+-
+ Configure Cash Bank Account.
+-
+ !record {model: account.account, id: account_anglo_cash_fifo}:
+ code: X5000f
+ name: Cash/Bank Account
+ parent_id: account.cash
+ type: other
+ user_type: account.data_account_type_asset
+-
+ Configure Creditor Account Payable.
+-
+ !record {model: account.account, id: account_anglo_payable_fifo}:
+ code: X440001f
+ name: Creditor Account Payable
+ parent_id: account.a_pay
+ type: other
+ user_type: account.data_account_type_payable
+-
+ Configure Debtor Account Receivable.
+-
+ !record {model: account.account, id: account_anglo_receivable_fifo}:
+ code: X400001f
+ name: Debtor Account Receivable
+ parent_id: account.a_recv
+ type: other
+ user_type: account.data_account_type_receivable
+-
+ Configure Cost of Good sale Account.
+-
+ !record {model: account.account, id: account_anglo_cogs_fifo}:
+ code: X7000f
+ name: Cost of goods sale account
+ parent_id: account.o_expense
+ type: other
+ user_type: account.data_account_type_expense
+-
+ Configure Income Account.
+-
+ !record {model: account.account, id: account_anglo_income_fifo}:
+ code: X8000f
+ name: Income Account
+ parent_id: account.o_income
+ type: other
+ user_type: account.data_account_type_income
+-
+ I configure the account receivable of supplier
+-
+ !record {model: res.partner, id: base.res_partner_3}:
+ property_account_payable: account_anglo_payable_fifo
+ property_account_receivable: account_anglo_receivable_fifo
+-
+ I configure the account receivable of Customer.
+-
+ !record {model: res.partner, id: base.res_partner_13}:
+ property_account_payable: account_anglo_payable_fifo
+ property_account_receivable: account_anglo_receivable_fifo
+-
+ I configure the product category with stock valuation account.
+-
+ !record {model: product.category, id: product.product_category_4}:
+ property_stock_valuation_account_id: account_anglo_stock_valuation_fifo
+-
+ I create a product with required accounts, and cost method average (but same applies for fifo)
+-
+ !record {model: product.product, id: product_fifo_anglo_saxon}:
+ name: 'FIFO product for anglo saxon tests'
+ list_price: 20.00
+ standard_price: 0
+ categ_id: product.product_category_4
+ valuation: 'real_time'
+ property_account_income: account_anglo_income_fifo
+ property_account_expense: account_anglo_cogs_fifo
+ property_account_creditor_price_difference: account_anglo_price_difference_fifo
+ property_stock_account_input: account_anglo_stock_input_fifo
+ property_stock_account_output: account_anglo_stock_output_fifo
+ cost_method: 'average'
+-
+ I create a draft Purchase Order.
+-
+ !record {model: purchase.order, id: purchase_order_001_fifo}:
+ partner_id: base.res_partner_3
+ location_id: stock.stock_location_stock
+ pricelist_id: 1
+ order_line:
+ - product_id: product_fifo_anglo_saxon
+ product_qty: 1
+ price_unit: 9
+ date_planned: '2013-08-31'
+ taxes_id: []
+-
+ I confirm the purchase order.
+-
+ !workflow {model: purchase.order, ref: purchase_order_001_fifo, action: purchase_confirm}
+-
+ Reception is ready for process so now done the reception.
+-
+ !python {model: stock.partial.picking}: |
+ pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_001_fifo")).picking_ids
+ partial_id = self.create(cr, uid, {},context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]})
+ self.do_partial(cr, uid, [partial_id])
+-
+ I check the Stock Interim account (Received) is credit successfully.
+-
+ !assert {model: account.account, id : account_anglo_stock_input_fifo, string : Stock Interim account (Received) is not credited successfully.}:
+ - credit == 9
+-
+ I check the Stock valuation account is debit sucessfully.
+-
+ !assert {model: account.account, id : account_anglo_stock_valuation_fifo, string : Stock valuation account is not debited successfully.}:
+ - debit == 9
+-
+ I Validate Invoice of Purchase Order after having changed the price to 10.
+-
+ !python {model: purchase.order}: |
+ invoice_ids = [x.id for x in self.browse(cr, uid, ref("purchase_order_001_fifo")).invoice_ids]
+ line_ids = self.pool.get('account.invoice.line').search(cr, uid, [('invoice_id', 'in', invoice_ids)])
+ self.pool.get('account.invoice.line').write(cr, uid, line_ids, {'price_unit': 10})
+ self.pool.get('account.invoice').signal_invoice_open(cr, uid, invoice_ids)
+-
+ I check the Stock Interim account (Received) is debited sucessfully when Invoice validated.
+-
+ !assert {model: account.account, id : account_anglo_stock_input_fifo, string : Stock Interim account (Received) is not debited successfully.}:
+ - debit == 9
+-
+ I check the Price difference creditor Account is debited sucessfully when Invoice validated.
+-
+ !assert {model: account.account, id : account_anglo_price_difference_fifo, string : Price difference creditor Account is not debited successfully.}:
+ - debit == 1
+-
+ I check Payable(creditor) Account is Credited sucessfully when Invoice validated.
+-
+ !assert {model: account.account, id : account_anglo_payable_fifo, string : Payable(creditor) Account is not Credited successfully.}:
+ - credit == 10
+-
+ I pay the invoice.
+-
+ !python {model: purchase.order}: |
+ invoice_ids = self.browse(cr, uid, ref("purchase_order_001_fifo")).invoice_ids
+ order = self.browse(cr, uid, ref("purchase_order_001_fifo"))
+ journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash'), ('company_id', '=', order.company_id.id)], limit=1)
+ for invoice in invoice_ids:
+ invoice.pay_and_reconcile(invoice.amount_total, ref('account_anglo_cash_fifo'), ref('account.period_8'), journal_ids[0], ref('account_anglo_cash_fifo'), ref('account.period_8'), journal_ids[0], name='test')
+-
+ I check Payable(Creditors) Account is Debited sucessfully after invoice paid.
+-
+ !assert {model: account.account, id : account_anglo_payable_fifo, string : Payable(Creditors) Account is not Debited successfully.}:
+ - debit == 10
+-
+ I check Bank/Cash account is credited sucessfully after invoice paid.
+-
+ !assert {model: account.account, id : account_anglo_cash_fifo, string: Bank/Cash account is not credited successfully.}:
+ - credit == 10
+-
+ I create an Outgoing Picking order
+-
+ !record {model: stock.picking, id: stock_picking_out001_fifo}:
+ partner_id: base.res_partner_13
+ invoice_state: 2binvoiced
+ move_lines:
+ - company_id: base.main_company
+ location_id: stock.stock_location_stock
+ product_id: product_fifo_anglo_saxon
+ product_qty: 1.0
+ location_dest_id: stock.stock_location_customers
+ move_type: direct
+ type: out
+-
+ I need to check the availability of the product, So I make my picking order for processing later.
+-
+ !python {model: stock.picking}: |
+ self.draft_force_assign(cr, uid, [ref("stock_picking_out001_fifo")], {"lang": "en_US", "search_default_available":
+ 1, "tz": False, "active_model": "ir.ui.menu", "contact_display": "partner",
+ "active_ids": [ref("stock.menu_action_picking_tree")], "active_id": ref("stock.menu_action_picking_tree"),
+ })
+-
+ I check the product availability, Product is available in the stock and ready to be sent.
+-
+ !python {model: stock.picking}: |
+ self.action_assign(cr, uid, [ref("stock_picking_out001_fifo")], {"lang": "en_US", "search_default_available":
+ 1, "tz": False, "active_model": "ir.ui.menu", "contact_display": "partner",
+ "active_ids": [ref("stock.menu_action_picking_tree")], "active_id": ref("stock.menu_action_picking_tree"),
+ })
+-
+ I process the delivery.
+-
+ !python {model: stock.partial.picking}: |
+ partial_id = self.create(cr, uid, {}, context={'active_model':'stock.picking','active_ids':[ref('stock_picking_out001_fifo')]})
+ self.do_partial(cr, uid, [partial_id])
+-
+ I check Stock Interim account (Delivery) is debited successfully.
+-
+ !assert {model: account.account, id : account_anglo_stock_output_fifo, string : Stock Interim account (Delivery) is not debited successfully.}:
+ - debit == 9
+-
+ I check the Stock valuation account is credited sucessfully.
+-
+ !assert {model: account.account, id : account_anglo_stock_valuation_fifo, string : Stock valuation account is not credited successfully.}:
+ - credit == 9
+-
+ As the Invoice state of the picking order is To be invoiced. I create invoice for my outgoing picking order.
+-
+ !python {model: stock.invoice.onshipping}: |
+ wiz_id = self.create(cr, uid, {'invoice_date': '2013-03-04', 'journal_id': ref('account.sales_journal')},
+ {'active_ids': [ref("stock_picking_out001_fifo")], "active_model": "stock.picking"})
+ self.create_invoice(cr, uid, [wiz_id], {"lang": "en_US",
+ "search_default_available": 1, "tz": False, "active_model": "stock.picking",
+ "contact_display": "partner", "active_ids": [ref("stock_picking_out001_fifo")], "active_id": ref("stock_picking_out001_fifo")})
+-
+ I check that the customer invoice is created successfully.
+-
+ !python {model: account.invoice}: |
+ partner_id = self.pool.get('stock.picking').browse(cr, uid, ref('stock_picking_out001_fifo')).partner_id.id
+ inv_ids = self.search(cr, uid, [('type','=','out_invoice'),('partner_id','=',partner_id)])
+ assert inv_ids, 'No Invoice is generated!'
+-
+ I open the Invoice.
+-
+ !python {model: stock.picking}: |
+ move_name = self.pool.get('stock.picking').browse(cr, uid, ref('stock_picking_out001_fifo')).name
+ account_invoice = self.pool.get('account.invoice').search(cr, uid, [('origin', '=', move_name)])
+ account_invoice_line = self.pool.get('account.invoice.line').search(cr, uid, [('invoice_id', 'in', account_invoice)])
+ self.pool.get('account.invoice.line').write(cr, uid, account_invoice_line, {'invoice_line_tax_id': [(6, 0, [])]})
+ self.pool.get('account.invoice').button_reset_taxes(cr, uid, account_invoice)
+ self.pool.get('account.invoice').signal_invoice_open(cr, uid, account_invoice)
+-
+ I check Income Account is Credited sucessfully when Invoice validated.
+-
+ !assert {model: account.account, id : account_anglo_income_fifo, string : Income Account is not Credited successfully.}:
+ - credit == 20
+-
+ I check Cost of goods sold account for debit.
+-
+ !assert {model: account.account, id : account_anglo_cogs_fifo, string : Cost of goods sale is not Debited successfully.}:
+ - debit == 9
+-
+ I check Stock Interim account (Delivery)
+-
+ !assert {model: account.account, id : account_anglo_stock_output_fifo, string : Stock Interim account (Delivery) is not credited successfully.}:
+ - credit == 9
+-
+ I check Receivable(Debtor) Account for debit.
+-
+ !assert {model: account.account, id : account_anglo_receivable_fifo, string : Receivable(Debtors) Account is not Debited successfully.}:
+ - debit == 20
+-
+ I pay the invoice.
+-
+ !python {model: account.invoice}: |
+ move_name = self.pool.get('stock.picking').browse(cr, uid, ref('stock_picking_out001_fifo')).name
+ account_invoice= self.pool.get('account.invoice').search(cr, uid, [('origin', '=', move_name)])
+ journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash')], limit=1)
+ pay = self.pay_and_reconcile(cr, uid, account_invoice,
+ 20.0, ref('account_anglo_cash_fifo'), ref('account.period_8'),
+ journal_ids[0], ref('account_anglo_cash_fifo'),
+ ref('account.period_8'), journal_ids[0],
+ name='Payment for test customer invoice')
+ assert (pay == True), "Incorrect Payment."
+-
+ I check Receivable(Debtor) Account for credit.
+-
+ !assert {model: account.account, id : account_anglo_receivable_fifo, string : Receivable(Debtors) Account is not Credited successfully.}:
+ - credit == 20
+-
+ I check Bank/Cash account is debited sucessfully after invoice paid.
+-
+ !assert {model: account.account, id : account_anglo_cash_fifo, string: Bank/Cash account is not successfully credited.}:
+ - debit == 20
diff --git a/addons/auth_oauth/controllers/main.py b/addons/auth_oauth/controllers/main.py
index 62eb2e812cc..35a06871696 100644
--- a/addons/auth_oauth/controllers/main.py
+++ b/addons/auth_oauth/controllers/main.py
@@ -7,7 +7,8 @@ from werkzeug.exceptions import BadRequest
import openerp
from openerp import SUPERUSER_ID
-import openerp.addons.web.http as oeweb
+import openerp.addons.web.http as http
+from openerp.addons.web.http import request
from openerp.addons.web.controllers.main import db_monodb, set_cookie_and_redirect, login_and_redirect
from openerp.modules.registry import RegistryManager
@@ -18,7 +19,7 @@ _logger = logging.getLogger(__name__)
#----------------------------------------------------------
def fragment_to_query_string(func):
@functools.wraps(func)
- def wrapper(self, req, **kw):
+ def wrapper(self, **kw):
if not kw:
return """
"""
- return func(self, req, **kw)
+ return func(self, **kw)
return wrapper
#----------------------------------------------------------
# Controller
#----------------------------------------------------------
-class OAuthController(oeweb.Controller):
- _cp_path = '/auth_oauth'
+class OAuthController(http.Controller):
- @oeweb.jsonrequest
- def list_providers(self, req, dbname):
+ @http.route('/auth_oauth/list_providers', type='json', auth='none')
+ def list_providers(self, dbname):
try:
registry = RegistryManager.get(dbname)
with registry.cursor() as cr:
@@ -51,9 +51,9 @@ class OAuthController(oeweb.Controller):
l = []
return l
- @oeweb.httprequest
+ @http.route('/auth_oauth/signin', type='http', auth='none')
@fragment_to_query_string
- def signin(self, req, **kw):
+ def signin(self, **kw):
state = simplejson.loads(kw['state'])
dbname = state['d']
provider = state['p']
@@ -71,7 +71,7 @@ class OAuthController(oeweb.Controller):
url = '/#action=%s' % action
elif menu:
url = '/#menu_id=%s' % menu
- return login_and_redirect(req, *credentials, redirect_url=url)
+ return login_and_redirect(*credentials, redirect_url=url)
except AttributeError:
# auth_signup is not installed
_logger.error("auth_signup not installed on database %s: oauth sign up cancelled." % (dbname,))
@@ -88,14 +88,14 @@ class OAuthController(oeweb.Controller):
_logger.exception("OAuth2: %s" % str(e))
url = "/#action=login&oauth_error=2"
- return set_cookie_and_redirect(req, url)
+ return set_cookie_and_redirect(url)
- @oeweb.httprequest
- def oea(self, req, **kw):
+ @http.route('/auth_oauth/oea', type='http', auth='none')
+ def oea(self, **kw):
"""login user via OpenERP Account provider"""
dbname = kw.pop('db', None)
if not dbname:
- dbname = db_monodb(req)
+ dbname = db_monodb()
if not dbname:
return BadRequest()
@@ -105,7 +105,7 @@ class OAuthController(oeweb.Controller):
try:
model, provider_id = IMD.get_object_reference(cr, SUPERUSER_ID, 'auth_oauth', 'provider_openerp')
except ValueError:
- return set_cookie_and_redirect(req, '/?db=%s' % dbname)
+ return set_cookie_and_redirect('/?db=%s' % dbname)
assert model == 'auth.oauth.provider'
state = {
@@ -115,6 +115,6 @@ class OAuthController(oeweb.Controller):
}
kw['state'] = simplejson.dumps(state)
- return self.signin(req, **kw)
+ return self.signin(**kw)
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/auth_openid/controllers/main.py b/addons/auth_openid/controllers/main.py
index 1fcc34c82a0..a4ef1bfa07b 100644
--- a/addons/auth_openid/controllers/main.py
+++ b/addons/auth_openid/controllers/main.py
@@ -38,6 +38,8 @@ import openerp
from openerp import SUPERUSER_ID
from openerp.modules.registry import RegistryManager
from openerp.addons.web.controllers.main import login_and_redirect, set_cookie_and_redirect
+import openerp.addons.web.http as http
+from openerp.addons.web.http import request
from .. import utils
@@ -88,20 +90,19 @@ class GoogleAppsAwareConsumer(consumer.GenericConsumer):
return super(GoogleAppsAwareConsumer, self).complete(message, endpoint, return_to)
-class OpenIDController(openerp.addons.web.http.Controller):
- _cp_path = '/auth_openid/login'
+class OpenIDController(http.Controller):
_store = filestore.FileOpenIDStore(_storedir)
_REQUIRED_ATTRIBUTES = ['email']
_OPTIONAL_ATTRIBUTES = 'nickname fullname postcode country language timezone'.split()
- def _add_extensions(self, request):
- """Add extensions to the request"""
+ def _add_extensions(self, oidrequest):
+ """Add extensions to the oidrequest"""
sreg_request = sreg.SRegRequest(required=self._REQUIRED_ATTRIBUTES,
optional=self._OPTIONAL_ATTRIBUTES)
- request.addExtension(sreg_request)
+ oidrequest.addExtension(sreg_request)
ax_request = ax.FetchRequest()
for alias in self._REQUIRED_ATTRIBUTES:
@@ -111,7 +112,7 @@ class OpenIDController(openerp.addons.web.http.Controller):
uri = utils.SREG2AX[alias]
ax_request.add(ax.AttrInfo(uri, required=False, alias=alias))
- request.addExtension(ax_request)
+ oidrequest.addExtension(ax_request)
def _get_attributes_from_success_response(self, success_response):
attrs = {}
@@ -133,58 +134,58 @@ class OpenIDController(openerp.addons.web.http.Controller):
attrs[attr] = value
return attrs
- def _get_realm(self, req):
- return req.httprequest.host_url
+ def _get_realm(self):
+ return request.httprequest.host_url
- @openerp.addons.web.http.httprequest
- def verify_direct(self, req, db, url):
- result = self._verify(req, db, url)
+ @http.route('/auth_openid/login/verify_direct', type='http', auth='none')
+ def verify_direct(self, db, url):
+ result = self._verify(db, url)
if 'error' in result:
return werkzeug.exceptions.BadRequest(result['error'])
if result['action'] == 'redirect':
return werkzeug.utils.redirect(result['value'])
return result['value']
- @openerp.addons.web.http.jsonrequest
- def verify(self, req, db, url):
- return self._verify(req, db, url)
+ @http.route('/auth_openid/login/verify', type='json', auth='none')
+ def verify(self, db, url):
+ return self._verify(db, url)
- def _verify(self, req, db, url):
- redirect_to = werkzeug.urls.Href(req.httprequest.host_url + 'auth_openid/login/process')(session_id=req.session_id)
- realm = self._get_realm(req)
+ def _verify(self, db, url):
+ redirect_to = werkzeug.urls.Href(request.httprequest.host_url + 'auth_openid/login/process')(session_id=request.session_id)
+ realm = self._get_realm()
session = dict(dbname=db, openid_url=url) # TODO add origin page ?
oidconsumer = consumer.Consumer(session, self._store)
try:
- request = oidconsumer.begin(url)
+ oidrequest = oidconsumer.begin(url)
except consumer.DiscoveryFailure, exc:
fetch_error_string = 'Error in discovery: %s' % (str(exc[0]),)
return {'error': fetch_error_string, 'title': 'OpenID Error'}
- if request is None:
+ if oidrequest is None:
return {'error': 'No OpenID services found', 'title': 'OpenID Error'}
- req.session.openid_session = session
- self._add_extensions(request)
+ request.session.openid_session = session
+ self._add_extensions(oidrequest)
- if request.shouldSendRedirect():
- redirect_url = request.redirectURL(realm, redirect_to)
- return {'action': 'redirect', 'value': redirect_url, 'session_id': req.session_id}
+ if oidrequest.shouldSendRedirect():
+ redirect_url = oidrequest.redirectURL(realm, redirect_to)
+ return {'action': 'redirect', 'value': redirect_url, 'session_id': request.session_id}
else:
- form_html = request.htmlMarkup(realm, redirect_to)
- return {'action': 'post', 'value': form_html, 'session_id': req.session_id}
+ form_html = oidrequest.htmlMarkup(realm, redirect_to)
+ return {'action': 'post', 'value': form_html, 'session_id': request.session_id}
- @openerp.addons.web.http.httprequest
- def process(self, req, **kw):
- session = getattr(req.session, 'openid_session', None)
+ @http.route('/auth_openid/login/process', type='http', auth='none')
+ def process(self, **kw):
+ session = getattr(request.session, 'openid_session', None)
if not session:
- return set_cookie_and_redirect(req, '/')
+ return set_cookie_and_redirect('/')
oidconsumer = consumer.Consumer(session, self._store, consumer_class=GoogleAppsAwareConsumer)
- query = req.httprequest.args
- info = oidconsumer.complete(query, req.httprequest.base_url)
+ query = request.httprequest.args
+ info = oidconsumer.complete(query, request.httprequest.base_url)
display_identifier = info.getDisplayIdentifier()
session['status'] = info.status
@@ -225,7 +226,7 @@ class OpenIDController(openerp.addons.web.http.Controller):
# TODO fill empty fields with the ones from sreg/ax
cr.commit()
- return login_and_redirect(req, dbname, login, key)
+ return login_and_redirect(dbname, login, key)
session['message'] = 'This OpenID identifier is not associated to any active users'
@@ -241,11 +242,11 @@ class OpenIDController(openerp.addons.web.http.Controller):
# information in a log.
session['message'] = 'Verification failed.'
- return set_cookie_and_redirect(req, '/#action=login&loginerror=1')
+ return set_cookie_and_redirect('/#action=login&loginerror=1')
- @openerp.addons.web.http.jsonrequest
- def status(self, req):
- session = getattr(req.session, 'openid_session', {})
+ @http.route('/auth_openid/login/status', type='json', auth='none')
+ def status(self):
+ session = getattr(request.session, 'openid_session', {})
return {'status': session.get('status'), 'message': session.get('message')}
diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py
index 924e1546862..8c61af1f03c 100644
--- a/addons/auth_signup/controllers/main.py
+++ b/addons/auth_signup/controllers/main.py
@@ -23,14 +23,15 @@ import logging
import openerp
from openerp.modules.registry import RegistryManager
from ..res_users import SignupError
+import openerp.addons.web.http as http
+from openerp.addons.web.http import request
_logger = logging.getLogger(__name__)
-class Controller(openerp.addons.web.http.Controller):
- _cp_path = '/auth_signup'
+class Controller(http.Controller):
- @openerp.addons.web.http.jsonrequest
- def get_config(self, req, dbname):
+ @http.route('/auth_signup/get_config', type='json', auth="none")
+ def get_config(self, dbname):
""" retrieve the module config (which features are enabled) for the login page """
registry = RegistryManager.get(dbname)
with registry.cursor() as cr:
@@ -41,8 +42,8 @@ class Controller(openerp.addons.web.http.Controller):
}
return config
- @openerp.addons.web.http.jsonrequest
- def retrieve(self, req, dbname, token):
+ @http.route('/auth_signup/retrieve', type='json', auth="user")
+ def retrieve(self, dbname, token):
""" retrieve the user info (name, login or email) corresponding to a signup token """
registry = RegistryManager.get(dbname)
with registry.cursor() as cr:
@@ -50,23 +51,23 @@ class Controller(openerp.addons.web.http.Controller):
user_info = res_partner.signup_retrieve_info(cr, openerp.SUPERUSER_ID, token)
return user_info
- @openerp.addons.web.http.jsonrequest
- def signup(self, req, dbname, token, **values):
+ @http.route('/auth_signup/signup', type='json', auth="user")
+ def signup(self, dbname, token, **values):
""" sign up a user (new or existing)"""
try:
- self._signup_with_values(req, dbname, token, values)
+ self._signup_with_values(dbname, token, values)
except SignupError, e:
return {'error': openerp.tools.exception_to_unicode(e)}
return {}
- def _signup_with_values(self, req, dbname, token, values):
+ def _signup_with_values(self, dbname, token, values):
registry = RegistryManager.get(dbname)
with registry.cursor() as cr:
res_users = registry.get('res.users')
res_users.signup(cr, openerp.SUPERUSER_ID, values, token)
- @openerp.addons.web.http.jsonrequest
- def reset_password(self, req, dbname, login):
+ @http.route('/auth_signup/reset_password', type='json', auth="user")
+ def reset_password(self, dbname, login):
""" retrieve user, and perform reset password """
registry = RegistryManager.get(dbname)
with registry.cursor() as cr:
diff --git a/addons/base_gengo/i18n/th.po b/addons/base_gengo/i18n/th.po
new file mode 100644
index 00000000000..e0b5ba3e2fc
--- /dev/null
+++ b/addons/base_gengo/i18n/th.po
@@ -0,0 +1,249 @@
+# Thai translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2013-06-20 13:54+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Thai \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-06-21 05:36+0000\n"
+"X-Generator: Launchpad (build 16677)\n"
+
+#. module: base_gengo
+#: view:res.company:0
+msgid "Comments for Translator"
+msgstr ""
+
+#. module: base_gengo
+#: field:ir.translation,job_id:0
+msgid "Gengo Job ID"
+msgstr ""
+
+#. module: base_gengo
+#: code:addons/base_gengo/wizard/base_gengo_translations.py:114
+#, python-format
+msgid "This language is not supported by the Gengo translation services."
+msgstr ""
+
+#. module: base_gengo
+#: field:res.company,gengo_comment:0
+msgid "Comments"
+msgstr "ความคิดเห็น"
+
+#. module: base_gengo
+#: field:res.company,gengo_private_key:0
+msgid "Gengo Private Key"
+msgstr ""
+
+#. module: base_gengo
+#: model:ir.model,name:base_gengo.model_base_gengo_translations
+msgid "base.gengo.translations"
+msgstr "base.gengo.translations"
+
+#. module: base_gengo
+#: help:res.company,gengo_auto_approve:0
+msgid "Jobs are Automatically Approved by Gengo."
+msgstr ""
+
+#. module: base_gengo
+#: field:base.gengo.translations,lang_id:0
+msgid "Language"
+msgstr "ภาษา"
+
+#. module: base_gengo
+#: field:ir.translation,gengo_comment:0
+msgid "Comments & Activity Linked to Gengo"
+msgstr ""
+
+#. module: base_gengo
+#: code:addons/base_gengo/wizard/base_gengo_translations.py:124
+#, python-format
+msgid "Gengo Sync Translation (Response)"
+msgstr ""
+
+#. module: base_gengo
+#: code:addons/base_gengo/wizard/base_gengo_translations.py:72
+#, python-format
+msgid ""
+"Gengo `Public Key` or `Private Key` are missing. Enter your Gengo "
+"authentication parameters under `Settings > Companies > Gengo Parameters`."
+msgstr ""
+
+#. module: base_gengo
+#: selection:ir.translation,gengo_translation:0
+msgid "Translation By Machine"
+msgstr ""
+
+#. module: base_gengo
+#: code:addons/base_gengo/wizard/base_gengo_translations.py:155
+#, python-format
+msgid ""
+"%s\n"
+"\n"
+"--\n"
+" Commented on %s by %s."
+msgstr ""
+
+#. module: base_gengo
+#: field:ir.translation,gengo_translation:0
+msgid "Gengo Translation Service Level"
+msgstr ""
+
+#. module: base_gengo
+#: constraint:ir.translation:0
+msgid ""
+"The Gengo translation service selected is not supported for this language."
+msgstr ""
+
+#. module: base_gengo
+#: selection:ir.translation,gengo_translation:0
+msgid "Standard"
+msgstr ""
+
+#. module: base_gengo
+#: help:ir.translation,gengo_translation:0
+msgid ""
+"You can select here the service level you want for an automatic translation "
+"using Gengo."
+msgstr ""
+
+#. module: base_gengo
+#: field:base.gengo.translations,restart_send_job:0
+msgid "Restart Sending Job"
+msgstr ""
+
+#. module: base_gengo
+#: view:ir.translation:0
+msgid "To Approve In Gengo"
+msgstr ""
+
+#. module: base_gengo
+#: view:res.company:0
+msgid "Private Key"
+msgstr ""
+
+#. module: base_gengo
+#: view:res.company:0
+msgid "Public Key"
+msgstr ""
+
+#. module: base_gengo
+#: field:res.company,gengo_public_key:0
+msgid "Gengo Public Key"
+msgstr ""
+
+#. module: base_gengo
+#: code:addons/base_gengo/wizard/base_gengo_translations.py:123
+#, python-format
+msgid "Gengo Sync Translation (Request)"
+msgstr ""
+
+#. module: base_gengo
+#: view:ir.translation:0
+msgid "Translations"
+msgstr ""
+
+#. module: base_gengo
+#: field:res.company,gengo_auto_approve:0
+msgid "Auto Approve Translation ?"
+msgstr ""
+
+#. module: base_gengo
+#: model:ir.actions.act_window,name:base_gengo.action_wizard_base_gengo_translations
+#: model:ir.ui.menu,name:base_gengo.menu_action_wizard_base_gengo_translations
+msgid "Gengo: Manual Request of Translation"
+msgstr ""
+
+#. module: base_gengo
+#: code:addons/base_gengo/ir_translation.py:62
+#: code:addons/base_gengo/wizard/base_gengo_translations.py:109
+#, python-format
+msgid "Gengo Authentication Error"
+msgstr ""
+
+#. module: base_gengo
+#: model:ir.model,name:base_gengo.model_res_company
+msgid "Companies"
+msgstr ""
+
+#. module: base_gengo
+#: view:ir.translation:0
+msgid ""
+"Note: If the translation state is 'In Progress', it means that the "
+"translation has to be approved to be uploaded in this system. You are "
+"supposed to do that directly by using your Gengo Account"
+msgstr ""
+
+#. module: base_gengo
+#: code:addons/base_gengo/wizard/base_gengo_translations.py:82
+#, python-format
+msgid ""
+"Gengo connection failed with this message:\n"
+"``%s``"
+msgstr ""
+
+#. module: base_gengo
+#: view:res.company:0
+msgid "Gengo Parameters"
+msgstr ""
+
+#. module: base_gengo
+#: view:base.gengo.translations:0
+msgid "Send"
+msgstr ""
+
+#. module: base_gengo
+#: selection:ir.translation,gengo_translation:0
+msgid "Ultra"
+msgstr ""
+
+#. module: base_gengo
+#: model:ir.model,name:base_gengo.model_ir_translation
+msgid "ir.translation"
+msgstr ""
+
+#. module: base_gengo
+#: view:ir.translation:0
+msgid "Gengo Translation Service"
+msgstr ""
+
+#. module: base_gengo
+#: selection:ir.translation,gengo_translation:0
+msgid "Pro"
+msgstr ""
+
+#. module: base_gengo
+#: view:base.gengo.translations:0
+msgid "Gengo Request Form"
+msgstr ""
+
+#. module: base_gengo
+#: code:addons/base_gengo/wizard/base_gengo_translations.py:114
+#, python-format
+msgid "Warning"
+msgstr ""
+
+#. module: base_gengo
+#: help:res.company,gengo_comment:0
+msgid ""
+"This comment will be automatically be enclosed in each an every request sent "
+"to Gengo"
+msgstr ""
+
+#. module: base_gengo
+#: view:base.gengo.translations:0
+msgid "Cancel"
+msgstr ""
+
+#. module: base_gengo
+#: view:base.gengo.translations:0
+msgid "or"
+msgstr ""
diff --git a/addons/crm/crm.py b/addons/crm/crm.py
index 4c9a60634a5..d1194508b71 100644
--- a/addons/crm/crm.py
+++ b/addons/crm/crm.py
@@ -222,17 +222,13 @@ class crm_case_section(osv.osv):
return res
def create(self, cr, uid, vals, context=None):
- mail_alias = self.pool.get('mail.alias')
- if not vals.get('alias_id'):
- alias_name = vals.pop('alias_name', None) or vals.get('name') # prevent errors during copy()
- alias_id = mail_alias.create_unique_alias(cr, uid,
- {'alias_name': alias_name},
- model_name="crm.lead",
- context=context)
- vals['alias_id'] = alias_id
- res = super(crm_case_section, self).create(cr, uid, vals, context)
- mail_alias.write(cr, uid, [vals['alias_id']], {'alias_defaults': {'section_id': res, 'type': 'lead'}}, context)
- return res
+ if context is None:
+ context = {}
+ create_context = dict(context, alias_model_name='crm.lead', alias_parent_model_name=self._name)
+ section_id = super(crm_case_section, self).create(cr, uid, vals, context=create_context)
+ section = self.browse(cr, uid, section_id, context=context)
+ self.pool.get('mail.alias').write(cr, uid, [section.alias_id.id], {'alias_parent_thread_id': section_id, 'alias_defaults': {'section_id': section_id, 'type': 'lead'}}, context=context)
+ return section_id
def unlink(self, cr, uid, ids, context=None):
# Cascade-delete mail aliases as well, as they should not exist without the sales team.
diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml
index be5611c03c4..c957311b47f 100644
--- a/addons/crm/crm_case_section_view.xml
+++ b/addons/crm/crm_case_section_view.xml
@@ -94,7 +94,7 @@
- %%
+ %%
@@ -168,17 +168,6 @@
-
-
-
-
-
- @
-
-
-
@@ -187,12 +176,25 @@
-
-
+
+
+
+
+
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index b8673e73927..44ada2ffcc0 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -719,7 +719,6 @@ class crm_lead(base_stage, format_address, osv.osv):
continue
vals = self._convert_opportunity_data(cr, uid, lead, customer, section_id, context=context)
self.write(cr, uid, [lead.id], vals, context=context)
- self.message_post(cr, uid, ids, body=_("Lead converted into an Opportunity "), subtype="crm.mt_lead_convert_to_opportunity", context=context)
if user_ids or section_id:
self.allocate_salesman(cr, uid, ids, user_ids, section_id, context=context)
diff --git a/addons/crm/crm_lead_data.xml b/addons/crm/crm_lead_data.xml
index 0979a94eb3f..92914542d9d 100644
--- a/addons/crm/crm_lead_data.xml
+++ b/addons/crm/crm_lead_data.xml
@@ -163,12 +163,6 @@
Opportunity created
-
- Lead to Opportunity
- crm.lead
-
- Lead converted into an opportunity
-
Stage Changed
crm.lead
@@ -195,13 +189,6 @@
section_id
-
- Lead to Opportunity
-
- crm.case.section
-
- section_id
-
Opportunity Stage Changed
crm.case.section
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index 6ddd06c1c90..df6a4a07a8e 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -601,7 +601,9 @@
'default_email_to':'{$object.email or \'\'}',
'default_use_template': True,
'default_template_id': ref('crm.email_template_opportunity_mail'),
- }"/>
+ }"
+ groups="base.group_sale_salesman"
+ />
@@ -617,6 +619,7 @@
if context.get('active_model') == 'crm.lead' and context.get('active_ids'):
self.case_cancel(cr, uid, context['active_ids'], context=context)
+
diff --git a/addons/crm/i18n/hu.po b/addons/crm/i18n/hu.po
index 98313efb4f3..6673d2da235 100644
--- a/addons/crm/i18n/hu.po
+++ b/addons/crm/i18n/hu.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2013-04-13 08:42+0000\n"
+"PO-Revision-Date: 2013-06-21 07:11+0000\n"
"Last-Translator: krnkris \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-04-14 05:12+0000\n"
-"X-Generator: Launchpad (build 16564)\n"
+"X-Launchpad-Export-Date: 2013-06-22 05:36+0000\n"
+"X-Generator: Launchpad (build 16677)\n"
#. module: crm
#: view:crm.lead.report:0
@@ -31,7 +31,7 @@ msgstr ""
"létrehozását a bejövő levelekből."
#. module: crm
-#: code:addons/crm/crm_lead.py:881
+#: code:addons/crm/crm_lead.py:898
#: selection:crm.case.stage,type:0
#: view:crm.lead:0
#: selection:crm.lead,type:0
@@ -192,8 +192,8 @@ msgstr ""
"direkt HTML formátumú ahhoz hogy beilleszthető legyen a kanban nézetekbe."
#. module: crm
-#: code:addons/crm/crm_lead.py:624
-#: code:addons/crm/crm_lead.py:744
+#: code:addons/crm/crm_lead.py:640
+#: code:addons/crm/crm_lead.py:761
#: code:addons/crm/crm_phonecall.py:280
#, python-format
msgid "Warning!"
@@ -304,7 +304,7 @@ msgid "Prospect Partner"
msgstr "Leendő partner"
#. module: crm
-#: code:addons/crm/crm_lead.py:982
+#: code:addons/crm/crm_lead.py:1002
#, python-format
msgid "No Subject"
msgstr "Nincs tárgy"
@@ -482,7 +482,7 @@ msgid "#Opportunities"
msgstr "Lehetőségek száma"
#. module: crm
-#: code:addons/crm/crm_lead.py:624
+#: code:addons/crm/crm_lead.py:640
#, python-format
msgid ""
"Please select more than one element (lead or opportunity) from the list view."
@@ -782,7 +782,7 @@ msgid "Statistics Dashboard"
msgstr "Statisztika vezérlőpult"
#. module: crm
-#: code:addons/crm/crm_lead.py:861
+#: code:addons/crm/crm_lead.py:878
#: model:crm.case.stage,name:crm.stage_lead2
#: selection:crm.case.stage,type:0
#: view:crm.lead:0
@@ -844,7 +844,7 @@ msgid "Exclusive"
msgstr "Kizárólagos"
#. module: crm
-#: code:addons/crm/crm_lead.py:584
+#: code:addons/crm/crm_lead.py:600
#, python-format
msgid "From %s : %s"
msgstr "Ettől %s : %s"
@@ -1016,7 +1016,7 @@ msgid "Next Action"
msgstr "Következő művelet"
#. module: crm
-#: code:addons/crm/crm_lead.py:763
+#: code:addons/crm/crm_lead.py:780
#, python-format
msgid "Partner set to %s ."
msgstr "Partner beállítva mint %s ."
@@ -1109,7 +1109,7 @@ msgid "Creation Date"
msgstr "Létrehozás dátuma"
#. module: crm
-#: code:addons/crm/crm_lead.py:698
+#: code:addons/crm/crm_lead.py:715
#, python-format
msgid "Lead converted into an Opportunity "
msgstr "Tervezet lehetőséggé átalakítva lehetőséggé "
@@ -1324,7 +1324,9 @@ msgid "Days to Close"
msgstr "Lezárásig hátralévő napok"
#. module: crm
+#: code:addons/crm/crm_lead.py:1057
#: field:crm.case.section,complete_name:0
+#, python-format
msgid "unknown"
msgstr "Ismeretlen"
@@ -1415,7 +1417,7 @@ msgid "Lead Description"
msgstr "Érdeklődés leírása"
#. module: crm
-#: code:addons/crm/crm_lead.py:565
+#: code:addons/crm/crm_lead.py:581
#, python-format
msgid "Merged opportunities"
msgstr "Lehetőségek összefésülése"
@@ -1989,7 +1991,7 @@ msgid "Leads"
msgstr "Érdeklődők"
#. module: crm
-#: code:addons/crm/crm_lead.py:563
+#: code:addons/crm/crm_lead.py:579
#, python-format
msgid "Merged leads"
msgstr "Össztefésült érdeklődések"
@@ -2085,7 +2087,6 @@ msgid "Global CC"
msgstr "Globális CC /másolat/"
#. module: crm
-#: view:crm.lead:0
#: view:crm.phonecall:0
#: model:ir.actions.act_window,name:crm.crm_case_categ_phone0
#: model:ir.ui.menu,name:crm.menu_crm_case_phone
@@ -2399,7 +2400,7 @@ msgstr "Érdeklődés átalakítva egy lehetőséggé"
#. module: crm
#: view:crm.lead:0
msgid "Unassigned Leads"
-msgstr "Nem iktatott rdeklődések"
+msgstr "Nem iktatott érdeklődések"
#. module: crm
#: model:mail.message.subtype,description:crm.mt_lead_won
@@ -3100,7 +3101,7 @@ msgid "Working Hours"
msgstr "Munkaórák"
#. module: crm
-#: code:addons/crm/crm_lead.py:968
+#: code:addons/crm/crm_lead.py:986
#: view:crm.lead:0
#: field:crm.lead2opportunity.partner,partner_id:0
#: field:crm.lead2opportunity.partner.mass,partner_id:0
diff --git a/addons/crm/wizard/crm_lead_to_opportunity_view.xml b/addons/crm/wizard/crm_lead_to_opportunity_view.xml
index 4093df910d0..9ddd1fc701f 100644
--- a/addons/crm/wizard/crm_lead_to_opportunity_view.xml
+++ b/addons/crm/wizard/crm_lead_to_opportunity_view.xml
@@ -102,7 +102,9 @@
res_model="crm.lead2opportunity.partner.mass" src_model="crm.lead"
view_mode="form" target="new" view_type="form"
context="{'mass_convert' : True}"
- view_id="view_crm_lead2opportunity_partner_mass"/>
+ view_id="view_crm_lead2opportunity_partner_mass"
+ groups="base.group_sale_salesman"
+ />
diff --git a/addons/crm/wizard/crm_merge_opportunities_view.xml b/addons/crm/wizard/crm_merge_opportunities_view.xml
index 919d83cb9a7..60693c13e19 100644
--- a/addons/crm/wizard/crm_merge_opportunities_view.xml
+++ b/addons/crm/wizard/crm_merge_opportunities_view.xml
@@ -45,7 +45,9 @@
multi="True"
key2="client_action_multi" name="Merge leads/opportunities"
res_model="crm.merge.opportunity" src_model="crm.lead"
- view_mode="form" target="new" view_type="form"/>
+ view_mode="form" target="new" view_type="form"
+ groups="base.group_sale_salesman"
+ />
diff --git a/addons/crm_partner_assign/__init__.py b/addons/crm_partner_assign/__init__.py
index bb4a3bb53be..6b1315cef07 100644
--- a/addons/crm_partner_assign/__init__.py
+++ b/addons/crm_partner_assign/__init__.py
@@ -20,6 +20,7 @@
##############################################################################
import crm_partner_assign
+import crm_lead
import wizard
import report
diff --git a/addons/crm_partner_assign/__openerp__.py b/addons/crm_partner_assign/__openerp__.py
index b9b21ca7a6a..37a8c5a3d6b 100644
--- a/addons/crm_partner_assign/__openerp__.py
+++ b/addons/crm_partner_assign/__openerp__.py
@@ -37,17 +37,23 @@ The most appropriate partner can be assigned.
You can also use the geolocalization without using the GPS coordinates.
""",
'author': 'OpenERP SA',
- 'depends': ['crm', 'account'],
+ 'depends': ['crm', 'account', 'portal'],
'demo': ['res_partner_demo.xml'],
'data': [
'security/ir.model.access.csv',
'res_partner_view.xml',
'wizard/crm_forward_to_partner_view.xml',
+ 'wizard/crm_channel_interested_view.xml',
'crm_lead_view.xml',
'crm_partner_assign_data.xml',
+ 'crm_portal_view.xml',
+ 'portal_data.xml',
'report/crm_lead_report_view.xml',
'report/crm_partner_report_view.xml',
],
+ 'js': [
+ 'static/src/js/next.js',
+ ],
'test': ['test/partner_assign.yml'],
'installable': True,
'auto_install': False,
diff --git a/addons/crm_partner_assign/crm_lead.py b/addons/crm_partner_assign/crm_lead.py
new file mode 100644
index 00000000000..37f4b9aedff
--- /dev/null
+++ b/addons/crm_partner_assign/crm_lead.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from openerp.osv import osv
+from openerp.tools.translate import _
+
+
+class crm_lead(osv.osv):
+ _inherit = 'crm.lead'
+
+ def get_interested_action(self, cr, uid, interested, context=None):
+ try:
+ model, action_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm_partner_assign', 'crm_lead_channel_interested_act')
+ except ValueError:
+ raise osv.except_osv(_('Error!'), _("The CRM Channel Interested Action is missing"))
+ action = self.pool[model].read(cr, uid, action_id, context=context)
+ action_context = eval(action['context'])
+ action_context['interested'] = interested
+ action['context'] = str(action_context)
+ return action
+
+ def case_interested(self, cr, uid, ids, context=None):
+ return self.get_interested_action(cr, uid, True, context=context)
+
+ def case_disinterested(self, cr, uid, ids, context=None):
+ return self.get_interested_action(cr, uid, False, context=context)
diff --git a/addons/crm_partner_assign/crm_lead_view.xml b/addons/crm_partner_assign/crm_lead_view.xml
index 0d2837d6ca5..5c14680ee78 100644
--- a/addons/crm_partner_assign/crm_lead_view.xml
+++ b/addons/crm_partner_assign/crm_lead_view.xml
@@ -8,27 +8,33 @@
-
+
-
-
-
+
+
+
+
+ (
+
+ N
+ S
+
+ E
+ W
+ )
+
+
+
+
-
-
+ type="action"
+ context="{'default_composition_mode': 'forward','hide_forward_type': 1 , 'default_partner_ids': [partner_assigned_id]}"/>
-
-
-
-
-
-
@@ -43,7 +49,7 @@
-
+
@@ -55,41 +61,46 @@
-
-
+
-
+
crm.lead.lead.geo_assign.inherit
crm.lead
-
+
-
-
-
+
+
-
-
+ (
+
+ N
+ S
+
+ E
+ W
+ )
+
+
+
+
+
+
+ type="action"
+ context="{'default_composition_mode': 'forward','hide_forward_type': 1 , 'default_partner_ids': [partner_assigned_id]}"/>
-
-
-
-
-
-
@@ -104,7 +115,7 @@
-
+
@@ -116,12 +127,11 @@
-
-
+
diff --git a/addons/crm_partner_assign/crm_partner_assign.py b/addons/crm_partner_assign/crm_partner_assign.py
index b13a75a2591..daf3d844fe6 100644
--- a/addons/crm_partner_assign/crm_partner_assign.py
+++ b/addons/crm_partner_assign/crm_partner_assign.py
@@ -66,10 +66,13 @@ class res_partner_grade(osv.osv):
_columns = {
'sequence': fields.integer('Sequence'),
'active': fields.boolean('Active'),
- 'name': fields.char('Grade Name', size=32)
+ 'name': fields.char('Grade Name', size=32),
+ 'partner_weight': fields.integer('Grade Weight',
+ help="Gives the probability to assign a lead to this partner. (0 means no assignation.)"),
}
_defaults = {
- 'active': lambda *args: 1
+ 'active': lambda *args: 1,
+ 'partner_weight':1
}
class res_partner_activation(osv.osv):
@@ -88,11 +91,11 @@ class res_partner(osv.osv):
'partner_latitude': fields.float('Geo Latitude'),
'partner_longitude': fields.float('Geo Longitude'),
'date_localization': fields.date('Geo Localization Date'),
- 'partner_weight': fields.integer('Weight',
+ 'partner_weight': fields.integer('Grade Weight',
help="Gives the probability to assign a lead to this partner. (0 means no assignation.)"),
'opportunity_assigned_ids': fields.one2many('crm.lead', 'partner_assigned_id',\
'Assigned Opportunities'),
- 'grade_id': fields.many2one('res.partner.grade', 'Partner Level'),
+ 'grade_id': fields.many2one('res.partner.grade', 'Grade'),
'activation' : fields.many2one('res.partner.activation', 'Activation', select=1),
'date_partnership' : fields.date('Partnership Date'),
'date_review' : fields.date('Latest Partner Review'),
@@ -101,6 +104,13 @@ class res_partner(osv.osv):
_defaults = {
'partner_weight': lambda *args: 0
}
+
+ def onchange_grade_id(self, cr, uid, ids, grade_id, context=None):
+ res = {'value' :{'partner_weight':0}}
+ if grade_id:
+ partner_grade = self.pool.get('res.partner.grade').browse(cr, uid, grade_id)
+ res['value']['partner_weight'] = partner_grade.partner_weight
+ return res
def geo_localize(self, cr, uid, ids, context=None):
# Don't pass context to browse()! We need country names in english below
for partner in self.browse(cr, uid, ids):
@@ -124,7 +134,7 @@ class crm_lead(osv.osv):
_columns = {
'partner_latitude': fields.float('Geo Latitude'),
'partner_longitude': fields.float('Geo Longitude'),
- 'partner_assigned_id': fields.many2one('res.partner', 'Assigned Partner', help="Partner this case has been forwarded/assigned to.", select=True),
+ 'partner_assigned_id': fields.many2one('res.partner', 'Assigned Partner',track_visibility='onchange' , help="Partner this case has been forwarded/assigned to.", select=True),
'date_assign': fields.date('Assignation Date', help="Last date this case was forwarded/assigned to a partner"),
}
def _merge_data(self, cr, uid, ids, oldest, fields, context=None):
@@ -134,6 +144,7 @@ class crm_lead(osv.osv):
def onchange_assign_id(self, cr, uid, ids, partner_assigned_id, context=None):
"""This function updates the "assignation date" automatically, when manually assign a partner in the geo assign tab
"""
+
if not partner_assigned_id:
return {'value':{'date_assign': False}}
else:
@@ -261,4 +272,3 @@ class crm_lead(osv.osv):
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/crm_partner_assign/crm_partner_assign_data.xml b/addons/crm_partner_assign/crm_partner_assign_data.xml
index dab50192641..b4347b1621b 100644
--- a/addons/crm_partner_assign/crm_partner_assign_data.xml
+++ b/addons/crm_partner_assign/crm_partner_assign_data.xml
@@ -1,44 +1,59 @@
-
+
-
- Lead forward
-
- Fwd: Lead: ${object.name}
-
-
-
+
+ Assigned
+
+
+
+ lead
+
+
+ To Recycle
+
+
+
+ lead
+
+
+ Lead Mass Mail
+
+ ${ctx['partner_id'].email}
+ ${user.email or ''}
+ Fwd: Lead: ${ctx['partner_id'].name}
-Here is a lead that might interest you.
-
-
-Please keep me informed about your actions about it so that I can keep an
-accurate follow-up of it and help you in the sale cycle.
-
-
-Your account manager,
-${object.user_id.name},
-${object.user_id.email}
-
+
+Hello,
-
-${ctx["mail_body"].replace('\n',' ') | safe}
-
-% if ctx["history_mode"] in ('whole'):
- % for message in object.message_ids:
- ---- Original Message (${message.date or ''}) ----
- ${message.body | safe}
- % endfor
+We have been contacted by those prospects that are in your region. Thus, the following leads have been assigned to ${ctx['partner_id'].name}:
+
+
+% for lead in ctx['partner_leads']:
+ ${lead.lead_id.name or 'Subject Undefined'} , ${lead.lead_id.contact_name or 'Contact Name Undefined'}, ${lead.lead_id.country_id and lead.lead_id.country_id.name or 'Country Undefined' }, ${lead.lead_id.email_from or 'Email Undefined'}, ${lead.lead_id.phone or ''}
+% endfor
+
+
+% if ctx.get('partner_in_portal'):
+Please connect to your Partner Portal to get details. On each lead are two buttons on the top left corner that you should press after having contacted the lead: "I'm interested" & "I'm not interested".
+% else:
+
+ You do not have yet a portal access to our database. Please contact
+ ${ctx['partner_id'].user_id and ctx['partner_id'].user_id.email and 'your account manager %s (%s)' % (ctx['partner_id'].user_id.name,ctx['partner_id'].user_id.email) or 'us'}.
+
% endif
-% if ctx['history_mode'] == 'latest':
- ---- Original Message (${object.message_ids[0].date or ''}) ----
- ${object.message_ids[0].body | safe}
+The lead will be sent to another partner if you do not contact the lead before 20 days.
+
+Thanks,
+
+
+${ctx['partner_id'].user_id and ctx['partner_id'].user_id.signature or ''}
+
+% if not ctx['partner_id'].user_id:
+PS: It looks like you do not have an account manager assigned to you, please contact us.
% endif
]]>
-
+
\ No newline at end of file
diff --git a/addons/crm_partner_assign/crm_portal_view.xml b/addons/crm_partner_assign/crm_portal_view.xml
new file mode 100644
index 00000000000..a8d342ebb94
--- /dev/null
+++ b/addons/crm_partner_assign/crm_portal_view.xml
@@ -0,0 +1,209 @@
+
+
+
+
+ partner lead
+ crm.lead
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ crm_portal_form
+ crm.lead
+
+
+
+
+
+
+
+ partner lead
+ crm.lead
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ crm_portal_form
+ crm.lead
+
+
+
+
+
+
+
+
+
+
+ Leads
+ crm.lead
+ tree,form
+
+ [('type','like','lead')]
+
+
+
+
+ tree
+
+
+
+
+
+
+ form
+
+
+
+
+
+
+
+ Opportunities
+ crm.lead
+ tree,form
+
+ [('type','like','opportunity')]
+
+
+
+
+ tree
+
+
+
+
+
+
+ form
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm_partner_assign/portal_data.xml b/addons/crm_partner_assign/portal_data.xml
new file mode 100644
index 00000000000..0d4a5b30abd
--- /dev/null
+++ b/addons/crm_partner_assign/portal_data.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+ openerp.portal.res.partner
+
+
+
+
+
+
+
+
+ openerp.portal.res.partner
+
+
+ [('id','child_of',user.commercial_partner_id.id)]
+
+
+ openerp.portal.res.partner.grade
+
+
+
+
+
+
+
+
+
+
+ openerp.portal.crm.lead
+
+
+ [('partner_assigned_id','child_of',user.commercial_partner_id.id)]
+
+
+ openerp.portal.crm.lead
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm_partner_assign/res_partner_view.xml b/addons/crm_partner_assign/res_partner_view.xml
index 9e70835a3f1..874d2a9f053 100644
--- a/addons/crm_partner_assign/res_partner_view.xml
+++ b/addons/crm_partner_assign/res_partner_view.xml
@@ -2,7 +2,7 @@
-
+
openerp_custom.res.partner.activation.form
@@ -33,145 +33,134 @@
tree,form
-
+
-
+
-
-
- res.partner.grade.tree
- res.partner.grade
-
-
-
-
-
-
-
-
- res.partner.grade.form
- res.partner.grade
-
-
-
-
-
- Partner Grade
- res.partner.grade
- form
-
-
-
-
-
- res.partner.geo.inherit.tree
- res.partner
-
-
-
-
-
-
+
+ res.partner.grade.tree
+ res.partner.grade
+
+
+
+
+
-
-
-
-
- res.partner.geo.inherit.search
- res.partner
-
-
-
-
-
-
-
-
-
-
-
-
- res.partner.geo.inherit
- res.partner
-
-
-
-
-
+
+
+ res.partner.grade.form
+ res.partner.grade
+
+
+
+
+
+ Partner Grade
+ res.partner.grade
+ form
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ res.partner.geo.inherit.tree
+ res.partner
+
+
+
+
+
+
+
+
+
+
+ res.partner.geo.inherit.search
+ res.partner
+
+
+
+
+
+
+
+
+
+
+
+
+ res.partner.geo.inherit
+ res.partner
+
+
+
+
+
+
+
+
+
+ (
+
+ N
+ S
+
+ E
+ W
+ )
+
+
+
+
+
+
+
+ Higher is the value, higher is the probability for this partner to get more leads.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm_partner_assign/security/ir.model.access.csv b/addons/crm_partner_assign/security/ir.model.access.csv
index 69b74ef6b3d..81d74bf43e3 100644
--- a/addons/crm_partner_assign/security/ir.model.access.csv
+++ b/addons/crm_partner_assign/security/ir.model.access.csv
@@ -5,3 +5,4 @@ access_crm_partner_report,crm.partner.report.assign.all,model_crm_partner_report
access_res_partner_grade,res.partner.grade,model_res_partner_grade,base.group_sale_salesman,1,1,1,0
access_res_partner_grade_manager,res.partner.grade.manager,model_res_partner_grade,base.group_sale_manager,1,1,1,1
"access_partner_activation_manager","res.partner.activation.manager","model_res_partner_activation","base.group_partner_manager",1,1,1,1
+partner_access_crm_lead,crm.lead,model_crm_lead,portal.group_portal,1,1,0,0
\ No newline at end of file
diff --git a/addons/crm_partner_assign/static/src/js/next.js b/addons/crm_partner_assign/static/src/js/next.js
new file mode 100644
index 00000000000..c40f104d6c6
--- /dev/null
+++ b/addons/crm_partner_assign/static/src/js/next.js
@@ -0,0 +1,13 @@
+openerp.crm_partner_assign = function (instance) {
+ instance.crm_partner_assign = instance.crm_partner_assign || {};
+ instance.crm_partner_assign.next_or_list = function(parent) {
+ var form = parent.inner_widget.views.form.controller;
+ form.dataset.remove_ids([form.dataset.ids[form.dataset.index]]);
+ form.reload();
+ if (!form.dataset.ids.length){
+ parent.inner_widget.switch_mode('list');
+ }
+ parent.do_action({ type: 'ir.actions.act_window_close' });
+ };
+ instance.web.client_actions.add("next_or_list", "instance.crm_partner_assign.next_or_list");
+}
\ No newline at end of file
diff --git a/addons/crm_partner_assign/wizard/__init__.py b/addons/crm_partner_assign/wizard/__init__.py
index 9224173145b..ab6c7b7f06a 100644
--- a/addons/crm_partner_assign/wizard/__init__.py
+++ b/addons/crm_partner_assign/wizard/__init__.py
@@ -20,3 +20,4 @@
##############################################################################
import crm_forward_to_partner
+import crm_channel_interested
\ No newline at end of file
diff --git a/addons/crm_partner_assign/wizard/crm_channel_interested.py b/addons/crm_partner_assign/wizard/crm_channel_interested.py
new file mode 100644
index 00000000000..57db36cb51f
--- /dev/null
+++ b/addons/crm_partner_assign/wizard/crm_channel_interested.py
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL (). All Rights Reserved
+# $Id$
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from openerp.osv import fields, osv
+from openerp.tools.translate import _
+from openerp import SUPERUSER_ID
+
+
+class crm_lead_forward_to_partner(osv.TransientModel):
+ """ Forward info history to partners. """
+ _name = 'crm.lead.channel.interested'
+ _columns = {
+ 'interested': fields.boolean('Interested by this lead'),
+ 'contacted': fields.boolean('Did you contact the lead?', help="The lead has been contacted"),
+ 'comment': fields.text('Comment', help="What are the elements that have led to this decision?", required=True),
+ }
+ _defaults = {
+ 'interested': lambda self, cr, uid, c: c.get('interested', True),
+ 'contacted': False,
+ }
+
+ def action_confirm(self, cr, uid, ids, context=None):
+ wizard = self.browse(cr, uid, ids[0], context=context)
+ if wizard.interested and not wizard.contacted:
+ raise osv.except_osv(_('Error!'), _("You must contact the lead before saying that you are interested"))
+ lead_obj = self.pool.get('crm.lead')
+ lead_obj.check_access_rights(cr, uid, 'write')
+ if wizard.interested:
+ message = _('I am interested by this lead.
')
+ values = {}
+ else:
+ stage = 'stage_portal_lead_recycle'
+ message = _('I am not interested by this lead. I %scontacted the lead.
') % (not wizard.contacted and 'have not ' or '')
+ values = {'partner_assigned_id': False}
+ user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
+ partner_ids = self.pool.get('res.partner').search(cr, SUPERUSER_ID, [('id', 'child_of', user.partner_id.commercial_partner_id.id)], context=context)
+ lead_obj.message_unsubscribe(cr, SUPERUSER_ID, context.get('active_ids'), partner_ids, context=None)
+ try:
+ stage_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm_partner_assign', stage)[1]
+ except ValueError:
+ stage_id = False
+ if stage_id:
+ values.update({'stage_id': stage_id})
+ if wizard.comment:
+ message += '%s
' % wizard.comment
+ lead_obj.message_post(cr, uid, context.get('active_ids'), body=message, context=context)
+ if values:
+ lead_obj.write(cr, SUPERUSER_ID, context.get('active_ids'), values)
+ if wizard.interested:
+ for lead in lead_obj.browse(cr, uid, context.get('active_ids'), context=context):
+ lead_obj.convert_opportunity(cr, SUPERUSER_ID, [lead.id], lead.partner_id and lead.partner_id.id or None, context=None)
+ return {
+ 'type': 'ir.actions.client',
+ 'tag': 'next_or_list',
+ 'params': {
+ },
+ }
diff --git a/addons/crm_partner_assign/wizard/crm_channel_interested_view.xml b/addons/crm_partner_assign/wizard/crm_channel_interested_view.xml
new file mode 100644
index 00000000000..400e02cd48a
--- /dev/null
+++ b/addons/crm_partner_assign/wizard/crm_channel_interested_view.xml
@@ -0,0 +1,45 @@
+
+
+
+
+ crm_lead_channel_interested
+ crm.lead.channel.interested
+
+
+
+
+
+ Lead Feedback
+ crm.lead.channel.interested
+ form
+ form
+
+ new
+
+
+
\ No newline at end of file
diff --git a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
index 724102a84b1..80fa2f28b04 100644
--- a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
+++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
@@ -27,107 +27,182 @@ from openerp.tools.translate import _
class crm_lead_forward_to_partner(osv.TransientModel):
""" Forward info history to partners. """
_name = 'crm.lead.forward.to.partner'
- _inherit = "mail.compose.message"
- def _get_composition_mode_selection(self, cr, uid, context=None):
- composition_mode = super(crm_lead_forward_to_partner, self)._get_composition_mode_selection(cr, uid, context=context)
- composition_mode.append(('forward', 'Forward'))
- return composition_mode
-
- _columns = {
- 'partner_ids': fields.many2many('res.partner',
- 'lead_forward_to_partner_res_partner_rel',
- 'wizard_id', 'partner_id', 'Additional contacts'),
- 'attachment_ids': fields.many2many('ir.attachment',
- 'lead_forward_to_partner_attachment_rel',
- 'wizard_id', 'attachment_id', 'Attachments'),
- 'history_mode': fields.selection([('info', 'Internal notes'),
- ('latest', 'Latest email'), ('whole', 'Whole Story')],
- 'Send history', required=True),
- }
-
- _defaults = {
- 'history_mode': 'info',
- }
+ def _convert_to_assignation_line(self, cr, uid, lead, partner, context=None):
+ lead_location = []
+ partner_location = []
+ if lead.country_id:
+ lead_location.append(lead.country_id.name)
+ if lead.city:
+ lead_location.append(lead.city)
+ if partner:
+ if partner.country_id:
+ partner_location.append(partner.country_id.name)
+ if partner.city:
+ partner_location.append(partner.city)
+ return {'lead_id': lead.id,
+ 'lead_location': ", ".join(lead_location),
+ 'partner_assigned_id': partner and partner.id or False,
+ 'partner_location': ", ".join(partner_location),
+ 'lead_link': self.get_lead_portal_url(cr, uid, lead.id, lead.type, context=context),
+ }
def default_get(self, cr, uid, fields, context=None):
if context is None:
context = {}
- # set as comment, perform overrided document-like action that calls get_record_data
- old_mode = context.get('default_composition_mode', 'forward')
- context['default_composition_mode'] = 'comment'
+ lead_obj = self.pool.get('crm.lead')
+ email_template_obj = self.pool.get('email.template')
+ try:
+ template_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm_partner_assign', 'email_template_lead_forward_mail')[1]
+ except ValueError:
+ template_id = False
res = super(crm_lead_forward_to_partner, self).default_get(cr, uid, fields, context=context)
- # back to forward mode
- context['default_composition_mode'] = old_mode
- res['composition_mode'] = context['default_composition_mode']
+ active_ids = context.get('active_ids')
+ default_composition_mode = context.get('default_composition_mode')
+ res['assignation_lines'] = []
+ if template_id:
+ res['body'] = email_template_obj.get_email_template(cr, uid, template_id).body_html
+ if active_ids:
+ lead_ids = lead_obj.browse(cr, uid, active_ids, context=context)
+ if default_composition_mode == 'mass_mail':
+ partner_assigned_ids = lead_obj.search_geo_partner(cr, uid, active_ids, context=context)
+ else:
+ partner_assigned_ids = dict((lead.id, lead.partner_assigned_id and lead.partner_assigned_id.id or False) for lead in lead_ids)
+ res['partner_id'] = lead_ids[0].partner_assigned_id.id
+ for lead in lead_ids:
+ partner_id = partner_assigned_ids.get(lead.id) or False
+ partner = False
+ if partner_id:
+ partner = self.pool.get('res.partner').browse(cr, uid, partner_id, context=context)
+ res['assignation_lines'].append(self._convert_to_assignation_line(cr, uid, lead, partner))
return res
- def get_record_data(self, cr, uid, model, res_id, context=None):
- """ Override of mail.compose.message, to add default values coming
- form the related lead.
- """
- if context is None:
- context = {}
- res = super(crm_lead_forward_to_partner, self).get_record_data(cr, uid, model, res_id, context=context)
- if model not in ('crm.lead') or not res_id:
- return res
- template_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm_partner_assign', 'crm_partner_assign_email_template')[1]
- context['history_mode'] = context.get('history_mode','whole')
- mail_body_fields = ['partner_id', 'partner_name', 'title', 'function', 'street', 'street2', 'zip', 'city', 'country_id', 'state_id', 'email_from', 'phone', 'fax', 'mobile', 'description']
- lead = self.pool.get('crm.lead').browse(cr, uid, res_id, context=context)
- context['mail_body'] = self.pool.get('crm.lead')._mail_body(cr, uid, lead, mail_body_fields, context=context)
- template = self.generate_email_for_composer(cr, uid, template_id, res_id, context)
- res['subject'] = template['subject']
- res['body'] = template['body']
- return res
-
- def on_change_history_mode(self, cr, uid, ids, history_mode, model, res_id, context=None):
- """ Update body when changing history_mode """
- if context is None:
- context = {}
- if model and model == 'crm.lead' and res_id:
- lead = self.pool[model].browse(cr, uid, res_id, context=context)
- context['history_mode'] = history_mode
- body = self.get_record_data(cr, uid, 'crm.lead', res_id, context=context)['body']
- return {'value': {'body': body}}
-
- def create(self, cr, uid, values, context=None):
- """ TDE-HACK: remove 'type' from context, because when viewing an
- opportunity form view, a default_type is set and propagated
- to the wizard, that has a not matching type field. """
- default_type = context.pop('default_type', None)
- new_id = super(crm_lead_forward_to_partner, self).create(cr, uid, values, context=context)
- if default_type:
- context['default_type'] = default_type
- return new_id
-
def action_forward(self, cr, uid, ids, context=None):
- """ Forward the lead to a partner """
- if context is None:
+ lead_obj = self.pool.get('crm.lead')
+ record = self.browse(cr, uid, ids[0], context=context)
+ email_template_obj = self.pool.get('email.template')
+ try:
+ template_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm_partner_assign', 'email_template_lead_forward_mail')[1]
+ except ValueError:
+ raise osv.except_osv(_('Email Template Error'),
+ _('The Forward Email Template is not in the database'))
+ try:
+ portal_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_portal')[1]
+ except ValueError:
+ raise osv.except_osv(_('Portal Group Error'),
+ _('The Portal group cannot be found'))
+
+ local_context = context.copy()
+ if not (record.forward_type == 'single'):
+ no_email = set()
+ for lead in record.assignation_lines:
+ if lead.partner_assigned_id and not lead.partner_assigned_id.email:
+ no_email.add(lead.partner_assigned_id.name)
+ if no_email:
+ raise osv.except_osv(_('Email Error'),
+ ('Set an email address for the partner(s): %s' % ", ".join(no_email)))
+ if record.forward_type == 'single' and not record.partner_id.email:
+ raise osv.except_osv(_('Email Error'),
+ ('Set an email address for the partner %s' % record.partner_id.name))
+
+ partners_leads = {}
+ for lead in record.assignation_lines:
+ partner = record.forward_type == 'single' and record.partner_id or lead.partner_assigned_id
+ lead_details = {
+ 'lead_link': lead.lead_link,
+ 'lead_id': lead.lead_id,
+ }
+ if partner:
+ partner_leads = partners_leads.get(partner.id)
+ if partner_leads:
+ partner_leads['leads'].append(lead_details)
+ else:
+ partners_leads[partner.id] = {'partner': partner, 'leads': [lead_details]}
+ stage_id = False
+ if record.assignation_lines and record.assignation_lines[0].lead_id.type == 'lead':
+ try:
+ stage_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm_partner_assign', 'stage_portal_lead_assigned')[1]
+ except ValueError:
+ pass
+
+ for partner_id, partner_leads in partners_leads.items():
+ in_portal = False
+ for contact in (partner.child_ids or [partner]):
+ if contact.user_ids:
+ in_portal = portal_id in [g.id for g in contact.user_ids[0].groups_id]
+
+ local_context['partner_id'] = partner_leads['partner']
+ local_context['partner_leads'] = partner_leads['leads']
+ local_context['partner_in_portal'] = in_portal
+ email_template_obj.send_mail(cr, uid, template_id, ids[0], context=local_context)
+ lead_ids = [lead['lead_id'].id for lead in partner_leads['leads']]
+ values = {'partner_assigned_id': partner_id, 'user_id': partner_leads['partner'].user_id.id}
+ if stage_id:
+ values['stage_id'] = stage_id
+ lead_obj.write(cr, uid, lead_ids, values)
+ self.pool.get('crm.lead').message_subscribe(cr, uid, lead_ids, [partner_id], context=context)
+ return True
+
+ def get_lead_portal_url(self, cr, uid, lead_id, type, context=None):
+ action = type == 'opportunity' and 'action_portal_opportunities' or 'action_portal_leads'
+ try:
+ action_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm_partner_assign', action)[1]
+ except ValueError:
+ action_id = False
+ portal_link = "%s/?db=%s#id=%s&action=%s&view_type=form" % (self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'), cr.dbname, lead_id, action_id)
+ return portal_link
+
+ def get_portal_url(self, cr, uid, ids, context=None):
+ portal_link = "%s/?db=%s" % (self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'), cr.dbname)
+ return portal_link
+
+ _columns = {
+ 'forward_type': fields.selection([('single', 'a single partner: manual selection of partner'), ('assigned', "several partners: automatic assignation, using GPS coordinates and partner's grades"), ], 'Forward selected leads to'),
+ 'partner_id': fields.many2one('res.partner', 'Forward Leads To'),
+ 'assignation_lines': fields.one2many('crm.lead.assignation', 'forward_id', 'Partner Assignation'),
+ 'body': fields.html('Contents', help='Automatically sanitized HTML contents'),
+ }
+
+ _defaults = {
+ 'forward_type': lambda self, cr, uid, c: c.get('forward_type') or 'single',
+ }
+
+
+class crm_lead_assignation (osv.TransientModel):
+ _name = 'crm.lead.assignation'
+ _columns = {
+ 'forward_id': fields.many2one('crm.lead.forward.to.partner', 'Partner Assignation'),
+ 'lead_id': fields.many2one('crm.lead', 'Lead'),
+ 'lead_location': fields.char('Lead Location', size=128),
+ 'partner_assigned_id': fields.many2one('res.partner', 'Assigned Partner'),
+ 'partner_location': fields.char('Partner Location', size=128),
+ 'lead_link': fields.char('Lead Single Links', size=128),
+ }
+
+ def on_change_lead_id(self, cr, uid, ids, lead_id, context=None):
+ if not context:
context = {}
- # TDE FIX in 7.0: force mass_mailing mode; this way, the message will be
- # send only to partners; default subtype of mass_mailing is indeed False
- # Chatter will show 'logged a note', but partner_ids (aka, the assigned partner)
- # will effectively receive the message if present in the composition window
- self.write(cr, uid, ids, {'composition_mode': 'mass_mail'}, context=context)
- res = {'type': 'ir.actions.act_window_close'}
- wizard = self.browse(cr, uid, ids[0], context=context)
- if wizard.model not in ('crm.lead'):
- return res
- if context.get('active_ids') is None:
- context['active_ids'] = [wizard.res_id]
+ if not lead_id:
+ return {'value': {'lead_location': False}}
+ lead = self.pool.get('crm.lead').browse(cr, uid, lead_id, context=context)
+ lead_location = []
+ if lead.country_id:
+ lead_location.append(lead.country_id.name)
+ if lead.city:
+ lead_location.append(lead.city)
+ return {'value': {'lead_location': ", ".join(lead_location)}}
- lead = self.pool[wizard.model]
- lead_ids = wizard.res_id and [wizard.res_id] or []
+ def on_change_partner_assigned_id(self, cr, uid, ids, partner_assigned_id, context=None):
+ if not context:
+ context = {}
+ if not partner_assigned_id:
+ return {'value': {'lead_location': False}}
+ partner = self.pool.get('res.partner').browse(cr, uid, partner_assigned_id, context=context)
+ partner_location = []
+ if partner.country_id:
+ partner_location.append(partner.country_id.name)
+ if partner.city:
+ partner_location.append(partner.city)
+ return {'value': {'partner_location': ", ".join(partner_location)}}
- if wizard.composition_mode == 'mass_mail':
- lead_ids = context and context.get('active_ids', []) or []
- value = self.default_get(cr, uid, ['body', 'email_to', 'email_cc', 'subject', 'history_mode'], context=context)
- value.pop('composition_mode')
- self.pool.get('crm.lead').message_subscribe(cr, uid, lead_ids, [partner.id for partner in wizard.partner_ids], context=context)
- self.write(cr, uid, ids, value, context=context)
-
- return self.send_mail(cr, uid, ids, context=context)
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+# # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml b/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml
index 0fda8c8beaa..26ad08f1528 100644
--- a/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml
+++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml
@@ -1,36 +1,38 @@
-
crm_lead_forward_to_partner
crm.lead.forward.to.partner
@@ -45,14 +47,11 @@
new
-
+
diff --git a/addons/delivery/partner.py b/addons/delivery/partner.py
index 477315dfc9b..226b5e493ab 100644
--- a/addons/delivery/partner.py
+++ b/addons/delivery/partner.py
@@ -25,11 +25,9 @@ class res_partner(osv.osv):
_inherit = 'res.partner'
_columns = {
'property_delivery_carrier': fields.property(
- 'delivery.carrier',
type='many2one',
relation='delivery.carrier',
string="Delivery Method",
- view_load=True,
help="This delivery method will be used when invoicing from picking."),
}
diff --git a/addons/event/event.py b/addons/event/event.py
index eb18afd747c..3c04f5c1baa 100644
--- a/addons/event/event.py
+++ b/addons/event/event.py
@@ -172,6 +172,12 @@ class event_event(osv.osv):
continue
return res
+ def _get_visibility_selection(self, cr, uid, context=None):
+ return [('public', 'All Users'),
+ ('employees', 'Employees Only')]
+ # Lambda indirection method to avoid passing a copy of the overridable method when declaring the field
+ _visibility_selection = lambda self, *args, **kwargs: self._get_visibility_selection(*args, **kwargs)
+
_columns = {
'name': fields.char('Name', size=64, required=True, translate=True, readonly=False, states={'done': [('readonly', True)]}),
'user_id': fields.many2one('res.users', 'Responsible User', readonly=False, states={'done': [('readonly', True)]}),
@@ -209,11 +215,14 @@ class event_event(osv.osv):
'note': fields.text('Description', readonly=False, states={'done': [('readonly', True)]}),
'company_id': fields.many2one('res.company', 'Company', required=False, change_default=True, readonly=False, states={'done': [('readonly', True)]}),
'is_subscribed' : fields.function(_subscribe_fnc, type="boolean", string='Subscribed'),
+ 'visibility': fields.selection(_visibility_selection, 'Privacy / Visibility',
+ select=True, required=True),
}
_defaults = {
'state': 'draft',
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'event.event', context=c),
'user_id': lambda obj, cr, uid, context: uid,
+ 'visibility': 'employees',
}
def subscribe_to_event(self, cr, uid, ids, context=None):
diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml
index 4f5e33eeafd..a9831720abf 100644
--- a/addons/event/event_view.xml
+++ b/addons/event/event_view.xml
@@ -76,6 +76,7 @@
+
diff --git a/addons/event/security/event_security.xml b/addons/event/security/event_security.xml
index 83039ca4686..90a232731a7 100644
--- a/addons/event/security/event_security.xml
+++ b/addons/event/security/event_security.xml
@@ -25,25 +25,35 @@
-
- Event multi-company
+
+ Event: multi-company
- ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
+ ['|',
+ ('company_id', '=', False),
+ ('company_id', 'child_of', [user.company_id.id]),
+ ]
+
-
-
- Event Registration multi-company
+
+ Event/Registration: multi-company
- ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
+ ['|',
+ ('company_id', '=', False),
+ ('company_id', 'child_of', [user.company_id.id]),
+ ]
+
-
-
- Report Event Registration multi-company
+
+ Event/Report Registration: multi-company
- ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
+ ['|',
+ ('company_id', '=', False),
+ ('company_id', 'child_of', [user.company_id.id]),
+ ]
+
diff --git a/addons/hr/hr_view.xml b/addons/hr/hr_view.xml
index 19a6d70839f..eb1bbe451b4 100644
--- a/addons/hr/hr_view.xml
+++ b/addons/hr/hr_view.xml
@@ -348,12 +348,10 @@
-
+
-
-
diff --git a/addons/hr_attendance/i18n/th.po b/addons/hr_attendance/i18n/th.po
index 55892e93dec..673d5e7ddd1 100644
--- a/addons/hr_attendance/i18n/th.po
+++ b/addons/hr_attendance/i18n/th.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-06-20 05:17+0000\n"
-"X-Generator: Launchpad (build 16673)\n"
+"X-Launchpad-Export-Date: 2013-06-21 05:35+0000\n"
+"X-Generator: Launchpad (build 16677)\n"
#. module: hr_attendance
#: model:ir.model,name:hr_attendance.model_hr_attendance_month
diff --git a/addons/hr_expense/i18n/th.po b/addons/hr_expense/i18n/th.po
new file mode 100644
index 00000000000..c3e70f447d8
--- /dev/null
+++ b/addons/hr_expense/i18n/th.po
@@ -0,0 +1,939 @@
+# Thai translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-12-21 17:04+0000\n"
+"PO-Revision-Date: 2013-06-20 10:09+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Thai \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-06-21 05:35+0000\n"
+"X-Generator: Launchpad (build 16677)\n"
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: model:process.node,name:hr_expense.process_node_confirmedexpenses0
+msgid "Confirmed Expenses"
+msgstr ""
+
+#. module: hr_expense
+#: model:ir.model,name:hr_expense.model_hr_expense_line
+msgid "Expense Line"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.node,note:hr_expense.process_node_reimbursement0
+msgid "The accoutant reimburse the expenses"
+msgstr ""
+
+#. module: hr_expense
+#: model:mail.message.subtype,description:hr_expense.mt_expense_approved
+msgid "Expense approved"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,date_confirm:0
+#: field:hr.expense.report,date_confirm:0
+msgid "Confirmation Date"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: view:hr.expense.report:0
+msgid "Group By..."
+msgstr "จัดกลุ่มตาม..."
+
+#. module: hr_expense
+#: model:product.template,name:hr_expense.air_ticket_product_template
+msgid "Air Ticket"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+msgid "Validated By"
+msgstr "ตรวจสอบโดย"
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: field:hr.expense.expense,department_id:0
+#: view:hr.expense.report:0
+#: field:hr.expense.report,department_id:0
+msgid "Department"
+msgstr "แผนก"
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "New Expense"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.line,uom_id:0
+#: view:product.product:0
+msgid "Unit of Measure"
+msgstr "หน่วยของการวัด"
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "March"
+msgstr "มีนาคม"
+
+#. module: hr_expense
+#: field:hr.expense.expense,message_unread:0
+msgid "Unread Messages"
+msgstr "ข้อความที่ไม่ได้อ่าน"
+
+#. module: hr_expense
+#: field:hr.expense.expense,company_id:0
+#: view:hr.expense.report:0
+#: field:hr.expense.report,company_id:0
+msgid "Company"
+msgstr "บริษัท"
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "Set to Draft"
+msgstr "กำหนดให้เป็นแบบร่าง"
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "To Pay"
+msgstr ""
+
+#. module: hr_expense
+#: code:addons/hr_expense/hr_expense.py:172
+#, python-format
+msgid ""
+"No expense journal found. Please make sure you have a journal with type "
+"'purchase' configured."
+msgstr ""
+
+#. module: hr_expense
+#: model:ir.model,name:hr_expense.model_hr_expense_report
+msgid "Expenses Statistics"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "Open Receipt"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+#: field:hr.expense.report,day:0
+msgid "Day"
+msgstr "วัน"
+
+#. module: hr_expense
+#: help:hr.expense.expense,date_valid:0
+msgid ""
+"Date of the acceptation of the sheet expense. It's filled when the button "
+"Accept is pressed."
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "Notes"
+msgstr "บันทึกย่อ"
+
+#. module: hr_expense
+#: field:hr.expense.expense,message_ids:0
+msgid "Messages"
+msgstr "ข้อความ"
+
+#. module: hr_expense
+#: code:addons/hr_expense/hr_expense.py:172
+#: code:addons/hr_expense/hr_expense.py:238
+#: code:addons/hr_expense/hr_expense.py:240
+#: code:addons/hr_expense/hr_expense.py:349
+#: code:addons/hr_expense/hr_expense.py:353
+#, python-format
+msgid "Error!"
+msgstr ""
+
+#. module: hr_expense
+#: model:mail.message.subtype,description:hr_expense.mt_expense_refused
+msgid "Expense refused"
+msgstr ""
+
+#. module: hr_expense
+#: model:ir.actions.act_window,name:hr_expense.hr_expense_product
+#: view:product.product:0
+msgid "Products"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+msgid "Confirm Expenses"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,state:0
+msgid "Cancelled"
+msgstr "ยกเลิกแล้ว"
+
+#. module: hr_expense
+#: model:process.node,note:hr_expense.process_node_refused0
+msgid "The direct manager refuses the sheet.Reset as draft."
+msgstr ""
+
+#. module: hr_expense
+#: help:hr.expense.expense,message_unread:0
+msgid "If checked new messages require your attention."
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,state:0
+msgid "Waiting confirmation"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,state:0
+msgid "Accepted"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.line,ref:0
+msgid "Reference"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+msgid "Certified honest and conform,"
+msgstr ""
+
+#. module: hr_expense
+#: help:hr.expense.expense,state:0
+msgid ""
+"When the expense request is created the status is 'Draft'.\n"
+" It is confirmed by the user and request is sent to admin, the status is "
+"'Waiting Confirmation'. \n"
+"If the admin accepts it, the status is 'Accepted'.\n"
+" If a receipt is made for the expense request, the status is 'Done'."
+msgstr ""
+
+#. module: hr_expense
+#: help:hr.expense.expense,date_confirm:0
+msgid ""
+"Date of the confirmation of the sheet expense. It's filled when the button "
+"Confirm is pressed."
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+#: field:hr.expense.report,nbr:0
+msgid "# of Lines"
+msgstr ""
+
+#. module: hr_expense
+#: help:hr.expense.expense,message_summary:0
+msgid ""
+"Holds the Chatter summary (number of messages, ...). This summary is "
+"directly in html format in order to be inserted in kanban views."
+msgstr ""
+
+#. module: hr_expense
+#: code:addons/hr_expense/hr_expense.py:453
+#, python-format
+msgid "Warning"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+msgid "(Date and signature)"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+msgid "Total:"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition,name:hr_expense.process_transition_refuseexpense0
+msgid "Refuse expense"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.report,price_average:0
+msgid "Average Price"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: model:process.transition.action,name:hr_expense.process_transition_action_confirm0
+msgid "Confirm"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.node,note:hr_expense.process_node_supplierinvoice0
+msgid "The accoutant validates the sheet"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.report,delay_valid:0
+msgid "Delay to Valid"
+msgstr ""
+
+#. module: hr_expense
+#: help:hr.expense.line,sequence:0
+msgid "Gives the sequence order when displaying a list of expense lines."
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,state:0
+#: view:hr.expense.report:0
+#: field:hr.expense.report,state:0
+msgid "Status"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.line,analytic_account:0
+#: view:hr.expense.report:0
+#: field:hr.expense.report,analytic_account:0
+msgid "Analytic account"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.report,date:0
+msgid "Date "
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+msgid "Waiting"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,message_follower_ids:0
+msgid "Followers"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+#: view:hr.expense.expense:0
+#: field:hr.expense.expense,employee_id:0
+#: view:hr.expense.report:0
+msgid "Employee"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: selection:hr.expense.expense,state:0
+msgid "New"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+#: field:hr.expense.report,product_qty:0
+msgid "Qty"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+#: field:hr.expense.report,price_total:0
+msgid "Total Price"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.node,note:hr_expense.process_node_reinvoicing0
+msgid "Some costs may be reinvoices to the customer"
+msgstr ""
+
+#. module: hr_expense
+#: code:addons/hr_expense/hr_expense.py:238
+#, python-format
+msgid "The employee must have a home address."
+msgstr ""
+
+#. module: hr_expense
+#: view:board.board:0
+#: view:hr.expense.expense:0
+#: model:ir.actions.act_window,name:hr_expense.action_my_expense
+msgid "My Expenses"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+msgid "Creation Date"
+msgstr ""
+
+#. module: hr_expense
+#: model:ir.actions.report.xml,name:hr_expense.hr_expenses
+msgid "HR expenses"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,id:0
+msgid "Sheet ID"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition,name:hr_expense.process_transition_reimburseexpense0
+msgid "Reimburse expense"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,journal_id:0
+#: field:hr.expense.report,journal_id:0
+msgid "Force Journal"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+#: field:hr.expense.report,no_of_products:0
+msgid "# of Products"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "July"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition,note:hr_expense.process_transition_reimburseexpense0
+msgid "After creating invoice, reimburse expenses"
+msgstr ""
+
+#. module: hr_expense
+#: code:addons/hr_expense/hr_expense.py:121
+#, python-format
+msgid "Warning!"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.node,name:hr_expense.process_node_reimbursement0
+msgid "Reimbursement"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,date_valid:0
+#: field:hr.expense.report,date_valid:0
+msgid "Validation Date"
+msgstr ""
+
+#. module: hr_expense
+#: code:addons/hr_expense/hr_expense.py:226
+#, python-format
+msgid "Expense Receipt"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+#: model:ir.actions.act_window,name:hr_expense.action_hr_expense_report_all
+#: model:ir.ui.menu,name:hr_expense.menu_hr_expense_report_all
+msgid "Expenses Analysis"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: field:hr.expense.line,expense_id:0
+#: model:ir.model,name:hr_expense.model_hr_expense_expense
+#: model:process.process,name:hr_expense.process_process_expenseprocess0
+msgid "Expense"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: field:hr.expense.expense,line_ids:0
+#: view:hr.expense.line:0
+msgid "Expense Lines"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.report,delay_confirm:0
+msgid "Delay to Confirm"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "September"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "December"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: view:hr.expense.report:0
+#: field:hr.expense.report,month:0
+msgid "Month"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,currency_id:0
+#: field:hr.expense.report,currency_id:0
+msgid "Currency"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,voucher_id:0
+msgid "Employee's Receipt"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.expense,state:0
+msgid "Waiting Approval"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.node,note:hr_expense.process_node_draftexpenses0
+msgid "Employee encode all his expenses"
+msgstr ""
+
+#. module: hr_expense
+#: code:addons/hr_expense/hr_expense.py:453
+#, python-format
+msgid ""
+"Selected Unit of Measure does not belong to the same category as the product "
+"Unit of Measure"
+msgstr ""
+
+#. module: hr_expense
+#: help:hr.expense.expense,journal_id:0
+msgid "The journal used when the expense is done."
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,note:0
+msgid "Note"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition,note:hr_expense.process_transition_reimbursereinvoice0
+msgid "Create Customer invoice"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,state:0
+msgid "Draft"
+msgstr ""
+
+#. module: hr_expense
+#: code:addons/hr_expense/hr_expense.py:353
+#, python-format
+msgid ""
+"Please configure Default Expense account for Product purchase: "
+"`property_account_expense_categ`."
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition,note:hr_expense.process_transition_approveexpense0
+msgid "Expense is approved."
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "August"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.node,note:hr_expense.process_node_approved0
+msgid "The direct manager approves the sheet"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: field:hr.expense.expense,amount:0
+msgid "Total Amount"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "June"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.node,name:hr_expense.process_node_draftexpenses0
+msgid "Draft Expenses"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,message_is_follower:0
+msgid "Is a Follower"
+msgstr ""
+
+#. module: hr_expense
+#: model:ir.actions.act_window,name:hr_expense.product_normal_form_view_installer
+msgid "Review Your Expenses Products"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+#: field:hr.expense.expense,date:0
+#: field:hr.expense.line,date_value:0
+msgid "Date"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "November"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+msgid "Extended Filters..."
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,user_id:0
+msgid "User"
+msgstr ""
+
+#. module: hr_expense
+#: model:ir.ui.menu,name:hr_expense.menu_hr_product
+msgid "Expense Categories"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "October"
+msgstr ""
+
+#. module: hr_expense
+#: model:ir.actions.act_window,help:hr_expense.expense_all
+msgid ""
+"\n"
+" Click to register new expenses. \n"
+"
\n"
+" OpenERP will ensure the whole process is followed; the "
+"expense\n"
+" sheet is validated by manager(s), the employee is "
+"reimbursed\n"
+" from his expenses, some expenses must be re-invoiced to the\n"
+" customers.\n"
+"
\n"
+" "
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "Generate Accounting Entries"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "January"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+msgid "HR Expenses"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,message_summary:0
+msgid "Summary"
+msgstr ""
+
+#. module: hr_expense
+#: model:product.template,name:hr_expense.car_travel_product_template
+msgid "Car Travel Expenses"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "Submit to Manager"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+msgid "Done Expenses"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.node,note:hr_expense.process_node_confirmedexpenses0
+msgid "The employee validates his expense sheet"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "Expenses to Invoice"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.node,name:hr_expense.process_node_supplierinvoice0
+#: model:process.transition,name:hr_expense.process_transition_approveinvoice0
+msgid "Supplier Invoice"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "Expenses Sheet"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.report,voucher_id:0
+msgid "Receipt"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+msgid "Approved Expenses"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+#: field:hr.expense.line,unit_amount:0
+msgid "Unit Price"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+#: selection:hr.expense.report,state:0
+msgid "Done"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition.action,name:hr_expense.process_transition_action_supplierinvoice0
+msgid "Invoice"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+#: field:hr.expense.report,year:0
+msgid "Year"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition,name:hr_expense.process_transition_reimbursereinvoice0
+msgid "Reinvoice"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "Expense Date"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,user_valid:0
+msgid "Validation By"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: model:process.transition.action,name:hr_expense.process_transition_action_refuse0
+msgid "Refuse"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition,name:hr_expense.process_transition_confirmexpense0
+msgid "Confirm expense"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition,name:hr_expense.process_transition_approveexpense0
+msgid "Approve expense"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition.action,name:hr_expense.process_transition_action_accept0
+msgid "Accept"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+msgid "This document must be dated and signed for reimbursement"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition,note:hr_expense.process_transition_refuseexpense0
+msgid "Expense is refused."
+msgstr ""
+
+#. module: hr_expense
+#: model:ir.actions.act_window,help:hr_expense.product_normal_form_view_installer
+msgid ""
+"Define one product for each expense type allowed for an employee (travel by "
+"car, hostel, restaurant, etc). If you reimburse the employees at a fixed "
+"rate, set a cost and a unit of measure on the product. If you reimburse "
+"based on real costs, set the cost at 0.00. The user will set the real price "
+"when recording his expense sheet."
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.expense,state:0
+#: view:hr.expense.report:0
+#: model:mail.message.subtype,name:hr_expense.mt_expense_approved
+#: model:process.node,name:hr_expense.process_node_approved0
+msgid "Approved"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.line,product_id:0
+#: view:hr.expense.report:0
+#: field:hr.expense.report,product_id:0
+#: model:ir.model,name:hr_expense.model_product_product
+msgid "Product"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+#: view:hr.expense.expense:0
+#: field:hr.expense.expense,name:0
+#: field:hr.expense.line,description:0
+msgid "Description"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "May"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.line,unit_quantity:0
+msgid "Quantities"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+msgid "Price"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.report,no_of_account:0
+msgid "# of Accounts"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.expense,state:0
+#: model:mail.message.subtype,name:hr_expense.mt_expense_refused
+#: model:process.node,name:hr_expense.process_node_refused0
+msgid "Refused"
+msgstr ""
+
+#. module: hr_expense
+#: field:product.product,hr_expense_ok:0
+msgid "Can be Expensed"
+msgstr ""
+
+#. module: hr_expense
+#: model:mail.message.subtype,description:hr_expense.mt_expense_confirmed
+msgid "Expense confirmed, waiting confirmation"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+msgid "Ref."
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.report,employee_id:0
+msgid "Employee's Name"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.report:0
+#: field:hr.expense.report,user_id:0
+msgid "Validation User"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "Accounting Data"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "February"
+msgstr ""
+
+#. module: hr_expense
+#: report:hr.expense:0
+msgid "Name"
+msgstr ""
+
+#. module: hr_expense
+#: code:addons/hr_expense/hr_expense.py:121
+#, python-format
+msgid "You can only delete draft expenses!"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.expense,account_move_id:0
+msgid "Ledger Posting"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition,note:hr_expense.process_transition_approveinvoice0
+msgid "Creates supplier invoice."
+msgstr ""
+
+#. module: hr_expense
+#: model:product.template,name:hr_expense.hotel_rent_product_template
+msgid "Hotel Accommodation"
+msgstr ""
+
+#. module: hr_expense
+#: selection:hr.expense.report,month:0
+msgid "April"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.line,name:0
+msgid "Expense Note"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "Approve"
+msgstr ""
+
+#. module: hr_expense
+#: help:hr.expense.expense,message_ids:0
+msgid "Messages and communication history"
+msgstr ""
+
+#. module: hr_expense
+#: field:hr.expense.line,sequence:0
+msgid "Sequence"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.transition,note:hr_expense.process_transition_confirmexpense0
+msgid "Expense is confirmed."
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: model:ir.actions.act_window,name:hr_expense.expense_all
+#: model:ir.ui.menu,name:hr_expense.menu_expense_all
+#: model:ir.ui.menu,name:hr_expense.next_id_49
+#: model:product.category,name:hr_expense.cat_expense
+msgid "Expenses"
+msgstr ""
+
+#. module: hr_expense
+#: help:product.product,hr_expense_ok:0
+msgid "Specify if the product can be selected in an HR expense line."
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+msgid "Accounting"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: model:mail.message.subtype,name:hr_expense.mt_expense_confirmed
+msgid "To Approve"
+msgstr ""
+
+#. module: hr_expense
+#: view:hr.expense.expense:0
+#: view:hr.expense.line:0
+#: field:hr.expense.line,total_amount:0
+msgid "Total"
+msgstr ""
+
+#. module: hr_expense
+#: model:process.node,name:hr_expense.process_node_reinvoicing0
+msgid "Reinvoicing"
+msgstr ""
diff --git a/addons/hr_holidays/i18n/pl.po b/addons/hr_holidays/i18n/pl.po
index ebc13bc02d4..ad5730d2268 100644
--- a/addons/hr_holidays/i18n/pl.po
+++ b/addons/hr_holidays/i18n/pl.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2012-12-14 12:51+0000\n"
-"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) \n"
+"PO-Revision-Date: 2013-06-22 10:54+0000\n"
+"Last-Translator: Dariusz Kubiak \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:30+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-23 05:13+0000\n"
+"X-Generator: Launchpad (build 16677)\n"
#. module: hr_holidays
#: selection:hr.holidays.status,color_name:0
@@ -32,7 +32,7 @@ msgid "Waiting Second Approval"
msgstr "Oczekuje na drugą aprobatę"
#. module: hr_holidays
-#: code:addons/hr_holidays/hr_holidays.py:298
+#: code:addons/hr_holidays/hr_holidays.py:309
#, python-format
msgid ""
"You cannot modify a leave request that has been approved. Contact a human "
@@ -109,11 +109,13 @@ msgid ""
"The default duration interval between the start date and the end date is 8 "
"hours. Feel free to adapt it to your needs."
msgstr ""
+"Domyślny odstęp między datą rozpoczęcia i data zakończenia jest 8 godzin. "
+"Zapraszam do dostosowania go do swoich potrzeb."
#. module: hr_holidays
#: model:mail.message.subtype,description:hr_holidays.mt_holidays_refused
msgid "Request refused"
-msgstr ""
+msgstr "Wniosek odrzucony"
#. module: hr_holidays
#: field:hr.holidays,number_of_days_temp:0
@@ -274,12 +276,12 @@ msgid ""
msgstr ""
#. module: hr_holidays
-#: code:addons/hr_holidays/hr_holidays.py:238
#: code:addons/hr_holidays/hr_holidays.py:249
-#: code:addons/hr_holidays/hr_holidays.py:274
-#: code:addons/hr_holidays/hr_holidays.py:298
-#: code:addons/hr_holidays/hr_holidays.py:421
-#: code:addons/hr_holidays/hr_holidays.py:471
+#: code:addons/hr_holidays/hr_holidays.py:260
+#: code:addons/hr_holidays/hr_holidays.py:285
+#: code:addons/hr_holidays/hr_holidays.py:309
+#: code:addons/hr_holidays/hr_holidays.py:432
+#: code:addons/hr_holidays/hr_holidays.py:482
#, python-format
msgid "Warning!"
msgstr "Ostrzeżenie !"
@@ -317,7 +319,7 @@ msgid "Sick Leaves"
msgstr "Zwolnienie lekarskie"
#. module: hr_holidays
-#: code:addons/hr_holidays/hr_holidays.py:478
+#: code:addons/hr_holidays/hr_holidays.py:489
#, python-format
msgid "Leave Request for %s"
msgstr "Wniosek urlopowy dla %s"
@@ -341,7 +343,7 @@ msgstr "Pozostało dni urlopu"
#. module: hr_holidays
#: field:hr.holidays,message_follower_ids:0
msgid "Followers"
-msgstr ""
+msgstr "Obserwatorzy"
#. module: hr_holidays
#: model:ir.model,name:hr_holidays.model_hr_holidays_remaining_leaves_user
@@ -388,7 +390,7 @@ msgid "Wheat"
msgstr "Pszenny"
#. module: hr_holidays
-#: code:addons/hr_holidays/hr_holidays.py:476
+#: code:addons/hr_holidays/hr_holidays.py:487
#, python-format
msgid "Allocation for %s"
msgstr "Przydział dla %s"
@@ -412,7 +414,7 @@ msgid "Number of Days"
msgstr "Liczba dni"
#. module: hr_holidays
-#: code:addons/hr_holidays/hr_holidays.py:471
+#: code:addons/hr_holidays/hr_holidays.py:482
#, python-format
msgid ""
"The feature behind the field 'Remaining Legal Leaves' can only be used when "
@@ -516,7 +518,7 @@ msgid "Start Date"
msgstr "Data początkowa"
#. module: hr_holidays
-#: code:addons/hr_holidays/hr_holidays.py:421
+#: code:addons/hr_holidays/hr_holidays.py:432
#, python-format
msgid ""
"There are not enough %s allocated for employee %s; please create an "
@@ -678,7 +680,7 @@ msgstr "Podsumowanie"
#. module: hr_holidays
#: model:hr.holidays.status,name:hr_holidays.holiday_status_unpaid
msgid "Unpaid"
-msgstr "Niezapłacone"
+msgstr "Bezpłatny"
#. module: hr_holidays
#: xsl:holidays.summary:0
@@ -741,7 +743,7 @@ msgstr "Różne"
#. module: hr_holidays
#: model:hr.holidays.status,name:hr_holidays.holiday_status_comp
msgid "Compensatory Days"
-msgstr ""
+msgstr "Urlop wyrównawczy"
#. module: hr_holidays
#: selection:hr.holidays.status,color_name:0
@@ -766,7 +768,7 @@ msgid "Validated"
msgstr "Zatwierdzony"
#. module: hr_holidays
-#: code:addons/hr_holidays/hr_holidays.py:238
+#: code:addons/hr_holidays/hr_holidays.py:249
#, python-format
msgid "You cannot delete a leave which is in %s state."
msgstr "Nie możesz usunąć nieobecności, która jest w stanie %s."
@@ -830,7 +832,7 @@ msgid "To Submit"
msgstr "Do wysłania"
#. module: hr_holidays
-#: code:addons/hr_holidays/hr_holidays.py:343
+#: code:addons/hr_holidays/hr_holidays.py:354
#: view:hr.holidays:0
#: selection:hr.holidays,type:0
#: field:resource.calendar.leaves,holiday_id:0
@@ -930,8 +932,8 @@ msgid "Messages and communication history"
msgstr "Wiadomości i historia komunikacji"
#. module: hr_holidays
-#: code:addons/hr_holidays/hr_holidays.py:249
-#: code:addons/hr_holidays/hr_holidays.py:274
+#: code:addons/hr_holidays/hr_holidays.py:260
+#: code:addons/hr_holidays/hr_holidays.py:285
#: sql_constraint:hr.holidays:0
#, python-format
msgid "The start date must be anterior to the end date."
diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py
index e26c96d41d9..c25583cba77 100644
--- a/addons/hr_recruitment/hr_recruitment.py
+++ b/addons/hr_recruitment/hr_recruitment.py
@@ -506,33 +506,18 @@ class hr_job(osv.osv):
help="Email alias for this job position. New emails will automatically "
"create new applicants for this job position."),
}
- _defaults = {
- 'alias_domain': False, # always hide alias during creation
- }
def _auto_init(self, cr, context=None):
"""Installation hook to create aliases for all jobs and avoid constraint errors."""
- if context is None:
- context = {}
- alias_context = dict(context, alias_model_name='hr.applicant')
- res = self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(hr_job, self)._auto_init,
- self._columns['alias_id'], 'name', alias_prefix='job+', alias_defaults={'job_id': 'id'}, context=alias_context)
- return res
+ return self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(hr_job, self)._auto_init,
+ 'hr.applicant', self._columns['alias_id'], 'name', alias_prefix='job+', alias_defaults={'job_id': 'id'}, context=context)
def create(self, cr, uid, vals, context=None):
- mail_alias = self.pool.get('mail.alias')
- if not vals.get('alias_id'):
- vals.pop('alias_name', None) # prevent errors during copy()
- alias_id = mail_alias.create_unique_alias(cr, uid,
- # Using '+' allows using subaddressing for those who don't
- # have a catchall domain setup.
- {'alias_name': 'jobs+'+vals['name']},
- model_name="hr.applicant",
- context=context)
- vals['alias_id'] = alias_id
- res = super(hr_job, self).create(cr, uid, vals, context)
- mail_alias.write(cr, uid, [vals['alias_id']], {"alias_defaults": {'job_id': res}}, context)
- return res
+ alias_context = dict(context, alias_model_name='hr.applicant', alias_parent_model_name=self._name)
+ job_id = super(hr_job, self).create(cr, uid, vals, context=alias_context)
+ job = self.browse(cr, uid, job_id, context=context)
+ self.pool.get('mail.alias').write(cr, uid, [job.alias_id.id], {'alias_parent_thread_id': job_id, "alias_defaults": {'job_id': job_id}}, context)
+ return job_id
def unlink(self, cr, uid, ids, context=None):
# Cascade-delete mail aliases as well, as they should not exist without the job position.
@@ -550,15 +535,16 @@ class hr_job(osv.osv):
if record.survey_id:
datas['ids'] = [record.survey_id.id]
datas['model'] = 'survey.print'
- context.update({'response_id': [0], 'response_no': 0,})
+ context.update({'response_id': [0], 'response_no': 0})
return {
'type': 'ir.actions.report.xml',
'report_name': 'survey.form',
'datas': datas,
- 'context' : context,
- 'nodestroy':True,
+ 'context': context,
+ 'nodestroy': True,
}
+
class applicant_category(osv.osv):
""" Category of applicant """
_name = "hr.applicant_category"
diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml
index f6fb202252c..9cbfd4560e7 100644
--- a/addons/hr_recruitment/hr_recruitment_view.xml
+++ b/addons/hr_recruitment/hr_recruitment_view.xml
@@ -316,18 +316,19 @@
attrs="{'invisible':[('survey_id','=',False)]}"/>
-
-
+
-
-
-
-
- @
-
-
-
+
+
+
+
diff --git a/addons/hr_recruitment/i18n/th.po b/addons/hr_recruitment/i18n/th.po
index 74af8f627ab..fb80cbf4ca7 100644
--- a/addons/hr_recruitment/i18n/th.po
+++ b/addons/hr_recruitment/i18n/th.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-06-20 05:17+0000\n"
-"X-Generator: Launchpad (build 16673)\n"
+"X-Launchpad-Export-Date: 2013-06-21 05:36+0000\n"
+"X-Generator: Launchpad (build 16677)\n"
#. module: hr_recruitment
#: help:hr.applicant,active:0
diff --git a/addons/idea/__init__.py b/addons/idea/__init__.py
index e6f7333e055..2b8966f9e7a 100644
--- a/addons/idea/__init__.py
+++ b/addons/idea/__init__.py
@@ -2,7 +2,7 @@
##############################################################################
#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ().
+# Copyright (C) 2004-Today OpenERP S.A. ().
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -19,5 +19,4 @@
#
##############################################################################
-import idea
-
+import models
diff --git a/addons/idea/__openerp__.py b/addons/idea/__openerp__.py
index 8f32e1e91c4..7d8560a2cf4 100644
--- a/addons/idea/__openerp__.py
+++ b/addons/idea/__openerp__.py
@@ -2,7 +2,7 @@
##############################################################################
#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ().
+# Copyright (C) 2004-Today OpenERP S.A. ().
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -22,29 +22,39 @@
{
'name': 'Ideas',
- 'version': '0.1',
+ 'summary': 'Share and Discuss your Ideas',
+ 'version': '1.0',
'category': 'Tools',
'description': """
-This module allows user to easily and efficiently participate in enterprise innovation.
-=======================================================================================
+Share your ideas and participate in enterprise innovation
+=========================================================
-It allows everybody to express ideas about different subjects.
-Then, other users can comment on these ideas and vote for particular ideas.
-Each idea has a score based on the different votes.
+The Ideas module give users a way to express and discuss ideas, allowing everybody
+to participate in enterprise innovation. Every user can suggest, comment ideas.
The managers can obtain an easy view of best ideas from all the users.
Once installed, check the menu 'Ideas' in the 'Tools' main menu.""",
'author': 'OpenERP SA',
- 'website': 'http://openerp.com',
+ 'website': 'http://www.openerp.com',
'depends': ['mail'],
'data': [
- 'security/idea_security.xml',
+ 'security/idea.xml',
'security/ir.model.access.csv',
- 'idea_view.xml',
- 'idea_workflow.xml',
+ 'views/idea.xml',
+ 'views/category.xml',
+ 'data/idea.xml',
+ 'data/idea_workflow.xml',
+ ],
+ 'demo': [
+ 'demo/idea.xml',
],
- 'demo': ['idea_data.xml'],
- 'test':[],
'installable': True,
+ 'application': True,
'images': [],
+ 'css': [
+ 'static/src/css/idea_idea.css',
+ ],
+ 'js': [],
+ 'qweb': [],
}
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/idea/data/idea.xml b/addons/idea/data/idea.xml
new file mode 100644
index 00000000000..c057868d6de
--- /dev/null
+++ b/addons/idea/data/idea.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/idea/data/idea_workflow.xml b/addons/idea/data/idea_workflow.xml
new file mode 100644
index 00000000000..b460c73a6ed
--- /dev/null
+++ b/addons/idea/data/idea_workflow.xml
@@ -0,0 +1,57 @@
+
+
+
+
+ idea.wkf
+ idea.idea
+ True
+
+
+
+
+ True
+ normal
+ function
+ idea_set_normal_priority()
+
+
+
+
+ low
+ function
+ idea_set_low_priority()
+
+
+
+
+ high
+ function
+ idea_set_high_priority()
+
+
+
+
+
+ idea_set_low_priority
+
+
+
+
+
+ idea_set_normal_priority
+
+
+
+
+
+ idea_set_high_priority
+
+
+
+
+
+ idea_set_normal_priority
+
+
+
+
diff --git a/addons/idea/demo/idea.xml b/addons/idea/demo/idea.xml
new file mode 100644
index 00000000000..2b4ff58b973
--- /dev/null
+++ b/addons/idea/demo/idea.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+ Sales
+
+
+ Organization
+
+
+ Technical
+
+
+
+ Docking station along with tablet PC
+ When you sell a tablet PC, maybe we could propose a docking station with it. I offer 20% on the docking stating (not the tablet).
+
+
+
+
+
+ Communicate using emails
+ I start communicating with prospects more by email than phonecalls. I send an email to create a sense of emergency, like "can I call you this week about our quote?" and I call only those that answer this email.
+
+ open
+
+
+
+
+
+ Use a two-stages testing phase
+ We should perform testing using two levels of validation.
+
+ open
+
+
+
+
+
+ Write some functional documentation about procurements
+ We receive many questions about OpenChatter. Maybe some functional doc could save us some time.
+
+ open
+
+
+
+
+ Better management of smtp errors
+ There should be away to store the reason why some emails are not sent.
+
+ close
+
+
+
+
+
+ Kitten mode enabled by default
+ As this is the most loved feature, the kitten mode should be enabled by default. And maybe even impossible to remove.
+
+ cancel
+
+
+
+
+
+
+
diff --git a/addons/idea/idea.py b/addons/idea/idea.py
deleted file mode 100644
index d1e250ce9a5..00000000000
--- a/addons/idea/idea.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ().
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-##############################################################################
-
-from openerp.osv import osv
-from openerp.osv import fields
-from openerp.tools.translate import _
-import time
-
-VoteValues = [('-1', 'Not Voted'), ('0', 'Very Bad'), ('25', 'Bad'), \
- ('50', 'Normal'), ('75', 'Good'), ('100', 'Very Good') ]
-DefaultVoteValue = '50'
-
-class idea_category(osv.osv):
- """ Category of Idea """
- _name = "idea.category"
- _description = "Idea Category"
- _columns = {
- 'name': fields.char('Category Name', size=64, required=True),
- }
- _sql_constraints = [
- ('name', 'unique(name)', 'The name of the category must be unique')
- ]
- _order = 'name asc'
-
-
-class idea_idea(osv.osv):
- """ Idea """
- _name = 'idea.idea'
- _inherit = ['mail.thread']
- _columns = {
- 'create_uid': fields.many2one('res.users', 'Creator', required=True, readonly=True),
- 'name': fields.char('Idea Summary', size=64, required=True, readonly=True, oldname='title', states={'draft': [('readonly', False)]}),
- 'description': fields.text('Description', help='Content of the idea', readonly=True, states={'draft': [('readonly', False)]}),
- 'category_ids': fields.many2many('idea.category', string='Tags', readonly=True, states={'draft': [('readonly', False)]}),
- 'state': fields.selection([('draft', 'New'),
- ('open', 'Accepted'),
- ('cancel', 'Refused'),
- ('close', 'Done')],
- 'Status', readonly=True, track_visibility='onchange',
- )
- }
- _sql_constraints = [
- ('name', 'unique(name)', 'The name of the idea must be unique')
- ]
- _defaults = {
- 'state': lambda *a: 'draft',
- }
- _order = 'name asc'
-
- def idea_cancel(self, cr, uid, ids, context=None):
- return self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
-
- def idea_open(self, cr, uid, ids, context={}):
- return self.write(cr, uid, ids, {'state': 'open'}, context=context)
-
- def idea_close(self, cr, uid, ids, context={}):
- return self.write(cr, uid, ids, {'state': 'close'}, context=context)
-
- def idea_draft(self, cr, uid, ids, context={}):
- return self.write(cr, uid, ids, {'state': 'draft'}, context=context)
diff --git a/addons/idea/idea_data.xml b/addons/idea/idea_data.xml
deleted file mode 100644
index 421cb6a9eef..00000000000
--- a/addons/idea/idea_data.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
- Sales
-
-
- Organization
-
-
- Technical
-
-
-
-
-
-
-
-
-
diff --git a/addons/idea/idea_view.xml b/addons/idea/idea_view.xml
deleted file mode 100644
index 53734d53919..00000000000
--- a/addons/idea/idea_view.xml
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-
-
-
-
-
- idea.category.search
- idea.category
-
-
-
-
-
-
-
-
-
- idea.category.form
- idea.category
-
-
-
-
-
-
-
- idea.category.tree
- idea.category
-
-
-
-
-
-
-
-
-
-
-
- Categories
- idea.category
- form
- tree,form
-
-
-
-
-
-
-
-
-
-
-
-
-
- idea.idea.form
- idea.idea
-
-
-
-
-
-
-
-
- idea.idea.tree
- idea.idea
-
-
-
-
-
-
-
-
-
-
-
-
- idea.idea.search
- idea.idea
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ideas
- idea.idea
- form
- tree,form
-
-
-
-
-
-
-
diff --git a/addons/idea/idea_workflow.xml b/addons/idea/idea_workflow.xml
deleted file mode 100644
index 649541ae349..00000000000
--- a/addons/idea/idea_workflow.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
- idea.wkf
- idea.idea
- True
-
-
-
-
- True
- draft
- function
- idea_draft()
-
-
-
-
- open
- function
- idea_open()
-
-
-
-
- close
- function
- idea_close()
- True
-
-
-
-
- cancel
- function
- idea_cancel()
- True
-
-
-
-
-
- idea_open
-
-
-
-
-
- idea_close
-
-
-
-
-
- idea_cancel
-
-
-
-
diff --git a/addons/idea/models/__init__.py b/addons/idea/models/__init__.py
new file mode 100644
index 00000000000..e8a48771771
--- /dev/null
+++ b/addons/idea/models/__init__.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2013-TODAY OpenERP S.A.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+import idea
diff --git a/addons/idea/models/idea.py b/addons/idea/models/idea.py
new file mode 100644
index 00000000000..61934cfc3b2
--- /dev/null
+++ b/addons/idea/models/idea.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-Today OpenERP S.A. ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from openerp.osv import osv
+from openerp.osv import fields
+
+
+class IdeaCategory(osv.Model):
+ """ Category of Idea """
+ _name = "idea.category"
+ _description = "Idea Category"
+
+ _order = 'name asc'
+
+ _columns = {
+ 'name': fields.char('Category Name', size=64, required=True),
+ }
+
+ _sql_constraints = [
+ ('name', 'unique(name)', 'The name of the category must be unique')
+ ]
+
+
+class IdeaIdea(osv.Model):
+ """ Model of an Idea """
+ _name = 'idea.idea'
+ _description = 'Propose and Share your Ideas'
+
+ _rec_name = 'name'
+ _order = 'name asc'
+
+ def _get_state_list(self, cr, uid, context=None):
+ return [('draft', 'New'),
+ ('open', 'In discussion'),
+ ('close', 'Accepted'),
+ ('cancel', 'Refused')]
+
+ def _get_color(self, cr, uid, ids, fields, args, context=None):
+ res = dict.fromkeys(ids, 3)
+ for idea in self.browse(cr, uid, ids, context=context):
+ if idea.priority == 'low':
+ res[idea.id] = 0
+ elif idea.priority == 'high':
+ res[idea.id] = 7
+ return res
+
+ _columns = {
+ 'user_id': fields.many2one('res.users', 'Responsible', required=True),
+ 'name': fields.char('Summary', required=True, readonly=True,
+ states={'draft': [('readonly', False)]},
+ oldname='title'),
+ 'description': fields.text('Description', required=True,
+ states={'draft': [('readonly', False)]},
+ help='Content of the idea'),
+ 'category_ids': fields.many2many('idea.category', string='Tags'),
+ 'state': fields.selection(_get_state_list, string='Status', required=True),
+ 'priority': fields.selection([('low', 'Low'), ('normal', 'Normal'), ('high', 'High')],
+ string='Priority', required=True),
+ 'color': fields.function(_get_color, type='integer', string='Color Index'),
+ }
+
+ _sql_constraints = [
+ ('name', 'unique(name)', 'The name of the idea must be unique')
+ ]
+
+ _defaults = {
+ 'user_id': lambda self, cr, uid, ctx=None: uid,
+ 'state': lambda self, cr, uid, ctx=None: self._get_state_list(cr, uid, ctx)[0][0],
+ 'priority': 'normal',
+ }
+
+ #------------------------------------------------------
+ # Technical stuff
+ #------------------------------------------------------
+
+ def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False):
+ """ Override read_group to always display all states. """
+ if groupby and groupby[0] == "state":
+ # Default result structure
+ states = self._get_state_list(cr, uid, context=context)
+ read_group_all_states = [{
+ '__context': {'group_by': groupby[1:]},
+ '__domain': domain + [('state', '=', state_value)],
+ 'state': state_value,
+ 'state_count': 0,
+ } for state_value, state_name in states]
+ # Get standard results
+ read_group_res = super(IdeaIdea, self).read_group(cr, uid, domain, fields, groupby, offset, limit, context, orderby)
+ # Update standard results with default results
+ result = []
+ for state_value, state_name in states:
+ res = filter(lambda x: x['state'] == state_value, read_group_res)
+ if not res:
+ res = filter(lambda x: x['state'] == state_value, read_group_all_states)
+ res[0]['state'] = [state_value, state_name]
+ result.append(res[0])
+ return result
+ else:
+ return super(IdeaIdea, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby)
+
+ #------------------------------------------------------
+ # Workflow / Actions
+ #------------------------------------------------------
+
+ def idea_set_low_priority(self, cr, uid, ids, context=None):
+ return self.write(cr, uid, ids, {'priority': 'low'}, context=context)
+
+ def idea_set_normal_priority(self, cr, uid, ids, context={}):
+ return self.write(cr, uid, ids, {'priority': 'normal'}, context=context)
+
+ def idea_set_high_priority(self, cr, uid, ids, context={}):
+ return self.write(cr, uid, ids, {'priority': 'high'}, context=context)
diff --git a/addons/idea/security/idea.xml b/addons/idea/security/idea.xml
new file mode 100644
index 00000000000..e7a0d800187
--- /dev/null
+++ b/addons/idea/security/idea.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/addons/idea/security/idea_security.xml b/addons/idea/security/idea_security.xml
deleted file mode 100644
index 8743252c9e5..00000000000
--- a/addons/idea/security/idea_security.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
- User
-
-
-
-
-
-
diff --git a/addons/idea/security/ir.model.access.csv b/addons/idea/security/ir.model.access.csv
index 78b8deeaf57..761ada8132c 100644
--- a/addons/idea/security/ir.model.access.csv
+++ b/addons/idea/security/ir.model.access.csv
@@ -1,3 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_idea_category_user,idea.category user,model_idea_category,base.group_tool_user,1,1,1,1
-access_idea_idea_user,idea.idea user,model_idea_idea,base.group_tool_user,1,1,1,1
+access_idea_category_user,idea.category.user,model_idea_category,base.group_user,1,1,1,1
+access_idea_idea_user,idea.idea.user,model_idea_idea,base.group_user,1,1,1,1
diff --git a/addons/idea/static/src/css/idea_idea.css b/addons/idea/static/src/css/idea_idea.css
new file mode 100644
index 00000000000..08daffd902a
--- /dev/null
+++ b/addons/idea/static/src/css/idea_idea.css
@@ -0,0 +1,21 @@
+.openerp .oe_kanban_view .oe_kanban_idea_idea {
+ width: 200px;
+}
+
+.openerp .oe_kanban_view .oe_kanban_idea_idea .oe_avatars {
+ text-align: right;
+ margin: -5px 0 -10px 0;
+}
+
+.openerp .oe_kanban_view .oe_kanban_idea_idea .oe_avatars img {
+ width: 30px;
+ height: 30px;
+ padding-left: 0px;
+ margin-top: 3px;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
+ -box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
+}
diff --git a/addons/idea/static/src/img/icon.png b/addons/idea/static/src/img/icon.png
new file mode 100644
index 00000000000..1f0cba223bb
Binary files /dev/null and b/addons/idea/static/src/img/icon.png differ
diff --git a/addons/portal_event/event.py b/addons/idea/tests/__init__.py
similarity index 54%
rename from addons/portal_event/event.py
rename to addons/idea/tests/__init__.py
index 45026da4eba..a53567a380b 100644
--- a/addons/portal_event/event.py
+++ b/addons/idea/tests/__init__.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
##############################################################################
#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ().
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2013-TODAY OpenERP S.A.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -19,21 +19,10 @@
#
##############################################################################
-from openerp.osv import fields, osv
+from openerp.addons.idea.tests import test_idea
-class event_event(osv.osv):
- _description = 'Portal event'
- _inherit = 'event.event'
+checks = [
+ test_idea,
+]
- """
- ``visibility``: defines if the event appears on the portal's event page
- - 'public' means the event will appear for everyone (anonymous)
- - 'private' means the event won't appear
- """
- _columns = {
- 'visibility': fields.selection([('public', 'Public'),('private', 'Private')],
- string='Visibility', help='Event\'s visibility in the portal\'s contact page'),
- }
- _defaults = {
- 'visibility': 'private',
- }
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/idea/tests/test_idea.py b/addons/idea/tests/test_idea.py
new file mode 100644
index 00000000000..4ca9bb9dcb9
--- /dev/null
+++ b/addons/idea/tests/test_idea.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2013-TODAY OpenERP S.A.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from openerp.tests import common
+
+
+class TestIdeaBase(common.TransactionCase):
+
+ def setUp(self):
+ super(TestIdeaBase, self).setUp()
+ cr, uid = self.cr, self.uid
+
+ # Usefull models
+ self.idea_category = self.registry('idea.category')
+ self.idea_idea = self.registry('idea.idea')
+
+ def tearDown(self):
+ super(TestIdeaBase, self).tearDown()
+
+ def test_OO(self):
+ pass
diff --git a/addons/idea/views/category.xml b/addons/idea/views/category.xml
new file mode 100644
index 00000000000..79725fad73f
--- /dev/null
+++ b/addons/idea/views/category.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+ idea.category.search
+ idea.category
+
+
+
+
+
+
+
+
+ idea.category.form
+ idea.category
+
+
+
+
+
+
+ idea.category.tree
+ idea.category
+
+
+
+
+
+
+
+
+
+ Categories
+ idea.category
+ form
+ tree,form
+
+
+
+
+
+
+
+
+
diff --git a/addons/idea/views/idea.xml b/addons/idea/views/idea.xml
new file mode 100644
index 00000000000..b228af2da45
--- /dev/null
+++ b/addons/idea/views/idea.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+ idea.idea.kanban
+ idea.idea
+
+
+
+
+
+
+
+
+ í
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ idea.idea.form
+ idea.idea
+
+
+
+
+
+
+ idea.idea.tree
+ idea.idea
+
+
+
+
+
+
+
+
+
+
+
+ idea.idea.search
+ idea.idea
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ideas
+ idea.idea
+ form
+ kanban,tree,form
+
+
+
+
+
+
+
+
+
diff --git a/addons/im/im.py b/addons/im/im.py
index cee1705ec35..4a867789cbc 100644
--- a/addons/im/im.py
+++ b/addons/im/im.py
@@ -22,6 +22,8 @@
import openerp
import openerp.tools.config
import openerp.modules.registry
+import openerp.addons.web.http as http
+from openerp.addons.web.http import request
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
import datetime
from openerp.osv import osv, fields
@@ -90,36 +92,38 @@ POLL_TIMER = 30
DISCONNECTION_TIMER = POLL_TIMER + 5
WATCHER_ERROR_DELAY = 10
-class LongPollingController(openerp.addons.web.http.Controller):
- _cp_path = '/longpolling/im'
+class LongPollingController(http.Controller):
- @openerp.addons.web.http.jsonrequest
- def poll(self, req, last=None, users_watch=None, db=None, uid=None, password=None, uuid=None):
+ @http.route('/longpolling/im/poll', type="json", auth="none")
+ def poll(self, last=None, users_watch=None, db=None, uid=None, password=None, uuid=None):
assert_uuid(uuid)
if not openerp.evented:
raise Exception("Not usable in a server not running gevent")
from openerp.addons.im.watcher import ImWatcher
if db is not None:
- req.session._db = db
- req.session._uid = uid
- req.session._password = password
- req.session.model('im.user').im_connect(uuid=uuid, context=req.context)
- my_id = req.session.model('im.user').get_by_user_id(uuid or req.session._uid, req.context)["id"]
+ request.session.authenticate(db=db, uid=uid, password=password)
+ else:
+ request.session.authenticate(db=request.session._db, uid=request.session._uid, password=request.session._password)
+
+ with request.registry.cursor() as cr:
+ request.registry.get('im.user').im_connect(cr, request.uid, uuid=uuid, context=request.context)
+ my_id = request.registry.get('im.user').get_by_user_id(cr, request.uid, uuid or request.session._uid, request.context)["id"]
num = 0
while True:
- res = req.session.model('im.message').get_messages(last, users_watch, uuid=uuid, context=req.context)
+ with request.registry.cursor() as cr:
+ res = request.registry.get('im.message').get_messages(cr, request.uid, last, users_watch, uuid=uuid, context=request.context)
if num >= 1 or len(res["res"]) > 0:
return res
last = res["last"]
num += 1
ImWatcher.get_watcher(res["dbname"]).stop(my_id, users_watch or [], POLL_TIMER)
- @openerp.addons.web.http.jsonrequest
- def activated(self, req):
+ @http.route('/longpolling/im/activated', type="json", auth="none")
+ def activated(self):
return not not openerp.evented
- @openerp.addons.web.http.jsonrequest
- def gen_uuid(self, req):
+ @http.route('/longpolling/im/gen_uuid', type="json", auth="none")
+ def gen_uuid(self):
import uuid
return "%s" % uuid.uuid1()
diff --git a/addons/im_livechat/im_livechat.py b/addons/im_livechat/im_livechat.py
index 1ffb422fe6a..adceebc7cba 100644
--- a/addons/im_livechat/im_livechat.py
+++ b/addons/im_livechat/im_livechat.py
@@ -26,6 +26,8 @@ import random
import jinja2
from openerp.osv import osv, fields
from openerp import tools
+import openerp.addons.web.http as http
+from openerp.addons.web.http import request
env = jinja2.Environment(
loader=jinja2.PackageLoader('openerp.addons.im_livechat', "."),
@@ -33,48 +35,38 @@ env = jinja2.Environment(
)
env.filters["json"] = json.dumps
-class LiveChatController(openerp.addons.web.http.Controller):
- _cp_path = '/im_livechat'
+class LiveChatController(http.Controller):
- @openerp.addons.web.http.httprequest
- def loader(self, req, **kwargs):
+ @http.route('/im_livechat/loader')
+ def loader(self, **kwargs):
p = json.loads(kwargs["p"])
db = p["db"]
channel = p["channel"]
user_name = p.get("user_name", None)
- req.session._db = db
- req.session._uid = None
- req.session._login = "anonymous"
- req.session._password = "anonymous"
- info = req.session.model('im_livechat.channel').get_info_for_chat_src(channel)
+ request.session.authenticate(db=db, login="anonymous", password="anonymous")
+ info = request.session.model('im_livechat.channel').get_info_for_chat_src(channel)
info["db"] = db
info["channel"] = channel
info["userName"] = user_name
- return req.make_response(env.get_template("loader.js").render(info),
+ return request.make_response(env.get_template("loader.js").render(info),
headers=[('Content-Type', "text/javascript")])
- @openerp.addons.web.http.httprequest
- def web_page(self, req, **kwargs):
+ @http.route('/im_livechat/web_page')
+ def web_page(self, **kwargs):
p = json.loads(kwargs["p"])
db = p["db"]
channel = p["channel"]
- req.session._db = db
- req.session._uid = None
- req.session._login = "anonymous"
- req.session._password = "anonymous"
- script = req.session.model('im_livechat.channel').read(channel, ["script"])["script"]
- info = req.session.model('im_livechat.channel').get_info_for_chat_src(channel)
+ request.session.authenticate(db=db, login="anonymous", password="anonymous")
+ script = request.session.model('im_livechat.channel').read(channel, ["script"])["script"]
+ info = request.session.model('im_livechat.channel').get_info_for_chat_src(channel)
info["script"] = script
- return req.make_response(env.get_template("web_page.html").render(info),
+ return request.make_response(env.get_template("web_page.html").render(info),
headers=[('Content-Type', "text/html")])
- @openerp.addons.web.http.jsonrequest
- def available(self, req, db, channel):
- req.session._db = db
- req.session._uid = None
- req.session._login = "anonymous"
- req.session._password = "anonymous"
- return req.session.model('im_livechat.channel').get_available_user(channel) > 0
+ @http.route('/im_livechat/available', type='json')
+ def available(self, db, channel):
+ request.session.authenticate(db=db, login="anonymous", password="anonymous")
+ return request.session.model('im_livechat.channel').get_available_user(channel) > 0
class im_livechat_channel(osv.osv):
_name = 'im_livechat.channel'
diff --git a/addons/knowledge/i18n/th.po b/addons/knowledge/i18n/th.po
new file mode 100644
index 00000000000..3b5327841d8
--- /dev/null
+++ b/addons/knowledge/i18n/th.po
@@ -0,0 +1,118 @@
+# Thai translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2013-06-21 18:52+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Thai \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-06-22 05:36+0000\n"
+"X-Generator: Launchpad (build 16677)\n"
+
+#. module: knowledge
+#: view:knowledge.config.settings:0
+msgid "Documents"
+msgstr "เอกสาร"
+
+#. module: knowledge
+#: model:ir.model,name:knowledge.model_knowledge_config_settings
+msgid "knowledge.config.settings"
+msgstr ""
+
+#. module: knowledge
+#: help:knowledge.config.settings,module_document_webdav:0
+msgid ""
+"Access your documents in OpenERP through WebDAV.\n"
+" This installs the module document_webdav."
+msgstr ""
+
+#. module: knowledge
+#: help:knowledge.config.settings,module_document_page:0
+msgid "This installs the module document_page."
+msgstr ""
+
+#. module: knowledge
+#: model:ir.ui.menu,name:knowledge.menu_document2
+msgid "Collaborative Content"
+msgstr ""
+
+#. module: knowledge
+#: model:ir.actions.act_window,name:knowledge.action_knowledge_configuration
+#: view:knowledge.config.settings:0
+msgid "Configure Knowledge"
+msgstr ""
+
+#. module: knowledge
+#: view:knowledge.config.settings:0
+msgid "Knowledge and Documents Management"
+msgstr ""
+
+#. module: knowledge
+#: help:knowledge.config.settings,module_document:0
+msgid ""
+"This is a complete document management system, with: user authentication,\n"
+" full document search (but pptx and docx are not supported), "
+"and a document dashboard.\n"
+" This installs the module document."
+msgstr ""
+
+#. module: knowledge
+#: field:knowledge.config.settings,module_document_page:0
+msgid "Create static web pages"
+msgstr ""
+
+#. module: knowledge
+#: field:knowledge.config.settings,module_document_ftp:0
+msgid "Share repositories (FTP)"
+msgstr ""
+
+#. module: knowledge
+#: field:knowledge.config.settings,module_document:0
+msgid "Manage documents"
+msgstr ""
+
+#. module: knowledge
+#: view:knowledge.config.settings:0
+msgid "Cancel"
+msgstr ""
+
+#. module: knowledge
+#: view:knowledge.config.settings:0
+msgid "Apply"
+msgstr "ปรับใช้"
+
+#. module: knowledge
+#: model:ir.ui.menu,name:knowledge.menu_document_configuration
+msgid "Configuration"
+msgstr "ตั้งค่า"
+
+#. module: knowledge
+#: help:knowledge.config.settings,module_document_ftp:0
+msgid ""
+"Access your documents in OpenERP through an FTP interface.\n"
+" This installs the module document_ftp."
+msgstr ""
+
+#. module: knowledge
+#: view:knowledge.config.settings:0
+msgid "or"
+msgstr "หรือ"
+
+#. module: knowledge
+#: field:knowledge.config.settings,module_document_webdav:0
+msgid "Share repositories (WebDAV)"
+msgstr ""
+
+#. module: knowledge
+#: model:ir.ui.menu,name:knowledge.menu_document
+#: model:ir.ui.menu,name:knowledge.menu_knowledge_configuration
+msgid "Knowledge"
+msgstr "ความรู้"
diff --git a/addons/l10n_be_hr_payroll/i18n/zh_CN.po b/addons/l10n_be_hr_payroll/i18n/zh_CN.po
new file mode 100644
index 00000000000..e753e1e1bb2
--- /dev/null
+++ b/addons/l10n_be_hr_payroll/i18n/zh_CN.po
@@ -0,0 +1,148 @@
+# Chinese (Simplified) translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-11-24 02:53+0000\n"
+"PO-Revision-Date: 2013-06-23 05:44+0000\n"
+"Last-Translator: Calvin \n"
+"Language-Team: Chinese (Simplified) \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-06-24 04:43+0000\n"
+"X-Generator: Launchpad (build 16677)\n"
+
+#. module: l10n_be_hr_payroll
+#: help:hr.employee,disabled_spouse_bool:0
+msgid "if recipient spouse is declared disabled by law"
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: help:hr.employee,disabled_children_bool:0
+msgid "if recipient children is/are declared disabled by law"
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: field:hr.contract,misc_onss_deduction:0
+msgid "Miscellaneous exempt ONSS "
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: model:ir.model,name:l10n_be_hr_payroll.model_hr_employee
+msgid "Employee"
+msgstr "员工"
+
+#. module: l10n_be_hr_payroll
+#: field:hr.employee,disabled_spouse_bool:0
+msgid "Disabled Spouse"
+msgstr "残疾人配偶"
+
+#. module: l10n_be_hr_payroll
+#: field:hr.contract,retained_net_amount:0
+msgid "Net retained "
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: field:hr.employee,resident_bool:0
+msgid "Nonresident"
+msgstr "非常住人口"
+
+#. module: l10n_be_hr_payroll
+#: help:hr.employee,resident_bool:0
+msgid "if recipient lives in a foreign country"
+msgstr "如果接受者居住在国外"
+
+#. module: l10n_be_hr_payroll
+#: view:hr.employee:0
+msgid "if spouse has professionnel income or not"
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: field:hr.contract,insurance_employee_deduction:0
+msgid "Insurance Group - by worker "
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: selection:hr.employee,spouse_fiscal_status:0
+msgid "With Income"
+msgstr "有收入"
+
+#. module: l10n_be_hr_payroll
+#: selection:hr.employee,spouse_fiscal_status:0
+msgid "Without Income"
+msgstr "无收入"
+
+#. module: l10n_be_hr_payroll
+#: field:hr.employee,disabled_children_number:0
+msgid "Number of disabled children"
+msgstr "残疾儿童个数"
+
+#. module: l10n_be_hr_payroll
+#: field:hr.contract,additional_net_amount:0
+msgid "Net supplements"
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: field:hr.contract,car_company_amount:0
+msgid "Company car employer"
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: field:hr.contract,misc_advantage_amount:0
+msgid "Benefits of various nature "
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: field:hr.contract,car_employee_deduction:0
+msgid "Company Car Deduction for Worker"
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: field:hr.employee,disabled_children_bool:0
+msgid "Disabled Children"
+msgstr "残疾儿童"
+
+#. module: l10n_be_hr_payroll
+#: model:ir.model,name:l10n_be_hr_payroll.model_hr_contract
+msgid "Contract"
+msgstr "合约"
+
+#. module: l10n_be_hr_payroll
+#: field:hr.contract,meal_voucher_amount:0
+msgid "Check Value Meal "
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: field:hr.contract,travel_reimbursement_amount:0
+msgid "Reimbursement of travel expenses"
+msgstr "差旅花费补贴"
+
+#. module: l10n_be_hr_payroll
+#: constraint:hr.contract:0
+msgid "Error! Contract start-date must be less than contract end-date."
+msgstr "错误!联系人开始日期必须小于结束日期"
+
+#. module: l10n_be_hr_payroll
+#: field:hr.employee,spouse_fiscal_status:0
+msgid "Tax status for spouse"
+msgstr "配偶缴税状态"
+
+#. module: l10n_be_hr_payroll
+#: view:hr.employee:0
+msgid "number of dependent children declared as disabled"
+msgstr ""
+
+#. module: l10n_be_hr_payroll
+#: constraint:hr.employee:0
+msgid "Error! You cannot create recursive hierarchy of Employee(s)."
+msgstr "错误!,你不能创建循环的员工层次"
+
+#. module: l10n_be_hr_payroll
+#: field:hr.contract,meal_voucher_employee_deduction:0
+msgid "Check Value Meal - by worker "
+msgstr ""
diff --git a/addons/l10n_in_hr_payroll/i18n/zh_CN.po b/addons/l10n_in_hr_payroll/i18n/zh_CN.po
new file mode 100644
index 00000000000..8ee2c7f2028
--- /dev/null
+++ b/addons/l10n_in_hr_payroll/i18n/zh_CN.po
@@ -0,0 +1,1013 @@
+# Chinese (Simplified) translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-11-24 02:53+0000\n"
+"PO-Revision-Date: 2013-06-24 10:15+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Chinese (Simplified) \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-06-25 05:14+0000\n"
+"X-Generator: Launchpad (build 16677)\n"
+
+#. module: l10n_in_hr_payroll
+#: report:salary.detail.byyear:0
+msgid "E-mail Address"
+msgstr "E-mail地址"
+
+#. module: l10n_in_hr_payroll
+#: field:payment.advice.report,employee_bank_no:0
+msgid "Employee Bank Account"
+msgstr "员工银行帐号"
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+msgid "Payment Advices which are in draft state"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:salary.detail.byyear:0
+msgid "Title"
+msgstr "职位"
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "Payment Advice from"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.model,name:l10n_in_hr_payroll.model_yearly_salary_detail
+msgid "Hr Salary Employee By Category Report"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payslip.report:0
+msgid "Payslips which are paid"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+#: view:payment.advice.report:0
+#: view:payslip.report:0
+msgid "Group By..."
+msgstr "分组于..."
+
+#. module: l10n_in_hr_payroll
+#: report:salary.detail.byyear:0
+msgid "Allowances with Basic:"
+msgstr "基本补贴:"
+
+#. module: l10n_in_hr_payroll
+#: view:payslip.report:0
+msgid "Payslips which are in done state"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:salary.detail.byyear:0
+msgid "Department"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:salary.detail.byyear:0
+msgid "Deductions:"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "A/C no."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.contract,driver_salay:0
+msgid "Driver Salary"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.actions.act_window,name:l10n_in_hr_payroll.action_yearly_salary_detail
+#: model:ir.actions.report.xml,name:l10n_in_hr_payroll.yearly_salary
+#: model:ir.ui.menu,name:l10n_in_hr_payroll.menu_yearly_salary_detail
+msgid "Yearly Salary by Employee"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.actions.act_window,name:l10n_in_hr_payroll.act_hr_emp_payslip_list
+msgid "Payslips"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "March"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+#: field:hr.payroll.advice,company_id:0
+#: field:hr.payroll.advice.line,company_id:0
+#: view:payment.advice.report:0
+#: field:payment.advice.report,company_id:0
+#: view:payslip.report:0
+#: field:payslip.report,company_id:0
+msgid "Company"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "The Manager"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+msgid "Letter Details"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+msgid "Set to Draft"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "to"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "Total :"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payslip.run,available_advice:0
+msgid "Made Payment Advice?"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+msgid "Advices which are paid using NEFT transfer"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:payslip.report,nbr:0
+msgid "# Payslip lines"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: help:hr.contract,tds:0
+msgid "Amount for Tax Deduction at Source"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.model,name:l10n_in_hr_payroll.model_hr_payslip
+msgid "Pay Slip"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+#: field:payment.advice.report,day:0
+#: view:payslip.report:0
+#: field:payslip.report,day:0
+msgid "Day"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+msgid "Month of Payment Advices"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: constraint:hr.payslip:0
+msgid "Payslip 'Date From' must be before 'Date To'."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice,batch_id:0
+msgid "Batch"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+msgid "Code"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+msgid "Other Information"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:hr.payroll.advice,state:0
+#: selection:payment.advice.report,state:0
+msgid "Cancelled"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.actions.act_window,help:l10n_in_hr_payroll.action_payslip_report_all
+msgid "This report performs analysis on Payslip"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "For"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+msgid "Details by Salary Rule Category:"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice,number:0
+#: report:paylip.details.in:0
+msgid "Reference"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.contract,medical_insurance:0
+msgid "Medical Insurance"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+msgid "Identification No"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payslip.report:0
+#: field:payslip.report,struct_id:0
+msgid "Structure"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "form period"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:hr.payroll.advice,state:0
+#: selection:payment.advice.report,state:0
+msgid "Confirmed"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:salary.detail.byyear:0
+#: report:salary.employee.bymonth:0
+msgid "From"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice.line,bysal:0
+#: field:payment.advice.report,bysal:0
+#: report:payroll.advice:0
+msgid "By Salary"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+#: view:payment.advice.report:0
+msgid "Confirm"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice,chaque_nos:0
+#: field:payment.advice.report,cheque_nos:0
+msgid "Cheque Numbers"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: constraint:res.company:0
+msgid "Error! You can not create recursive companies."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.actions.act_window,name:l10n_in_hr_payroll.action_salary_employee_month
+#: model:ir.actions.report.xml,name:l10n_in_hr_payroll.hr_salary_employee_bymonth
+#: model:ir.ui.menu,name:l10n_in_hr_payroll.menu_salary_employee_month
+msgid "Yearly Salary by Head"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:134
+#, python-format
+msgid "You can not confirm Payment advice without advice lines."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "Yours Sincerely"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payslip.report:0
+msgid "# Payslip Lines"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: help:hr.contract,medical_insurance:0
+msgid "Deduction towards company provided medical insurance"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.model,name:l10n_in_hr_payroll.model_hr_payroll_advice_line
+msgid "Bank Advice Lines"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payslip.report:0
+msgid "Day of Payslip"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+msgid "Email"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: help:hr.payslip.run,available_advice:0
+msgid ""
+"If this box is checked which means that Payment Advice exists for current "
+"batch"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:108
+#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:134
+#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:190
+#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:207
+#, python-format
+msgid "Error !"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:payslip.report,paid:0
+msgid "Made Payment Order ? "
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.salary.employee.month:0
+#: view:yearly.salary.detail:0
+msgid "Print"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payslip.report,state:0
+msgid "Rejected"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payslip.report:0
+msgid "Year of Payslip"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.model,name:l10n_in_hr_payroll.model_hr_payslip_run
+msgid "Payslip Batches"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice.line,debit_credit:0
+#: report:payroll.advice:0
+msgid "C/D"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:salary.employee.bymonth:0
+msgid "Yearly Salary Details"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.actions.report.xml,name:l10n_in_hr_payroll.payroll_advice
+msgid "Print Advice"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice,line_ids:0
+msgid "Employee Salary"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "July"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:res.company:0
+msgid "Configuration"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payslip.report:0
+msgid "Payslip Line"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.actions.act_window,name:l10n_in_hr_payroll.action_view_hr_bank_advice_tree
+#: model:ir.ui.menu,name:l10n_in_hr_payroll.hr_menu_payment_advice
+msgid "Payment Advices"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.actions.act_window,name:l10n_in_hr_payroll.action_payment_advice_report_all
+#: model:ir.ui.menu,name:l10n_in_hr_payroll.menu_reporting_payment_advice
+#: view:payment.advice.report:0
+msgid "Advices Analysis"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.salary.employee.month:0
+msgid ""
+"This wizard will print report which displays employees break-up of Net Head "
+"for a specified dates."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice.line,ifsc:0
+msgid "IFSC"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+#: field:payslip.report,date_to:0
+msgid "Date To"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.contract,tds:0
+msgid "TDS"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+msgid "Confirm Advices"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: constraint:hr.contract:0
+msgid "Error! Contract start-date must be less than contract end-date."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:res.company,dearness_allowance:0
+msgid "Dearness Allowance"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "August"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.contract:0
+msgid "Deduction"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "SI. No."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+msgid "Payment Advices which are in confirm state"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "December"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+msgid "Confirm Sheet"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+#: field:payment.advice.report,month:0
+#: view:payslip.report:0
+#: field:payslip.report,month:0
+msgid "Month"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:salary.detail.byyear:0
+msgid "Employee Code"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.salary.employee.month:0
+#: view:yearly.salary.detail:0
+msgid "or"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.model,name:l10n_in_hr_payroll.model_hr_salary_employee_month
+msgid "Hr Salary Employee By Month Report"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.salary.employee.month,category_id:0
+#: view:payslip.report:0
+#: field:payslip.report,category_id:0
+msgid "Category"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:190
+#, python-format
+msgid ""
+"Payment advice already exists for %s, 'Set to Draft' to create a new advice."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payslip.run:0
+msgid "To Advice"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+msgid "Note"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+msgid "Salary Rule Category"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+#: selection:hr.payroll.advice,state:0
+#: view:payment.advice.report:0
+#: selection:payment.advice.report,state:0
+#: view:payslip.report:0
+#: selection:payslip.report,state:0
+msgid "Draft"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+#: field:payslip.report,date_from:0
+msgid "Date From"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:salary.detail.byyear:0
+msgid "Employee Name"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.model,name:l10n_in_hr_payroll.model_payment_advice_report
+msgid "Payment Advice Analysis"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+#: field:hr.payroll.advice,state:0
+#: view:payment.advice.report:0
+#: field:payment.advice.report,state:0
+#: view:payslip.report:0
+#: field:payslip.report,state:0
+msgid "Status"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: help:res.company,dearness_allowance:0
+msgid "Check this box if your company provide Dearness Allowance to employee"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice.line,ifsc_code:0
+#: field:payment.advice.report,ifsc_code:0
+#: report:payroll.advice:0
+msgid "IFSC Code"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "June"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payslip.report:0
+msgid "Paid"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: help:hr.contract,voluntary_provident_fund:0
+msgid ""
+"VPF is a safe option wherein you can contribute more than the PF ceiling of "
+"12% that has been mandated by the government and VPF computed as "
+"percentage(%)"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+#: field:payment.advice.report,nbr:0
+msgid "# Payment Lines"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.actions.report.xml,name:l10n_in_hr_payroll.payslip_details_report
+msgid "PaySlip Details"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+msgid "Payment Lines"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice,date:0
+#: field:payment.advice.report,date:0
+msgid "Date"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "November"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+#: view:payslip.report:0
+msgid "Extended Filters..."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.actions.act_window,help:l10n_in_hr_payroll.action_payment_advice_report_all
+msgid "This report performs analysis on Payment Advices"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "October"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+#: report:salary.detail.byyear:0
+msgid "Designation"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payslip.report:0
+msgid "Month of Payslip"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "January"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:yearly.salary.detail:0
+msgid "Pay Head Employee Breakup"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.model,name:l10n_in_hr_payroll.model_res_company
+msgid "Companies"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+#: report:payroll.advice:0
+msgid "Authorized Signature"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.model,name:l10n_in_hr_payroll.model_hr_contract
+msgid "Contract"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.contract,supplementary_allowance:0
+msgid "Supplementary Allowance"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice.line:0
+msgid "Advice Lines"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "To,"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: help:hr.contract,driver_salay:0
+msgid "Check this box if you provide allowance for driver"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payslip.report:0
+msgid "Payslips which are in draft state"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+#: field:hr.payroll.advice.line,advice_id:0
+#: field:hr.payslip,advice_id:0
+#: model:ir.model,name:l10n_in_hr_payroll.model_hr_payroll_advice
+msgid "Bank Advice"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:salary.detail.byyear:0
+msgid "Other No."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+msgid "Draft Advices"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: help:hr.payroll.advice,neft:0
+msgid "Check this box if your company use online transfer for salary"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:payment.advice.report,number:0
+#: field:payslip.report,number:0
+msgid "Number"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "September"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payslip.report:0
+#: selection:payslip.report,state:0
+msgid "Done"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+#: view:hr.salary.employee.month:0
+#: view:yearly.salary.detail:0
+msgid "Cancel"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+msgid "Day of Payment Advices"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+msgid "Search Payment advice"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:yearly.salary.detail:0
+msgid ""
+"This wizard will print report which display a pay head employee breakup for "
+"a specified dates."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+msgid "Pay Slip Details"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+msgid "Total Salary"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice.line,employee_id:0
+#: view:payment.advice.report:0
+#: field:payment.advice.report,employee_id:0
+#: view:payslip.report:0
+#: field:payslip.report,employee_id:0
+msgid "Employee"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+msgid "Compute Advice"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "Dear Sir/Madam,"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice,note:0
+msgid "Description"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "May"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:res.company:0
+msgid "Payroll"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+msgid "NEFT"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+#: report:salary.detail.byyear:0
+msgid "Address"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+#: field:hr.payroll.advice,bank_id:0
+#: view:payment.advice.report:0
+#: field:payment.advice.report,bank_id:0
+#: report:payroll.advice:0
+#: report:salary.detail.byyear:0
+msgid "Bank"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.salary.employee.month,end_date:0
+#: field:yearly.salary.detail,date_to:0
+msgid "End Date"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "February"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: sql_constraint:res.company:0
+msgid "The company name must be unique !"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payroll.advice:0
+#: field:hr.payroll.advice,name:0
+#: report:paylip.details.in:0
+#: field:payment.advice.report,name:0
+#: field:payslip.report,name:0
+#: report:salary.employee.bymonth:0
+msgid "Name"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.salary.employee.month:0
+#: field:hr.salary.employee.month,employee_ids:0
+#: view:yearly.salary.detail:0
+#: field:yearly.salary.detail,employee_ids:0
+msgid "Employees"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+msgid "Bank Account"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: model:ir.actions.act_window,name:l10n_in_hr_payroll.action_payslip_report_all
+#: model:ir.model,name:l10n_in_hr_payroll.model_payslip_report
+#: model:ir.ui.menu,name:l10n_in_hr_payroll.menu_reporting_payslip
+#: view:payslip.report:0
+msgid "Payslip Analysis"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: selection:payment.advice.report,month:0
+#: selection:payslip.report,month:0
+msgid "April"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:payroll.advice:0
+msgid "Name of the Employe"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:108
+#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:207
+#, python-format
+msgid "Please define bank account for the %s employee"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.salary.employee.month,start_date:0
+#: field:yearly.salary.detail,date_from:0
+msgid "Start Date"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.contract:0
+msgid "Allowance"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.contract,voluntary_provident_fund:0
+msgid "Voluntary Provident Fund (%)"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.contract,house_rent_allowance_metro_nonmetro:0
+msgid "House Rent Allowance (%)"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: help:hr.payroll.advice,bank_id:0
+msgid "Select the Bank from which the salary is going to be paid"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.salary.employee.month:0
+msgid "Employee Pay Head Breakup"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:salary.detail.byyear:0
+msgid "Phone No."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+msgid "Credit"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice.line,name:0
+#: report:payroll.advice:0
+msgid "Bank Account No."
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: help:hr.payroll.advice,date:0
+msgid "Advice Date is used to search Payslips"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payslip.run:0
+msgid "Payslip Batches ready to be Adviced"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:hr.payslip.run:0
+msgid "Create Advice"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+#: field:payment.advice.report,year:0
+#: view:payslip.report:0
+#: field:payslip.report,year:0
+msgid "Year"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: field:hr.payroll.advice,neft:0
+#: field:payment.advice.report,neft:0
+msgid "NEFT Transaction"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: report:paylip.details.in:0
+#: field:payslip.report,total:0
+#: report:salary.detail.byyear:0
+#: report:salary.employee.bymonth:0
+msgid "Total"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: help:hr.contract,house_rent_allowance_metro_nonmetro:0
+msgid ""
+"HRA is an allowance given by the employer to the employee for taking care of "
+"his rental or accommodation expenses for metro city it is 50 % and for non "
+"metro 40%.HRA computed as percentage(%)"
+msgstr ""
+
+#. module: l10n_in_hr_payroll
+#: view:payment.advice.report:0
+msgid "Year of Payment Advices"
+msgstr ""
diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py
index 870695e074e..97d2842d15c 100644
--- a/addons/mail/mail_alias.py
+++ b/addons/mail/mail_alias.py
@@ -39,6 +39,7 @@ def remove_accents(input_str):
nkfd_form = unicodedata.normalize('NFKD', input_str)
return u''.join([c for c in nkfd_form if not unicodedata.combining(c)])
+
class mail_alias(osv.Model):
"""A Mail Alias is a mapping of an email address with a given OpenERP Document
model. It is used by OpenERP's mail gateway when processing incoming emails
@@ -47,7 +48,7 @@ class mail_alias(osv.Model):
of that alias. If the message is a reply it will be attached to the
existing discussion on the corresponding record, otherwise a new
record of the corresponding model will be created.
-
+
This is meant to be used in combination with a catch-all email configuration
on the company's mail server, so that as soon as a new mail.alias is
created, it becomes immediately usable and OpenERP will accept email for it.
@@ -63,9 +64,8 @@ class mail_alias(osv.Model):
return dict.fromkeys(ids, domain or "")
_columns = {
- 'alias_name': fields.char('Alias', required=True,
- help="The name of the email alias, e.g. 'jobs' "
- "if you want to catch emails for ",),
+ 'alias_name': fields.char('Alias',
+ help="The name of the email alias, e.g. 'jobs' if you want to catch emails for ",),
'alias_model_id': fields.many2one('ir.model', 'Aliased Model', required=True, ondelete="cascade",
help="The model (OpenERP Document Kind) to which this alias "
"corresponds. Any incoming email that does not reply to an "
@@ -87,13 +87,29 @@ class mail_alias(osv.Model):
"messages will be attached, even if they did not reply to it. "
"If set, this will disable the creation of new records completely."),
'alias_domain': fields.function(_get_alias_domain, string="Alias domain", type='char', size=None),
+ 'alias_parent_model_id': fields.many2one('ir.model', 'Parent Model',
+ help="Parent model holding the alias. The model holding the alias reference\n"
+ "is not necessarily the model given by alias_model_id\n"
+ "(example: project (parent_model) and task (model))"),
+ 'alias_parent_thread_id': fields.integer('Parent Record Thread ID',
+ help="ID of the parent record holding the alias (example: project holding the task creation alias)"),
+ 'alias_contact': fields.selection([
+ ('everyone', 'Everyone'),
+ ('partners', 'Authenticated Partners'),
+ ('followers', 'Followers only'),
+ ], string='Alias Contact Security', required=True,
+ help="Policy to post a message on the document using the mailgateway.\n"
+ "- everyone: everyone can post\n"
+ "- partners: only authenticated partners\n"
+ "- followers: only followers of the related document\n"),
}
_defaults = {
'alias_defaults': '{}',
- 'alias_user_id': lambda self,cr,uid,context: uid,
+ 'alias_user_id': lambda self, cr, uid, context: uid,
# looks better when creating new aliases - even if the field is informative only
- 'alias_domain': lambda self,cr,uid,context: self._get_alias_domain(cr, SUPERUSER_ID,[1],None,None)[1]
+ 'alias_domain': lambda self, cr, uid, context: self._get_alias_domain(cr, SUPERUSER_ID, [1], None, None)[1],
+ 'alias_contact': 'everyone',
}
_sql_constraints = [
@@ -139,13 +155,15 @@ class mail_alias(osv.Model):
return new_name
def migrate_to_alias(self, cr, child_model_name, child_table_name, child_model_auto_init_fct,
- alias_id_column, alias_key, alias_prefix='', alias_force_key='', alias_defaults={}, context=None):
+ alias_model_name, alias_id_column, alias_key, alias_prefix='', alias_force_key='', alias_defaults={},
+ alias_generate_name=False, context=None):
""" Installation hook to create aliases for all users and avoid constraint errors.
:param child_model_name: model name of the child class (i.e. res.users)
:param child_table_name: table name of the child class (i.e. res_users)
:param child_model_auto_init_fct: pointer to the _auto_init function
(i.e. super(res_users,self)._auto_init(cr, context=context))
+ :param alias_model_name: name of the aliased model
:param alias_id_column: alias_id column (i.e. self._columns['alias_id'])
:param alias_key: name of the column used for the unique name (i.e. 'login')
:param alias_prefix: prefix for the unique name (i.e. 'jobs' + ...)
@@ -153,6 +171,8 @@ class mail_alias(osv.Model):
if empty string, not taken into account
:param alias_defaults: dict, keys = mail.alias columns, values = child
model column name used for default values (i.e. {'job_id': 'id'})
+ :param alias_generate_name: automatically generate alias name using prefix / alias key;
+ default alias_name value is False because since 8.0 it is not required anymore
"""
if context is None:
context = {}
@@ -170,13 +190,17 @@ class mail_alias(osv.Model):
no_alias_ids = child_class_model.search(cr, SUPERUSER_ID, [('alias_id', '=', False)], context={'active_test': False})
# Use read() not browse(), to avoid prefetching uninitialized inherited fields
for obj_data in child_class_model.read(cr, SUPERUSER_ID, no_alias_ids, [alias_key]):
- alias_vals = {'alias_name': '%s%s' % (alias_prefix, obj_data[alias_key])}
+ alias_vals = {'alias_name': False}
+ if alias_generate_name:
+ alias_vals['alias_name'] = '%s%s' % (alias_prefix, obj_data[alias_key])
if alias_force_key:
alias_vals['alias_force_thread_id'] = obj_data[alias_force_key]
alias_vals['alias_defaults'] = dict((k, obj_data[v]) for k, v in alias_defaults.iteritems())
- alias_id = mail_alias.create_unique_alias(cr, SUPERUSER_ID, alias_vals, model_name=context.get('alias_model_name', child_model_name))
+ alias_vals['alias_parent_thread_id'] = obj_data['id']
+ alias_create_ctx = dict(context, alias_model_name=alias_model_name, alias_parent_model_name=child_model_name)
+ alias_id = mail_alias.create(cr, SUPERUSER_ID, alias_vals, context=alias_create_ctx)
child_class_model.write(cr, SUPERUSER_ID, obj_data['id'], {'alias_id': alias_id})
- _logger.info('Mail alias created for %s %s (uid %s)', child_model_name, obj_data[alias_key], obj_data['id'])
+ _logger.info('Mail alias created for %s %s (id %s)', child_model_name, obj_data[alias_key], obj_data['id'])
# Finally attempt to reinstate the missing constraint
try:
@@ -189,22 +213,53 @@ class mail_alias(osv.Model):
# set back the unique alias_id constraint
alias_id_column.required = True
-
return res
- def create_unique_alias(self, cr, uid, vals, model_name=None, context=None):
- """Creates an email.alias record according to the values provided in ``vals``,
- with 2 alterations: the ``alias_name`` value may be suffixed in order to
- make it unique (and certain unsafe characters replaced), and
- he ``alias_model_id`` value will set to the model ID of the ``model_name``
- value, if provided,
+ def create(self, cr, uid, vals, context=None):
+ """ Creates an email.alias record according to the values provided in ``vals``,
+ with 2 alterations: the ``alias_name`` value may be suffixed in order to
+ make it unique (and certain unsafe characters replaced), and
+ he ``alias_model_id`` value will set to the model ID of the ``model_name``
+ context value, if provided.
"""
- # when an alias name appears to already be an email, we keep the local part only
- alias_name = remove_accents(vals['alias_name']).lower().split('@')[0]
- alias_name = re.sub(r'[^\w+.]+', '-', alias_name)
- alias_name = self._find_unique(cr, uid, alias_name, context=context)
- vals['alias_name'] = alias_name
+ if context is None:
+ context = {}
+ model_name = context.get('alias_model_name')
+ parent_model_name = context.get('alias_parent_model_name')
+ if vals.get('alias_name'):
+ # when an alias name appears to already be an email, we keep the local part only
+ alias_name = remove_accents(vals['alias_name']).lower().split('@')[0]
+ alias_name = re.sub(r'[^\w+.]+', '-', alias_name)
+ alias_name = self._find_unique(cr, uid, alias_name, context=context)
+ vals['alias_name'] = alias_name
if model_name:
model_id = self.pool.get('ir.model').search(cr, uid, [('model', '=', model_name)], context=context)[0]
vals['alias_model_id'] = model_id
- return self.create(cr, uid, vals, context=context)
+ if parent_model_name:
+ model_id = self.pool.get('ir.model').search(cr, uid, [('model', '=', parent_model_name)], context=context)[0]
+ vals['alias_parent_model_id'] = model_id
+ return super(mail_alias, self).create(cr, uid, vals, context=context)
+
+ def open_document(self, cr, uid, ids, context=None):
+ alias = self.browse(cr, uid, ids, context=context)[0]
+ if not alias.alias_model_id or not alias.alias_force_thread_id:
+ return False
+ return {
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': alias.alias_model_id.model,
+ 'res_id': alias.alias_force_thread_id,
+ 'type': 'ir.actions.act_window',
+ }
+
+ def open_parent_document(self, cr, uid, ids, context=None):
+ alias = self.browse(cr, uid, ids, context=context)[0]
+ if not alias.alias_parent_model_id or not alias.alias_parent_thread_id:
+ return False
+ return {
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': alias.alias_parent_model_id.model,
+ 'res_id': alias.alias_parent_thread_id,
+ 'type': 'ir.actions.act_window',
+ }
diff --git a/addons/mail/mail_alias_view.xml b/addons/mail/mail_alias_view.xml
index e0d8e173ebc..248bf7e8f3a 100644
--- a/addons/mail/mail_alias_view.xml
+++ b/addons/mail/mail_alias_view.xml
@@ -9,13 +9,23 @@
@@ -32,6 +42,7 @@
+
@@ -44,8 +55,13 @@
+
+
+
+
+
-
+
@@ -55,6 +71,10 @@
Aliases
mail.alias
+ {
+ 'search_default_active': True,
+ }
+