[MERGE]: Merge with latest trunk-addons

bzr revid: rpa@tinyerp.com-20120712062623-cvhg4a2ewwqp9hcv
This commit is contained in:
Rucha (Open ERP) 2012-07-12 11:56:23 +05:30
commit 9dc752d788
27 changed files with 1179 additions and 2198 deletions

View File

@ -1862,8 +1862,10 @@ class account_tax(osv.osv):
'applicable_type': fields.selection( [('true','Always'), ('code','Given by Python Code')], 'Applicability', required=True,
help="If not applicable (computed through a Python code), the tax won't appear on the invoice."),
'domain':fields.char('Domain', size=32, help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."),
'account_collected_id':fields.many2one('account.account', 'Invoice Tax Account'),
'account_paid_id':fields.many2one('account.account', 'Refund Tax Account'),
'account_collected_id':fields.many2one('account.account', 'Invoice Tax Account', help="Set the account that will be set by default on invoice tax lines for invoices. Leave empty to use the expense account."),
'account_paid_id':fields.many2one('account.account', 'Refund Tax Account', help="Set the account that will be set by default on invoice tax lines for refunds. Leave empty to use the expense account."),
'account_analytic_collected_id':fields.many2one('account.analytic.account', 'Invoice Tax Analytic Account', help="Set the analytic account that will be used by default on the invoice tax lines for invoices. Leave empty if you don't want to use an analytic account on the invoice tax lines by default."),
'account_analytic_paid_id':fields.many2one('account.analytic.account', 'Refund Tax Analytic Account', help="Set the analytic account that will be used by default on the invoice tax lines for refunds. Leave empty if you don't want to use an analytic account on the invoice tax lines by default."),
'parent_id':fields.many2one('account.tax', 'Parent Tax Account', select=True),
'child_ids':fields.one2many('account.tax', 'parent_id', 'Child Tax Accounts'),
'child_depend':fields.boolean('Tax on Children', help="Set if the tax computation is based on the computation of child taxes rather than on the total amount."),
@ -2001,6 +2003,8 @@ class account_tax(osv.osv):
'name':tax.description and tax.description + " - " + tax.name or tax.name,
'account_collected_id':tax.account_collected_id.id,
'account_paid_id':tax.account_paid_id.id,
'account_analytic_collected_id': tax.account_analytic_collected_id.id,
'account_analytic_paid_id': tax.account_analytic_paid_id.id,
'base_code_id': tax.base_code_id.id,
'ref_base_code_id': tax.ref_base_code_id.id,
'sequence': tax.sequence,
@ -2066,7 +2070,20 @@ class account_tax(osv.osv):
'taxes': [] # List of taxes, see compute for the format
}
"""
# By default, for each tax, tax amount will first be computed
# and rounded at the 'Account' decimal precision for each
# PO/SO/invoice line and then these rounded amounts will be
# summed, leading to the total amount for that tax. But, if the
# company has tax_calculation_rounding_method = round_globally,
# we still follow the same method, but we use a much larger
# precision when we round the tax amount for each line (we use
# the 'Account' decimal precision + 5), and that way it's like
# rounding after the sum of the tax amounts of each line
precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
tax_compute_precision = precision
if taxes and taxes[0].company_id.tax_calculation_rounding_method == 'round_globally':
tax_compute_precision += 5
totalin = totalex = round(price_unit * quantity, precision)
tin = []
tex = []
@ -2075,7 +2092,7 @@ class account_tax(osv.osv):
tex.append(tax)
else:
tin.append(tax)
tin = self.compute_inv(cr, uid, tin, price_unit, quantity, product=product, partner=partner)
tin = self.compute_inv(cr, uid, tin, price_unit, quantity, product=product, partner=partner, precision=tax_compute_precision)
for r in tin:
totalex -= r.get('amount', 0.0)
totlex_qty = 0.0
@ -2083,7 +2100,7 @@ class account_tax(osv.osv):
totlex_qty = totalex/quantity
except:
pass
tex = self._compute(cr, uid, tex, totlex_qty, quantity,product=product, partner=partner)
tex = self._compute(cr, uid, tex, totlex_qty, quantity, product=product, partner=partner, precision=tax_compute_precision)
for r in tex:
totalin += r.get('amount', 0.0)
return {
@ -2096,7 +2113,7 @@ class account_tax(osv.osv):
_logger.warning("Deprecated, use compute_all(...)['taxes'] instead of compute(...) to manage prices with tax included")
return self._compute(cr, uid, taxes, price_unit, quantity, product, partner)
def _compute(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None):
def _compute(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None, precision=None):
"""
Compute tax values for given PRICE_UNIT, QUANTITY and a buyer/seller ADDRESS_ID.
@ -2105,14 +2122,15 @@ class account_tax(osv.osv):
tax = {'name':'', 'amount':0.0, 'account_collected_id':1, 'account_paid_id':2}
one tax for each tax id in IDS and their children
"""
if not precision:
precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
res = self._unit_compute(cr, uid, taxes, price_unit, product, partner, quantity)
total = 0.0
precision_pool = self.pool.get('decimal.precision')
for r in res:
if r.get('balance',False):
r['amount'] = round(r.get('balance', 0.0) * quantity, precision_pool.precision_get(cr, uid, 'Account')) - total
r['amount'] = round(r.get('balance', 0.0) * quantity, precision) - total
else:
r['amount'] = round(r.get('amount', 0.0) * quantity, precision_pool.precision_get(cr, uid, 'Account'))
r['amount'] = round(r.get('amount', 0.0) * quantity, precision)
total += r['amount']
return res
@ -2160,6 +2178,8 @@ class account_tax(osv.osv):
'amount': amount,
'account_collected_id': tax.account_collected_id.id,
'account_paid_id': tax.account_paid_id.id,
'account_analytic_collected_id': tax.account_analytic_collected_id.id,
'account_analytic_paid_id': tax.account_analytic_paid_id.id,
'base_code_id': tax.base_code_id.id,
'ref_base_code_id': tax.ref_base_code_id.id,
'sequence': tax.sequence,
@ -2188,7 +2208,7 @@ class account_tax(osv.osv):
r['todo'] = 0
return res
def compute_inv(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None):
def compute_inv(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None, precision=None):
"""
Compute tax values for given PRICE_UNIT, QUANTITY and a buyer/seller ADDRESS_ID.
Price Unit is a VAT included price
@ -2198,15 +2218,15 @@ class account_tax(osv.osv):
tax = {'name':'', 'amount':0.0, 'account_collected_id':1, 'account_paid_id':2}
one tax for each tax id in IDS and their children
"""
if not precision:
precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
res = self._unit_compute_inv(cr, uid, taxes, price_unit, product, partner=None)
total = 0.0
obj_precision = self.pool.get('decimal.precision')
for r in res:
prec = obj_precision.precision_get(cr, uid, 'Account')
if r.get('balance',False):
r['amount'] = round(r['balance'] * quantity, prec) - total
r['amount'] = round(r['balance'] * quantity, precision) - total
else:
r['amount'] = round(r['amount'] * quantity, prec)
r['amount'] = round(r['amount'] * quantity, precision)
total += r['amount']
return res

View File

@ -43,6 +43,12 @@ class bank(osv.osv):
"Return the name to use when creating a bank journal"
return (bank.bank_name or '') + ' ' + bank.acc_number
def _prepare_name_get(self, cr, uid, bank_type_obj, bank_obj, context=None):
"""Add ability to have %(currency_name)s in the format_layout of
res.partner.bank.type"""
bank_obj._data[bank_obj.id]['currency_name'] = bank_obj.currency_id and bank_obj.currency_id.name or ''
return super(bank, self)._prepare_name_get(cr, uid, bank_type_obj, bank_obj, context=context)
def post_write(self, cr, uid, ids, context={}):
if isinstance(ids, (int, long)):
ids = [ids]

View File

@ -756,7 +756,7 @@ class account_invoice(osv.osv):
for tax in inv.tax_line:
if tax.manual:
continue
key = (tax.tax_code_id.id, tax.base_code_id.id, tax.account_id.id)
key = (tax.tax_code_id.id, tax.base_code_id.id, tax.account_id.id, tax.account_analytic_id.id)
tax_key.append(key)
if not key in compute_taxes:
raise osv.except_osv(_('Warning !'), _('Global taxes defined, but they are not in invoice lines !'))
@ -1002,7 +1002,7 @@ class account_invoice(osv.osv):
'quantity': x.get('quantity',1.00),
'product_id': x.get('product_id', False),
'product_uom_id': x.get('uos_id', False),
'analytic_account_id': x.get('account_analytic_id', False),
'analytic_account_id': x.get('analytic_account_id', False),
}
def action_number(self, cr, uid, ids, context=None):
@ -1578,6 +1578,7 @@ class account_invoice_tax(osv.osv):
'invoice_id': fields.many2one('account.invoice', 'Invoice Line', ondelete='cascade', select=True),
'name': fields.char('Tax Description', size=64, required=True),
'account_id': fields.many2one('account.account', 'Tax Account', required=True, domain=[('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]),
'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'),
'base': fields.float('Base', digits_compute=dp.get_precision('Account')),
'amount': fields.float('Amount', digits_compute=dp.get_precision('Account')),
'manual': fields.boolean('Manual'),
@ -1648,14 +1649,16 @@ class account_invoice_tax(osv.osv):
val['base_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['base'] * tax['base_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False)
val['tax_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['amount'] * tax['tax_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False)
val['account_id'] = tax['account_collected_id'] or line.account_id.id
val['account_analytic_id'] = tax['account_analytic_collected_id']
else:
val['base_code_id'] = tax['ref_base_code_id']
val['tax_code_id'] = tax['ref_tax_code_id']
val['base_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['base'] * tax['ref_base_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False)
val['tax_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['amount'] * tax['ref_tax_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False)
val['account_id'] = tax['account_paid_id'] or line.account_id.id
val['account_analytic_id'] = tax['account_analytic_paid_id']
key = (val['tax_code_id'], val['base_code_id'], val['account_id'])
key = (val['tax_code_id'], val['base_code_id'], val['account_id'], val['account_analytic_id'])
if not key in tax_grouped:
tax_grouped[key] = val
else:
@ -1687,7 +1690,8 @@ class account_invoice_tax(osv.osv):
'price': t['amount'] or 0.0,
'account_id': t['account_id'],
'tax_code_id': t['tax_code_id'],
'tax_amount': t['tax_amount']
'tax_amount': t['tax_amount'],
'analytic_account_id': t['account_analytic_id'],
})
return res

View File

@ -98,6 +98,7 @@
<field name="name"/>
<field name="sequence"/>
<field name="account_id" groups="account.group_account_user"/>
<field name="account_analytic_id" domain="[('type','&lt;&gt;','view'), ('company_id', '=', parent.company_id), ('parent_id', '!=', False)]" groups="analytic.group_analytic_accounting"/>
<field name="manual"/>
<field name="amount"/>
<field name="base" readonly="0"/>
@ -215,6 +216,7 @@
<tree editable="bottom" string="Taxes">
<field name="name"/>
<field name="account_id" groups="account.group_account_invoice"/>
<field name="account_analytic_id" domain="[('type','&lt;&gt;','view'), ('company_id', '=', parent.company_id), ('parent_id', '!=', False)]" groups="analytic.group_analytic_accounting"/>
<field name="base" on_change="base_change(base,parent.currency_id,parent.company_id,parent.date_invoice)" readonly="1"/>
<field name="amount" on_change="amount_change(amount,parent.currency_id,parent.company_id,parent.date_invoice)"/>

View File

@ -909,9 +909,9 @@
<field name="amount" attrs="{'readonly':[('type','in',('none', 'code', 'balance'))]}"/>
<separator colspan="4" string="Accounting Information"/>
<field name="account_collected_id" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]"/>
<label colspan="2" nolabel="1" string="Keep empty to use the income account"/>
<field name="account_analytic_collected_id" domain="[('type','&lt;&gt;','view'), ('company_id', '=', company_id), ('parent_id', '&lt;&gt;', False)]" groups="analytic.group_analytic_accounting"/>
<field name="account_paid_id" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]"/>
<label colspan="2" nolabel="1" string="Keep empty to use the expense account"/>
<field name="account_analytic_paid_id" domain="[('type','&lt;&gt;','view'), ('company_id', '=', company_id), ('parent_id', '&lt;&gt;', False)]" groups="analytic.group_analytic_accounting"/>
<separator colspan="4" string="Tax Declaration: Invoices"/>
<field name="base_code_id"/>
<field name="base_sign"/>

View File

@ -25,6 +25,11 @@ class res_company(osv.osv):
_inherit = "res.company"
_columns = {
'expects_chart_of_accounts': fields.boolean('Expects a Chart of Accounts'),
'tax_calculation_rounding_method': fields.selection([
('round_per_line', 'Round per Line'),
('round_globally', 'Round Globally'),
], 'Tax Calculation Rounding Method',
help="If you select 'Round per Line' : for each tax, the tax amount will first be computed and rounded for each PO/SO/invoice line and then these rounded amounts will be summed, leading to the total amount for that tax. If you select 'Round Globally': for each tax, the tax amount will be computed for each PO/SO/invoice line, then these amounts will be summed and eventually this total tax amount will be rounded. If you sell with tax included, you should choose 'Round per line' because you certainly want the sum of your tax-included line subtotals to be equal to the total amount with taxes."),
'paypal_account': fields.char("Paypal Account", size=128, help="Paypal username (usually email) for receiving online payments."),
'overdue_msg': fields.text('Overdue Payments Message', translate=True),
'property_reserve_and_surplus_account': fields.property(
@ -39,6 +44,7 @@ class res_company(osv.osv):
_defaults = {
'expects_chart_of_accounts': True,
'tax_calculation_rounding_method': 'round_per_line',
'overdue_msg': '''Dear Sir, dear Madam,
Our records indicate that some payments on your account are still due. Please find details below.

View File

@ -24,6 +24,7 @@
<field name="arch" type="xml">
<field name="currency_id" position="after">
<field name="property_reserve_and_surplus_account" colspan="2"/>
<field name="tax_calculation_rounding_method"/>
<field name="paypal_account" placeholder="sales@openerp.com"/>
</field>
</field>

View File

@ -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-02-08 00:35+0000\n"
"PO-Revision-Date: 2012-06-20 16:17+0000\n"
"Last-Translator: Jeff Wang <wjfonhand@hotmail.com>\n"
"PO-Revision-Date: 2012-07-11 03:05+0000\n"
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\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: 2012-06-22 04:44+0000\n"
"X-Generator: Launchpad (build 15461)\n"
"X-Launchpad-Export-Date: 2012-07-12 04:41+0000\n"
"X-Generator: Launchpad (build 15593)\n"
#. module: account
#: view:account.invoice.report:0
@ -4963,7 +4963,7 @@ msgstr "资产负债表"
#: view:account.general.journal:0
#: model:ir.ui.menu,name:account.menu_account_general_journal
msgid "General Journals"
msgstr "一般账簿"
msgstr "总账账簿"
#. module: account
#: field:account.journal,allow_date:0
@ -5702,7 +5702,7 @@ msgstr "发票税科目"
#: model:ir.actions.act_window,name:account.action_account_general_journal
#: model:ir.model,name:account.model_account_general_journal
msgid "Account General Journal"
msgstr "一般账簿"
msgstr "科目总账账簿"
#. module: account
#: field:account.payment.term.line,days:0
@ -10184,7 +10184,7 @@ msgstr "周期次数"
#: report:account.general.journal:0
#: model:ir.actions.report.xml,name:account.account_general_journal
msgid "General Journal"
msgstr "一般账簿"
msgstr "总账账簿"
#. module: account
#: view:account.invoice:0

View File

@ -49,6 +49,12 @@ class account_config_settings(osv.osv_memory):
'has_chart_of_accounts': fields.boolean('Company has a chart of accounts'),
'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', domain="[('visible','=', True)]"),
'code_digits': fields.integer('# of Digits', help="No. of Digits to use for account code"),
'tax_calculation_rounding_method': fields.related('company_id',
'tax_calculation_rounding_method', type='selection', selection=[
('round_per_line', 'Round per Line'),
('round_globally', 'Round Globally'),
], string='Tax Calculation Rounding Method',
help="If you select 'Round per Line' : for each tax, the tax amount will first be computed and rounded for each PO/SO/invoice line and then these rounded amounts will be summed, leading to the total amount for that tax. If you select 'Round Globally': for each tax, the tax amount will be computed for each PO/SO/invoice line, then these amounts will be summed and eventually this total tax amount will be rounded. If you sell with tax included, you should choose 'Round per line' because you certainly want the sum of your tax-included line subtotals to be equal to the total amount with taxes."),
'sale_tax': fields.many2one("account.tax.template", "Default Sale Tax"),
'purchase_tax': fields.many2one("account.tax.template", "Default Purchase Tax"),
'sale_tax_rate': fields.float('Sales Tax (%)'),
@ -152,6 +158,7 @@ class account_config_settings(osv.osv_memory):
'has_chart_of_accounts': has_chart_of_accounts,
'has_fiscal_year': bool(fiscalyear_count),
'chart_template_id': False,
'tax_calculation_rounding_method': company.tax_calculation_rounding_method,
}
# update journals and sequences
for journal_type in ('sale', 'sale_refund', 'purchase', 'purchase_refund'):

View File

@ -76,6 +76,7 @@
<group>
<field name="default_purchase_tax" domain="[('type_tax_use','=','purchase'), ('company_id','=',company_id)]"
attrs="{'invisible': [('has_chart_of_accounts','=',False)]}"/>
<field name="tax_calculation_rounding_method"/>
<field name="module_account_asset"/>
<field name="module_account_budget"/>
</group>

View File

@ -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: 2012-07-10 05:34+0000\n"
"X-Generator: Launchpad (build 15558)\n"
"X-Launchpad-Export-Date: 2012-07-11 05:15+0000\n"
"X-Generator: Launchpad (build 15593)\n"
#. module: account_asset
#: view:account.asset.asset:0

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2012-06-25 05:03+0000\n"
"Last-Translator: Tomomi Mengelberg <tomomi.mengelberg@aquasys.co.jp>\n"
"PO-Revision-Date: 2012-07-12 01:34+0000\n"
"Last-Translator: Akira Hiyama <Unknown>\n"
"Language-Team: Japanese <ja@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-06-26 05:22+0000\n"
"X-Generator: Launchpad (build 15482)\n"
"X-Launchpad-Export-Date: 2012-07-12 04:40+0000\n"
"X-Generator: Launchpad (build 15593)\n"
#. module: base_setup
#: field:user.preferences.config,menu_tips:0
@ -200,17 +200,17 @@ msgstr "どのように顧客を呼びますか"
#. module: base_setup
#: field:migrade.application.installer.modules,quickbooks_ippids:0
msgid "Quickbooks Ippids"
msgstr "Quickbooks lppids"
msgstr "QuickBooksのIPP / IDS"
#. module: base_setup
#: selection:base.setup.terminology,partner:0
msgid "Client"
msgstr "取引先"
msgstr "顧客"
#. module: base_setup
#: field:migrade.application.installer.modules,import_saleforce:0
msgid "Import Saleforce"
msgstr "Saleforceを取り込む"
msgstr "Salesforceのインポート"
#. module: base_setup
#: field:user.preferences.config,context_tz:0
@ -249,22 +249,22 @@ msgstr "user.preferences.config"
#. module: base_setup
#: model:ir.actions.act_window,name:base_setup.action_config_access_other_user
msgid "Create Additional Users"
msgstr "追加ユーザを作成します。"
msgstr "追加ユーザの作成"
#. module: base_setup
#: model:ir.actions.act_window,name:base_setup.action_import_create_installer
msgid "Create or Import Customers"
msgstr "顧客を作成または取り込みます。"
msgstr "顧客の作成 / インポート"
#. module: base_setup
#: field:migrade.application.installer.modules,import_sugarcrm:0
msgid "Import Sugarcrm"
msgstr "SugarCRMを取り込みます。"
msgstr "SugarCRMのインポート"
#. module: base_setup
#: help:product.installer,customers:0
msgid "Import or create customers"
msgstr "顧客を取り込みまたは作成します。"
msgstr "顧客の作成 / インポート"
#. module: base_setup
#: selection:user.preferences.config,view:0
@ -279,7 +279,7 @@ msgstr "SugarCRMを取り込むために"
#. module: base_setup
#: selection:base.setup.terminology,partner:0
msgid "Partner"
msgstr "パートナ"
msgstr "パートナ"
#. module: base_setup
#: view:base.setup.terminology:0

View File

@ -309,6 +309,10 @@ class res_users(osv.osv):
return user_id
_columns = {
'employee_ids': fields.one2many('hr.employee', 'user_id', 'Related employees'),
}
res_users()

File diff suppressed because it is too large Load Diff

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
"PO-Revision-Date: 2012-06-08 02:57+0000\n"
"PO-Revision-Date: 2012-07-11 05:37+0000\n"
"Last-Translator: Akira Hiyama <Unknown>\n"
"Language-Team: Japanese <ja@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-06-09 05:39+0000\n"
"X-Generator: Launchpad (build 15376)\n"
"X-Launchpad-Export-Date: 2012-07-12 04:40+0000\n"
"X-Generator: Launchpad (build 15593)\n"
#. module: point_of_sale
#: field:report.transaction.pos,product_nb:0
@ -765,7 +765,7 @@ msgstr "小計の合計"
#. module: point_of_sale
#: field:pos.order,lines:0
msgid "Order Lines"
msgstr "受注行"
msgstr "オーダー行"
#. module: point_of_sale
#: view:report.transaction.pos:0

View File

@ -155,7 +155,6 @@ class product_pricelist(osv.osv):
currency_obj = self.pool.get('res.currency')
product_obj = self.pool.get('product.product')
product_template_obj = self.pool.get('product.template')
product_category_obj = self.pool.get('product.category')
product_uom_obj = self.pool.get('product.uom')
supplierinfo_obj = self.pool.get('product.supplierinfo')
@ -246,7 +245,7 @@ class product_pricelist(osv.osv):
price = 0.0
if sinfo:
qty_in_product_uom = qty
product_default_uom = product_template_obj.read(cr, uid, [tmpl_id], ['uom_id'])[0]['uom_id'][0]
product_default_uom = product_obj.read(cr, uid, [product_id], ['uom_id'])[0]['uom_id'][0]
supplier = supplierinfo_obj.browse(cr, uid, sinfo, context=context)[0]
seller_uom = supplier.product_uom and supplier.product_uom.id or False
if seller_uom and product_default_uom and product_default_uom != seller_uom:

View File

@ -559,8 +559,8 @@ class product_product(osv.osv):
return False
def _check_ean_key(self, cr, uid, ids, context=None):
for product in self.browse(cr, uid, ids, context=context):
res = check_ean(product.ean13)
for product in self.read(cr, uid, ids, ['ean13'], context=context):
res = check_ean(product['ean13'])
return res
_constraints = [(_check_ean_key, 'Error: Invalid ean code', ['ean13'])]

View File

@ -47,7 +47,6 @@ class sale_order_line(osv.osv):
item_obj = self.pool.get('product.pricelist.item')
price_type_obj = self.pool.get('product.price.type')
product_obj = self.pool.get('product.product')
template_obj = self.pool.get('product.template')
field_name = 'list_price'
if res_dict.get('item_id',False) and res_dict['item_id'].get(pricelist,False):
@ -57,9 +56,7 @@ class sale_order_line(osv.osv):
field_name = price_type_obj.browse(cr, uid, item_base).field
product = product_obj.browse(cr, uid, product_id, context)
product_tmpl_id = product.product_tmpl_id.id
product_read = template_obj.read(cr, uid, product_tmpl_id, [field_name], context)
product_read = product_obj.read(cr, uid, product_id, [field_name], context=context)
factor = 1.0
if uom and uom != product.uom_id.id:
@ -110,7 +107,6 @@ class account_invoice_line(osv.osv):
item_obj = self.pool.get('product.pricelist.item')
price_type_obj = self.pool.get('product.price.type')
product_obj = self.pool.get('product.product')
template_obj = self.pool.get('product.template')
field_name = 'list_price'
if res_dict.get('item_id',False) and res_dict['item_id'].get(pricelist,False):
@ -120,9 +116,7 @@ class account_invoice_line(osv.osv):
field_name = price_type_obj.browse(cr, uid, item_base).field
product = product_obj.browse(cr, uid, product_id, context)
product_tmpl_id = product.product_tmpl_id.id
product_read = template_obj.read(cr, uid, product_tmpl_id, [field_name], context)
product_read = product_obj.read(cr, uid, product_id, [field_name], context=context)
factor = 1.0
if uom and uom != product.uom_id.id:

View File

@ -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: 2012-07-10 05:33+0000\n"
"X-Generator: Launchpad (build 15558)\n"
"X-Launchpad-Export-Date: 2012-07-11 05:14+0000\n"
"X-Generator: Launchpad (build 15593)\n"
#. module: project
#: view:report.project.task.user:0

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:37+0000\n"
"PO-Revision-Date: 2012-06-24 16:46+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"PO-Revision-Date: 2012-07-11 03:11+0000\n"
"Last-Translator: gobi <Unknown>\n"
"Language-Team: Mongolian <mn@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-06-25 05:15+0000\n"
"X-Generator: Launchpad (build 15482)\n"
"X-Launchpad-Export-Date: 2012-07-12 04:41+0000\n"
"X-Generator: Launchpad (build 15593)\n"
#. module: project_timesheet
#: model:ir.actions.act_window,help:project_timesheet.action_project_timesheet_bill_task
@ -45,12 +45,12 @@ msgid ""
"Fill in the timesheet tab of the employee form."
msgstr ""
"Холбогдох ажилтанд журнал тодорхойлогдоогүй байна.\n"
"Ажилтны формын цагийн хуваарь хавтасыг бөглө."
"Ажилтны формын цагийн хуудас хавтасыг бөглө."
#. module: project_timesheet
#: model:process.node,name:project_timesheet.process_node_timesheettask0
msgid "Timesheet task"
msgstr "Цагийн хуваарийн даалгавар"
msgstr "Цагийн хуудсын даалгавар"
#. module: project_timesheet
#: view:report.timesheet.task.user:0
@ -90,31 +90,33 @@ msgid ""
"You cannot delete a partner which is assigned to project, we suggest you to "
"uncheck the active box!"
msgstr ""
"Та төсөлд оноогдсон харилцагчийг устгах боломжгүй, тиймээс идэвхтэй "
"тэмдэглэгээг арилгахыг зөвлөе!"
#. module: project_timesheet
#: view:report.timesheet.task.user:0
msgid "Group By..."
msgstr ""
msgstr "Бүлэглэх..."
#. module: project_timesheet
#: model:process.node,note:project_timesheet.process_node_triggerinvoice0
msgid "Trigger invoices from sale order lines"
msgstr ""
msgstr "Борлуулалтын захиалгын мөрөөс нэхэмжлэх үүсгэх"
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "October"
msgstr ""
msgstr "10-р сар"
#. module: project_timesheet
#: view:report.timesheet.task.user:0
msgid "Timesheet/Task hours Report Per Month"
msgstr ""
msgstr "Цагийн хуудас/Даалгавар цагийн тайлан сарын хэмжээнд"
#. module: project_timesheet
#: view:project.project:0
msgid "Billable"
msgstr ""
msgstr "Нэхэмжлэх боломжтой"
#. module: project_timesheet
#: model:ir.actions.act_window,help:project_timesheet.action_account_analytic_overdue
@ -122,225 +124,227 @@ msgid ""
"You will find here the contracts related to your customer projects in order "
"to track the invoicing progress."
msgstr ""
"Энд захиалагчийн төсөлтэй холбогдсон гэрээнүүдийг харах болно. Энэ нь "
"нэхэмжлэх явцыг зөвх хянахад туслана."
#. module: project_timesheet
#: view:account.analytic.line:0
msgid "Analytic account/project"
msgstr ""
msgstr "Шинжилгээний данс/төсөл"
#. module: project_timesheet
#: field:report.timesheet.task.user,task_hrs:0
msgid "Task Hours"
msgstr ""
msgstr "Даалгаврын цагууд"
#. module: project_timesheet
#: view:report.timesheet.task.user:0
#: field:report.timesheet.task.user,year:0
msgid "Year"
msgstr ""
msgstr "Он"
#. module: project_timesheet
#: constraint:project.project:0
msgid "Error! project start-date must be lower then project end-date."
msgstr ""
msgstr "Алдаа! төслийн эхлэх огноо дуусах огноогоос бага байх ёстой."
#. module: project_timesheet
#: model:ir.actions.act_window,name:project_timesheet.action_account_analytic_overdue
msgid "Customer Projects"
msgstr ""
msgstr "Захиалагчийн төслууд"
#. module: project_timesheet
#: model:ir.model,name:project_timesheet.model_account_analytic_line
msgid "Analytic Line"
msgstr ""
msgstr "Шинжилгээний мөр"
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "August"
msgstr ""
msgstr "8-р сар"
#. module: project_timesheet
#: model:process.transition,name:project_timesheet.process_transition_taskinvoice0
msgid "Task invoice"
msgstr ""
msgstr "Даалгаврын нэхэмжлэл"
#. module: project_timesheet
#: model:process.node,name:project_timesheet.process_node_taskwork0
msgid "Task Work"
msgstr ""
msgstr "Даалгаврын ажил"
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "May"
msgstr ""
msgstr "5-р сар"
#. module: project_timesheet
#: constraint:project.task:0
msgid "Error ! You cannot create recursive tasks."
msgstr ""
msgstr "Алдаа ! Та рекурсив цэс үүсгэж болохгүй!"
#. module: project_timesheet
#: model:ir.ui.menu,name:project_timesheet.menu_project_working_hours
msgid "Timesheet Lines"
msgstr ""
msgstr "Цагийн хуудсын мөрүүд"
#. module: project_timesheet
#: code:addons/project_timesheet/project_timesheet.py:231
#, python-format
msgid "Invalid action !"
msgstr ""
msgstr "Алдаатай үйлдэл !"
#. module: project_timesheet
#: view:project.project:0
msgid "Billable Project"
msgstr ""
msgstr "Нэхэмжлэх боломжтой Төсөл"
#. module: project_timesheet
#: model:ir.ui.menu,name:project_timesheet.menu_invoicing_contracts
msgid "Contracts to Renew"
msgstr ""
msgstr "Шинэчлэх Гэрээнүүд"
#. module: project_timesheet
#: model:ir.ui.menu,name:project_timesheet.menu_hr_timesheet_sign_in
msgid "Sign in / Sign out by project"
msgstr ""
msgstr "Орох/Гарах үйлдлийг төслөөр харах"
#. module: project_timesheet
#: view:report.timesheet.task.user:0
msgid "Group by month of date"
msgstr ""
msgstr "Огнооны сараар бүлэглэх"
#. module: project_timesheet
#: model:ir.model,name:project_timesheet.model_project_task
msgid "Task"
msgstr ""
msgstr "Даалгавар"
#. module: project_timesheet
#: model:ir.ui.menu,name:project_timesheet.menu_project_billing_line
msgid "Invoice Tasks Work"
msgstr ""
msgstr "Даалгаврын Ажлыг Нэхэмжлэх"
#. module: project_timesheet
#: view:report.timesheet.task.user:0
#: field:report.timesheet.task.user,user_id:0
msgid "User"
msgstr ""
msgstr "Хэрэглэгч"
#. module: project_timesheet
#: constraint:project.project:0
msgid "Error! You cannot assign escalation to the same project!"
msgstr ""
msgstr "Алдаа! Ижил төсөлд томруулалтыг олгох боломжгүй."
#. module: project_timesheet
#: field:report.timesheet.task.user,name:0
msgid "Date"
msgstr ""
msgstr "Огноо"
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "July"
msgstr ""
msgstr "7-р сар"
#. module: project_timesheet
#: model:process.node,note:project_timesheet.process_node_timesheettask0
msgid "Complete Your Timesheet."
msgstr ""
msgstr "Цагийн Хуудсаа Гүйцээ"
#. module: project_timesheet
#: view:report.timesheet.task.user:0
msgid "Task Hours in current year"
msgstr ""
msgstr "Энэ жилийн даалгаврын цаг"
#. module: project_timesheet
#: view:project.project:0
msgid "Customer"
msgstr ""
msgstr "Захиалагч"
#. module: project_timesheet
#: model:process.node,note:project_timesheet.process_node_taskwork0
msgid "Work on task"
msgstr ""
msgstr "Даалгавар дахь ажил"
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "February"
msgstr ""
msgstr "2-р сар"
#. module: project_timesheet
#: model:ir.actions.act_window,name:project_timesheet.action_project_timesheet_bill_task
msgid "Bill Tasks Works"
msgstr ""
msgstr "Даалгаврын ажлуудын тооцоо"
#. module: project_timesheet
#: field:report.timesheet.task.user,timesheet_hrs:0
msgid "Timesheet Hours"
msgstr ""
msgstr "Цагийн хуудас дахь цагууд"
#. module: project_timesheet
#: model:process.transition,name:project_timesheet.process_transition_taskencoding0
msgid "Task encoding"
msgstr ""
msgstr "Даалгаврыг шивнэ үү"
#. module: project_timesheet
#: model:process.transition,note:project_timesheet.process_transition_filltimesheet0
msgid "Task summary is comes into the timesheet line"
msgstr ""
msgstr "Даалгаврын товчоо нь цагийн хуудсын мөр рүү очдог."
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "January"
msgstr ""
msgstr "1-р сар"
#. module: project_timesheet
#: model:process.node,name:project_timesheet.process_node_triggerinvoice0
msgid "Trigger Invoice"
msgstr ""
msgstr "Нэхэмжлэлийг Үүсгэх"
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "November"
msgstr ""
msgstr "11-р сар"
#. module: project_timesheet
#: view:report.timesheet.task.user:0
msgid "Task hours of last month"
msgstr ""
msgstr "Өнгөрсөн сарын ажлын цагууд"
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "March"
msgstr ""
msgstr "3-р сар"
#. module: project_timesheet
#: model:ir.model,name:project_timesheet.model_project_project
msgid "Project"
msgstr ""
msgstr "Төсөл"
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "April"
msgstr ""
msgstr "4-р сар"
#. module: project_timesheet
#: view:project.project:0
msgid "Invoicing Data"
msgstr ""
msgstr "Нэхэмжлэх өгөгдөл"
#. module: project_timesheet
#: model:process.transition,note:project_timesheet.process_transition_taskencoding0
msgid "Encode how much time u spent on your task"
msgstr ""
msgstr "Өөрийн даалгавар дээр хичнээн цаг зарцуулснаа оруулна уу"
#. module: project_timesheet
#: model:ir.model,name:project_timesheet.model_res_partner
msgid "Partner"
msgstr ""
msgstr "Харилцагч"
#. module: project_timesheet
#: code:addons/project_timesheet/project_timesheet.py:247
#, python-format
msgid "Invalid Analytic Account !"
msgstr ""
msgstr "Буруу Шинжилгээний Данс !"
#. module: project_timesheet
#: code:addons/project_timesheet/project_timesheet.py:59
@ -349,6 +353,8 @@ msgid ""
"No product defined on the related employee.\n"
"Fill in the timesheet tab of the employee form."
msgstr ""
"Холбогдох ажилтан дээр бараа тодорхойлогдоогүй байна.\n"
"Ажилтны формын цагийн хуудас хавтас дээр бөглөнө үү."
#. module: project_timesheet
#: code:addons/project_timesheet/project_timesheet.py:54
@ -357,17 +363,17 @@ msgstr ""
#: code:addons/project_timesheet/project_timesheet.py:69
#, python-format
msgid "Bad Configuration !"
msgstr ""
msgstr "Буруу Тохиргоо !"
#. module: project_timesheet
#: model:ir.ui.menu,name:project_timesheet.menu_project_billing
msgid "Invoicing"
msgstr ""
msgstr "Нэхэмжлэл"
#. module: project_timesheet
#: constraint:res.partner:0
msgid "Error ! You cannot create recursive associated members."
msgstr ""
msgstr "Алдаа ! Рекурсив холбогдсон гишүүдийг үүсгэх боломжгүй."
#. module: project_timesheet
#: code:addons/project_timesheet/project_timesheet.py:247
@ -375,57 +381,58 @@ msgstr ""
msgid ""
"You cannot select a Analytic Account which is in Close or Cancelled state"
msgstr ""
"Хаагдсан эсвэл Цуцлагдсан төлөвтэй Шинжилгээний Дансыг сонгох боломжгүй"
#. module: project_timesheet
#: view:report.timesheet.task.user:0
msgid " Month-1 "
msgstr ""
msgstr " Сар-1 "
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "September"
msgstr ""
msgstr "9-р сар"
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "December"
msgstr ""
msgstr "12-р сар"
#. module: project_timesheet
#: model:process.transition,note:project_timesheet.process_transition_taskinvoice0
msgid "After task is completed, Create its invoice."
msgstr ""
msgstr "Даалгавар дуусмагц харгалзах нэхэмжлэл үүсгэнэ."
#. module: project_timesheet
#: selection:report.timesheet.task.user,month:0
msgid "June"
msgstr ""
msgstr "6-р сар"
#. module: project_timesheet
#: model:ir.model,name:project_timesheet.model_report_timesheet_task_user
msgid "report.timesheet.task.user"
msgstr ""
msgstr "report.timesheet.task.user"
#. module: project_timesheet
#: view:report.timesheet.task.user:0
#: field:report.timesheet.task.user,month:0
msgid "Month"
msgstr ""
msgstr "Сар"
#. module: project_timesheet
#: model:ir.ui.menu,name:project_timesheet.menu_act_project_management_timesheet_sheet_form
msgid "My Timesheet"
msgstr ""
msgstr "Өөрийн цагийн хуудас"
#. module: project_timesheet
#: constraint:account.analytic.line:0
msgid "You can not create analytic line on view account."
msgstr ""
msgstr "Харагдац төрлийн данс дээр шинжилгээний мөрийг үүсгэх боломжгүй."
#. module: project_timesheet
#: view:project.project:0
msgid "Invoice Task Work"
msgstr ""
msgstr "Даалгаврын Ажлыг Нэхэмжлэх"
#. module: project_timesheet
#: code:addons/project_timesheet/project_timesheet.py:70
@ -435,15 +442,18 @@ msgid ""
"employee.\n"
"Fill in the timesheet tab of the employee form."
msgstr ""
"Холбогдох ажилтан дээр бараа болон барааны ангилалын үзүүлэлтийн данс "
"тодорхойлогдоогүй байна.\n"
"Ажилтны формын цагийн хуудас хавтсыг бөглөнө үү."
#. module: project_timesheet
#: model:ir.actions.act_window,name:project_timesheet.action_report_timesheet_task_user
#: model:ir.ui.menu,name:project_timesheet.menu_timesheet_task_user
#: view:report.timesheet.task.user:0
msgid "Task Hours Per Month"
msgstr ""
msgstr "Даалгаврын цагууд сарын хэмжээнд"
#. module: project_timesheet
#: model:process.transition,name:project_timesheet.process_transition_filltimesheet0
msgid "Fill Timesheet"
msgstr ""
msgstr "Цагийн хуудсыг бөглөх"

View File

@ -845,7 +845,8 @@ class sale_order(osv.osv):
'procure_method': line.type,
'move_id': move_id,
'company_id': order.company_id.id,
'note': line.notes
'note': line.notes,
'property_ids': [(6, 0, [x.id for x in line.property_ids])]
}
def _prepare_order_line_move(self, cr, uid, order, line, picking_id, date_planned, context=None):

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
"PO-Revision-Date: 2012-06-29 23:16+0000\n"
"PO-Revision-Date: 2012-07-11 05:35+0000\n"
"Last-Translator: Akira Hiyama <Unknown>\n"
"Language-Team: Japanese <ja@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-07-01 04:39+0000\n"
"X-Generator: Launchpad (build 15520)\n"
"X-Launchpad-Export-Date: 2012-07-12 04:40+0000\n"
"X-Generator: Launchpad (build 15593)\n"
#. module: stock
#: field:product.product,track_outgoing:0

View File

@ -243,13 +243,16 @@ class product_product(osv.osv):
child_location_ids = location_obj.search(cr, uid, [('location_id', 'child_of', location_ids)])
location_ids = child_location_ids or location_ids
# this will be a dictionary of the UoM resources we need for conversion purposes, by UoM id
uoms_o = {}
# this will be a dictionary of the product UoM by product id
product2uom = {}
for product in self.browse(cr, uid, ids, context=context):
product2uom[product.id] = product.uom_id.id
uoms_o[product.uom_id.id] = product.uom_id
uom_ids = []
for product in self.read(cr, uid, ids, ['uom_id'], context=context):
product2uom[product['id']] = product['uom_id'][0]
uom_ids.append(product['uom_id'][0])
# this will be a dictionary of the UoM resources we need for conversion purposes, by UoM id
uoms_o = {}
for uom in self.pool.get('product.uom').browse(cr, uid, uom_ids, context=context):
uoms_o[uom.id] = uom
results = []
results2 = []

View File

@ -103,20 +103,14 @@ class stock_change_product_qty(osv.osv_memory):
self.change_product_qty_send_note(cr, uid, [data.id], context)
return {}
def change_product_qty_send_note (self, cr, uid, ids, context=None):
def change_product_qty_send_note(self, cr, uid, ids, context=None):
prod_obj = self.pool.get('product.product')
location_obj = self.pool.get('stock.location')
prod_temp_obj = self.pool.get('product.template')
uom_obj = self.pool.get('product.uom')
for data in self.browse(cr, uid, ids, context=context):
for location in location_obj.browse(cr, uid, [data.location_id.id], context=context):
location_name = location.name
for prod in prod_obj.browse(cr, uid, [data.product_id.id], context=context):
for prod_temp in prod_temp_obj.browse(cr, uid, [prod.product_tmpl_id.id], context=context):
for uom in uom_obj.browse(cr, uid, [prod_temp.uom_id.id], context=context):
message = _("<b>Quantity has been changed</b> to <em>%s %s </em> for <em>%s</em> location.") % (data.new_quantity,uom.name,location_name)
prod_obj.message_append_note(cr, uid, [prod.id], body=message, context=context)
location_name = location_obj.browse(cr, uid, data.location_id.id, context=context).name
message = _("<b>Quantity has been changed</b> to <em>%s %s </em> for <em>%s</em> location.") % (data.new_quantity, data.product_id.uom_id.name, location_name)
prod_obj.message_append_note(cr, uid, [data.product_id.id], body=message, context=context)
stock_change_product_qty()

View File

@ -36,7 +36,7 @@ class stock_invoice_onshipping(osv.osv_memory):
context = {}
model = context.get('active_model')
if not model or model != 'stock.picking':
if not model or 'stock.picking' not in model:
return []
model_pool = self.pool.get(model)

View File

@ -56,7 +56,6 @@ class stock_planning_createlines(osv.osv_memory):
planning_obj = self.pool.get('stock.planning')
mod_obj = self.pool.get('ir.model.data')
prod_categ_obj = self.pool.get('product.category')
template_obj = self.pool.get('product.template')
planning_lines = []
for f in self.browse(cr, uid, ids, context=context):
if f.forecasted_products:
@ -67,8 +66,7 @@ class stock_planning_createlines(osv.osv_memory):
else:
categ_ids = f.product_categ_id.id and [f.product_categ_id.id] or []
prod_categ_ids = prod_categ_obj.search(cr,uid,[('parent_id','child_of',categ_ids)])
templates_ids = template_obj.search(cr,uid,[('categ_id','in',prod_categ_ids)])
products_id1 = product_obj.search(cr,uid,[('product_tmpl_id','in',templates_ids)])
products_id1 = product_obj.search(cr,uid,[('categ_id','in',prod_categ_ids)])
if len(products_id1)==0:
raise osv.except_osv(_('Error !'), _('No forecasts for selected period or no products in selected category !'))

View File

@ -49,13 +49,11 @@ class stock_sale_forecast_createlines(osv.osv_memory):
forecast_obj = self.pool.get('stock.sale.forecast')
mod_obj = self.pool.get('ir.model.data')
prod_categ_obj = self.pool.get('product.category')
template_obj = self.pool.get('product.template')
forecast_lines = []
for f in self.browse(cr, uid, ids, context=context):
categ_ids = f.product_categ_id.id and [f.product_categ_id.id] or []
prod_categ_ids = prod_categ_obj.search(cr, uid, [('parent_id','child_of', categ_ids)])
templates_ids = template_obj.search(cr, uid, [('categ_id','in',prod_categ_ids)])
products_ids = product_obj.search(cr, uid, [('product_tmpl_id','in',templates_ids)])
products_ids = product_obj.search(cr, uid, [('categ_id','in',prod_categ_ids)])
if len(products_ids) == 0:
raise osv.except_osv(_('Error !'), _('No products in selected category !'))
copy = f.copy_forecast