diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py index ec5e2c56e6c..99890a5f239 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis.py +++ b/addons/account_analytic_analysis/account_analytic_analysis.py @@ -543,33 +543,40 @@ class account_analytic_account(osv.osv): 'nodestroy': True, } - def on_change_template(self, cr, uid, ids, template_id, context=None): + def on_change_template(self, cr, uid, ids, template_id, date_start=False, fix_price_invoices=False, invoice_on_timesheets=False, recurring_invoices=False, context=None): if not template_id: return {} obj_analytic_line = self.pool.get('account.analytic.invoice.line') - res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context) + res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, date_start=date_start, context=context) template = self.browse(cr, uid, template_id, context=context) - invoice_line_ids = [] - for x in template.recurring_invoice_line_ids: - invoice_line_ids.append((0, 0, { - 'product_id': x.product_id.id, - 'uom_id': x.uom_id.id, - 'name': x.name, - 'quantity': x.quantity, - 'price_unit': x.price_unit, - 'analytic_account_id': x.analytic_account_id and x.analytic_account_id.id or False, - })) - res['value']['fix_price_invoices'] = template.fix_price_invoices - res['value']['invoice_on_timesheets'] = template.invoice_on_timesheets - res['value']['hours_qtt_est'] = template.hours_qtt_est - res['value']['amount_max'] = template.amount_max - res['value']['to_invoice'] = template.to_invoice.id - res['value']['pricelist_id'] = template.pricelist_id.id - res['value']['recurring_invoices'] = template.recurring_invoices - res['value']['recurring_interval'] = template.recurring_interval - res['value']['recurring_rule_type'] = template.recurring_rule_type - res['value']['recurring_invoice_line_ids'] = invoice_line_ids + + if not fix_price_invoices: + res['value']['fix_price_invoices'] = template.fix_price_invoices + res['value']['amount_max'] = template.amount_max + if not invoice_on_timesheets: + res['value']['invoice_on_timesheets'] = template.invoice_on_timesheets + res['value']['hours_qtt_est'] = template.hours_qtt_est + + if template.to_invoice.id: + res['value']['to_invoice'] = template.to_invoice.id + if template.pricelist_id.id: + res['value']['pricelist_id'] = template.pricelist_id.id + if not recurring_invoices: + invoice_line_ids = [] + for x in template.recurring_invoice_line_ids: + invoice_line_ids.append((0, 0, { + 'product_id': x.product_id.id, + 'uom_id': x.uom_id.id, + 'name': x.name, + 'quantity': x.quantity, + 'price_unit': x.price_unit, + 'analytic_account_id': x.analytic_account_id and x.analytic_account_id.id or False, + })) + res['value']['recurring_invoices'] = template.recurring_invoices + res['value']['recurring_interval'] = template.recurring_interval + res['value']['recurring_rule_type'] = template.recurring_rule_type + res['value']['recurring_invoice_line_ids'] = invoice_line_ids return res def onchange_recurring_invoices(self, cr, uid, ids, recurring_invoices, date_start=False, context=None): diff --git a/addons/account_analytic_analysis/account_analytic_analysis_view.xml b/addons/account_analytic_analysis/account_analytic_analysis_view.xml index f5b89db7089..d99be3db355 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis_view.xml +++ b/addons/account_analytic_analysis/account_analytic_analysis_view.xml @@ -38,6 +38,9 @@ {'required': [('type','=','contract'),'|','|',('fix_price_invoices','=',True), ('invoice_on_timesheets', '=', True), ('recurring_invoices', '=', True)]} + + on_change_template(template_id, date_start, fix_price_invoices, invoice_on_timesheets, recurring_invoices) + diff --git a/addons/analytic/analytic.py b/addons/analytic/analytic.py index 894a2a2d6c5..c1ea1f655d2 100644 --- a/addons/analytic/analytic.py +++ b/addons/analytic/analytic.py @@ -203,7 +203,7 @@ class account_analytic_account(osv.osv): }, string='Currency', type='many2one', relation='res.currency'), } - def on_change_template(self, cr, uid, ids, template_id, context=None): + def on_change_template(self, cr, uid, ids, template_id, date_start=False, context=None): if not template_id: return {} res = {'value':{}} @@ -213,7 +213,8 @@ class account_analytic_account(osv.osv): to_dt = datetime.strptime(template.date, tools.DEFAULT_SERVER_DATE_FORMAT) timedelta = to_dt - from_dt res['value']['date'] = datetime.strftime(datetime.now() + timedelta, tools.DEFAULT_SERVER_DATE_FORMAT) - res['value']['date_start'] = fields.date.today() + if not date_start: + res['value']['date_start'] = fields.date.today() res['value']['quantity_max'] = template.quantity_max res['value']['parent_id'] = template.parent_id and template.parent_id.id or False res['value']['description'] = template.description diff --git a/addons/analytic/analytic_view.xml b/addons/analytic/analytic_view.xml index 9a99552be13..5e65874a1d9 100644 --- a/addons/analytic/analytic_view.xml +++ b/addons/analytic/analytic_view.xml @@ -27,7 +27,7 @@ - + diff --git a/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py b/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py index a1bf43714ce..3682755b9c4 100644 --- a/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py +++ b/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py @@ -115,8 +115,8 @@ class account_analytic_account(osv.osv): digits_compute=dp.get_precision('Account')), } - def on_change_template(self, cr, uid, id, template_id, context=None): - res = super(account_analytic_account, self).on_change_template(cr, uid, id, template_id, context=context) + def on_change_template(self, cr, uid, id, template_id, date_start=False, context=None): + res = super(account_analytic_account, self).on_change_template(cr, uid, id, template_id, date_start=date_start, context=context) if template_id and 'value' in res: template = self.browse(cr, uid, template_id, context=context) res['value']['charge_expenses'] = template.charge_expenses diff --git a/addons/base_gengo/gengo_sync_schedular_data.xml b/addons/base_gengo/gengo_sync_schedular_data.xml index baf2a639cff..e55066e0e74 100644 --- a/addons/base_gengo/gengo_sync_schedular_data.xml +++ b/addons/base_gengo/gengo_sync_schedular_data.xml @@ -4,7 +4,7 @@ Gengo Sync Translation (Response) - + 20 minutes -1 @@ -16,7 +16,7 @@ Gengo Sync Translation (Request) - + 20 minutes -1 diff --git a/addons/base_gengo/ir_translation.py b/addons/base_gengo/ir_translation.py index 0ade9c54625..306516878cc 100644 --- a/addons/base_gengo/ir_translation.py +++ b/addons/base_gengo/ir_translation.py @@ -23,7 +23,7 @@ from openerp.osv import fields, osv from openerp.tools.translate import _ LANG_CODE_MAPPING = { - 'ar_SA': ('ar', 'Arabic'), + 'ar_SY': ('ar', 'Arabic'), 'id_ID': ('id', 'Indonesian'), 'nl_NL': ('nl', 'Dutch'), 'fr_CA': ('fr-ca', 'French (Canada)'), @@ -41,7 +41,19 @@ LANG_CODE_MAPPING = { 'fr_BE': ('fr', 'French'), 'ru_RU': ('ru', 'Russian'), 'it_IT': ('it', 'Italian'), - 'pt_BR': ('pt-br', 'Portuguese (Brazil)') + 'pt_BR': ('pt-br', 'Portuguese (Brazil)'), + 'th_TH': ('th', 'Thai'), + 'nb_NO': ('no', 'Norwegian'), + 'ro_RO': ('ro', 'Romanian'), + 'tr_TR': ('tr', 'Turkish'), + 'bg_BG': ('bg', 'Bulgarian'), + 'da_DK': ('da', 'Danish'), + 'en_GB': ('en-gb', 'English (British)'), + 'el_GR': ('el', 'Greek'), + 'vi_VN': ('vi', 'Vietnamese'), + 'he_IL': ('he', 'Hebrew'), + 'hu_HU': ('hu', 'Hungarian'), + 'fi_FI': ('fi', 'Finnish') } class ir_translation(osv.Model): @@ -71,18 +83,3 @@ class ir_translation(osv.Model): def _get_gengo_corresponding_language(cr, lang): return lang in LANG_CODE_MAPPING and LANG_CODE_MAPPING[lang][0] or lang - - def _check_lang_support(self, cr, uid, ids, context=None): - for term in self.browse(cr, uid, ids, context=context): - if term.gengo_translation: - supported_langs = self._get_all_supported_languages(cr, uid, context=context) - if supported_langs: - tier = "nonprofit" if term.gengo_translation == 'machine' else term.gengo_translation - language = self._get_gengo_corresponding_language(term.lang) - if tier not in supported_langs.get(language,[]): - return False - return True - - _constraints = [ - (_check_lang_support, 'The Gengo translation service selected is not supported for this language.', ['gengo_translation']) - ] diff --git a/addons/base_gengo/res_company.py b/addons/base_gengo/res_company.py index 3d038ac0813..1b083ecf5a2 100644 --- a/addons/base_gengo/res_company.py +++ b/addons/base_gengo/res_company.py @@ -30,6 +30,7 @@ class res_company(osv.Model): "gengo_public_key": fields.text("Gengo Public Key"), "gengo_comment": fields.text("Comments", help="This comment will be automatically be enclosed in each an every request sent to Gengo"), "gengo_auto_approve": fields.boolean("Auto Approve Translation ?", help="Jobs are Automatically Approved by Gengo."), + "gengo_sandbox": fields.boolean("Sandbox Mode", help="Check this box if you're using the sandbox mode of Gengo, mainly used for testing purpose."), } _defaults = { diff --git a/addons/base_gengo/res_company_view.xml b/addons/base_gengo/res_company_view.xml index 0f99efc8ad0..d08d809eb9c 100644 --- a/addons/base_gengo/res_company_view.xml +++ b/addons/base_gengo/res_company_view.xml @@ -17,8 +17,13 @@ - - + + + + + + + diff --git a/addons/base_gengo/wizard/base_gengo_translations.py b/addons/base_gengo/wizard/base_gengo_translations.py index bfd51480141..ecfb696fddc 100644 --- a/addons/base_gengo/wizard/base_gengo_translations.py +++ b/addons/base_gengo/wizard/base_gengo_translations.py @@ -40,22 +40,19 @@ except ImportError: GENGO_DEFAULT_LIMIT = 20 -DEFAULT_CRON_VALS = { - 'active': True, - 'interval_number': 20, - 'interval_type': 'minutes', - 'model': "'base.gengo.translations'", - 'args': "'(%s,)'" % (str(GENGO_DEFAULT_LIMIT)), -} - class base_gengo_translations(osv.osv_memory): _name = 'base.gengo.translations' _columns = { - 'restart_send_job': fields.boolean("Restart Sending Job"), + 'sync_type': fields.selection([('send', 'Send New Terms'), + ('receive', 'Receive Translation'), + ('both', 'Both')], "Sync Type"), 'lang_id': fields.many2one('res.lang', 'Language', required=True), + 'sync_limit': fields.integer("No. of terms to sync"), } - + _defaults = {'sync_type' : 'both', + 'sync_limit' : 20 + } def gengo_authentication(self, cr, uid, context=None): ''' This method tries to open a connection with Gengo. For that, it uses the Public and Private @@ -74,6 +71,7 @@ class base_gengo_translations(osv.osv_memory): gengo = MyGengo( public_key=user.company_id.gengo_public_key.encode('ascii'), private_key=user.company_id.gengo_private_key.encode('ascii'), + sandbox = user.company_id.gengo_sandbox, ) gengo.getAccountStats() return (True, gengo) @@ -81,22 +79,6 @@ class base_gengo_translations(osv.osv_memory): _logger.exception('Gengo connection failed') return (False, _("Gengo connection failed with this message:\n``%s``") % e) - def do_check_schedular(self, cr, uid, xml_id, name, fn, context=None): - """ - This function is used to reset a cron to its default values, or to recreate it if it was deleted. - """ - cron_pool = self.pool.get('ir.cron') - cron_vals = DEFAULT_CRON_VALS.copy() - cron_vals.update({'name': name, "function": fn}) - try: - res = [] - _, res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base_gengo', xml_id) - cron_pool.write(cr, uid, [res], cron_vals, context=context) - except: - #the cron job was not found, probably deleted previously, so we create it again using default values - cron_vals.update({'numbercall': -1}) - return cron_pool.create(cr, uid, cron_vals, context=context) - def act_update(self, cr, uid, ids, context=None): ''' Function called by the wizard. @@ -113,15 +95,14 @@ class base_gengo_translations(osv.osv_memory): if language not in supported_langs: raise osv.except_osv(_("Warning"), _('This language is not supported by the Gengo translation services.')) - #send immediately a new request for the selected language (if any) ctx = context.copy() ctx['gengo_language'] = wizard.lang_id.id - self._sync_request(cr, uid, limit=GENGO_DEFAULT_LIMIT, context=ctx) - self._sync_response( cr, uid, limit=GENGO_DEFAULT_LIMIT, context=ctx) - #check the cron jobs and eventually restart/recreate them - if wizard.restart_send_job: - self.do_check_schedular(cr, uid, 'gengo_sync_send_request_scheduler', _('Gengo Sync Translation (Request)'), '_sync_request', context=context) - self.do_check_schedular(cr, uid, 'gengo_sync_receive_request_scheduler', _('Gengo Sync Translation (Response)'), '_sync_response', context=context) + if wizard.sync_limit > 200 or wizard.sync_limit < 1: + raise osv.except_osv(_("Warning"), _('Sync limit should between 1 to 200 for Gengo translation services.')) + if wizard.sync_type in ['send','both']: + self._sync_request(cr, uid, wizard.sync_limit, context=ctx) + if wizard.sync_type in ['receive','both']: + self._sync_response( cr, uid, wizard.sync_limit, context=ctx) return {'type': 'ir.actions.act_window_close'} def _sync_response(self, cr, uid, limit=GENGO_DEFAULT_LIMIT, context=None): @@ -135,31 +116,31 @@ class base_gengo_translations(osv.osv_memory): if not flag: _logger.warning("%s", gengo) else: - translation_id = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine','standard','pro','ultra'))], limit=limit, context=context) - for term in translation_pool.browse(cr, uid, translation_id, context=context): - up_term = up_comment = 0 - if term.job_id: - vals={} - job_response = gengo.getTranslationJob(id=term.job_id) - if job_response['opstat'] != 'ok': - _logger.warning("Invalid Response! Skipping translation Terms with `id` %s." % (term.job_id)) - continue - if job_response['response']['job']['status'] == 'approved': - vals.update({'state': 'translated', - 'value': job_response['response']['job']['body_tgt']}) - up_term += 1 - job_comment = gengo.getTranslationJobComments(id=term.job_id) - if job_comment['opstat']=='ok': - gengo_comments="" - for comment in job_comment['response']['thread']: - gengo_comments += _('%s\n\n--\n Commented on %s by %s.') % (comment['body'], time.ctime(comment['ctime']), comment['author']) - vals.update({'gengo_comment': gengo_comments}) - up_comment += 1 - if vals: - translation_pool.write(cr, uid, term.id, vals) - _logger.info("Successfully Updated `%d` terms and %d Comments." % (up_term, up_comment )) - else: - _logger.warning("%s", 'Cannot retrieve the Gengo job ID for translation %s: %s' % (term.id, term.src)) + translation_id = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine','standard','pro','ultra')), ('job_id', "!=",False)], limit=limit, context=context) + translation_terms = translation_pool.browse(cr, uid, translation_id, context=context) + gengo_job_id = [term.job_id for term in translation_terms] + if gengo_job_id: + gengo_ids = ','.join(gengo_job_id) + job_response = gengo.getTranslationJobBatch(id=gengo_ids) + if job_response['opstat'] == 'ok': + job_response_dict = dict([(job['job_id'],job) for job in job_response['response']['jobs']]) + for term in translation_terms: + up_term = up_comment = 0 + vals={} + if job_response_dict[term.job_id]['status'] == 'approved': + vals.update({'state': 'translated', + 'value': job_response_dict[term.job_id]['body_tgt']}) + up_term += 1 + job_comment = gengo.getTranslationJobComments(id=term.job_id) + if job_comment['opstat']=='ok': + gengo_comments="" + for comment in job_comment['response']['thread']: + gengo_comments += _('%s\n-- Commented on %s by %s.\n\n') % (comment['body'], time.ctime(comment['ctime']), comment['author']) + vals.update({'gengo_comment': gengo_comments}) + up_comment += 1 + if vals: + translation_pool.write(cr, uid, term.id, vals) + _logger.info("Successfully Updated `%d` terms and %d Comments." % (up_term, up_comment )) return True def _update_terms(self, cr, uid, response, context=None): @@ -200,7 +181,8 @@ class base_gengo_translations(osv.osv_memory): 'lc_src': 'en', 'lc_tgt': translation_pool._get_gengo_corresponding_language(term.lang), 'auto_approve': auto_approve, - 'comment': user.company_id.gengo_comment, + 'comment': user.company_id.gengo_comment and "%s %s"%(user.company_id.gengo_comment,term.gengo_comment) or term.gengo_comment, + 'callback_url': self.pool.get('ir.config_parameter').get_param(cr, uid,'web.base.url') + '/website/gengo_callback/' + str(term.id) } return {'jobs': jobs} @@ -242,7 +224,7 @@ class base_gengo_translations(osv.osv_memory): lang_ids = [context.get('gengo_language')] langs = [lang.code for lang in language_pool.browse(cr, uid, lang_ids, context=context)] #search for the n first terms to translate - term_ids = translation_pool.search(cr, uid, [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine','standard','pro','ultra')), ('lang', 'in', langs)], limit=limit, context=context) + term_ids = translation_pool.search(cr, uid, [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine','standard','pro','ultra')), ('lang', 'in', langs),('job_id',"=",False)], limit=limit, context=context) if term_ids: self._send_translation_terms(cr, uid, term_ids, context=context) _logger.info("%s Translation terms have been posted to Gengo successfully", len(term_ids)) diff --git a/addons/base_gengo/wizard/base_gengo_translations_view.xml b/addons/base_gengo/wizard/base_gengo_translations_view.xml index 7b6be31d042..f1d77730c47 100644 --- a/addons/base_gengo/wizard/base_gengo_translations_view.xml +++ b/addons/base_gengo/wizard/base_gengo_translations_view.xml @@ -8,7 +8,14 @@
- + + + + + + + +