diff options
| author | Paramjit Singh Sahota <psa@tinyerp.com> | 2013-04-05 19:00:30 +0530 |
|---|---|---|
| committer | Paramjit Singh Sahota <psa@tinyerp.com> | 2013-04-05 19:00:30 +0530 |
| commit | fcb015d277bc688c7ee19bc406aaf32b241e49af (patch) | |
| tree | 5a0ab4e5794368a5e902d8eb0a5fe82e19eec7da /addons | |
| parent | 7e2e37b7c9ab314c5a45f99547b1a22be58eede8 (diff) | |
| parent | d8b3533a82fa19a509ca53881570b56af2ab30ff (diff) | |
[MERGE] Merged lp:openobject-addons.
bzr revid: psa@tinyerp.com-20130405133030-u1lr42lly3dqvr37
Diffstat (limited to 'addons')
72 files changed, 1117 insertions, 514 deletions
diff --git a/addons/account/account.py b/addons/account/account.py index bb24aec1748..1a44e480e03 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -1027,6 +1027,9 @@ class account_period(osv.osv): def action_draft(self, cr, uid, ids, *args): mode = 'draft' + for period in self.browse(cr, uid, ids): + if period.fiscalyear_id.state == 'done': + raise osv.except_osv(_('Warning !'), _('You can not re-open a period which belongs to closed fiscal year')) cr.execute('update account_journal_period set state=%s where period_id in %s', (mode, tuple(ids),)) cr.execute('update account_period set state=%s where id in %s', (mode, tuple(ids),)) return True diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 36d211c11d2..082d654c5a2 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -742,7 +742,7 @@ class account_move_line(osv.osv): def list_partners_to_reconcile(self, cr, uid, context=None): cr.execute( """SELECT partner_id FROM ( - SELECT l.partner_id, p.last_reconciliation_date, SUM(l.debit) AS debit, SUM(l.credit) AS credit, MAX(l.date) AS max_date + SELECT l.partner_id, p.last_reconciliation_date, SUM(l.debit) AS debit, SUM(l.credit) AS credit, MAX(l.create_date) AS max_date FROM account_move_line l RIGHT JOIN account_account a ON (a.id = l.account_id) RIGHT JOIN res_partner p ON (l.partner_id = p.id) @@ -753,9 +753,14 @@ class account_move_line(osv.osv): ) AS s WHERE debit > 0 AND credit > 0 AND (last_reconciliation_date IS NULL OR max_date > last_reconciliation_date) ORDER BY last_reconciliation_date""") - ids = cr.fetchall() - ids = len(ids) and [x[0] for x in ids] or [] - return self.pool.get('res.partner').name_get(cr, uid, ids, context=context) + ids = [x[0] for x in cr.fetchall()] + if not ids: + return [] + + # To apply the ir_rules + partner_obj = self.pool.get('res.partner') + ids = partner_obj.search(cr, uid, [('id', 'in', ids)], context=context) + return partner_obj.name_get(cr, uid, ids, context=context) def reconcile_partial(self, cr, uid, ids, type='auto', context=None, writeoff_acc_id=False, writeoff_period_id=False, writeoff_journal_id=False): move_rec_obj = self.pool.get('account.move.reconcile') diff --git a/addons/account/report/account_invoice_report.py b/addons/account/report/account_invoice_report.py index af6ae1eede7..31725a46b46 100644 --- a/addons/account/report/account_invoice_report.py +++ b/addons/account/report/account_invoice_report.py @@ -210,8 +210,8 @@ class account_invoice_report(osv.osv): cr.id IN (SELECT id FROM res_currency_rate cr2 WHERE (cr2.currency_id = sub.currency_id) - AND ((sub.date IS NOT NULL AND cr.name <= sub.date) - OR (sub.date IS NULL AND cr.name <= NOW())) + AND ((sub.date IS NOT NULL AND cr2.name <= sub.date) + OR (sub.date IS NULL AND cr2.name <= NOW())) ORDER BY name DESC LIMIT 1) )""" % ( self._table, diff --git a/addons/account/report/account_print_invoice.rml b/addons/account/report/account_print_invoice.rml index 4ffa7a33f9d..9268c94d4c7 100644 --- a/addons/account/report/account_print_invoice.rml +++ b/addons/account/report/account_print_invoice.rml @@ -168,7 +168,7 @@ </para> <para style="terp_default_8">Tel. : [[ (o.partner_id.phone) or removeParentNode('para') ]]</para> <para style="terp_default_8">Fax : [[ (o.partner_id.fax) or removeParentNode('para') ]]</para> - <para style="terp_default_8">VAT : [[ (o.partner_id.vat) or removeParentNode('para') ]]</para> + <para style="terp_default_8">TIN : [[ (o.partner_id.vat) or removeParentNode('para') ]]</para> </td> </tr> </blockTable> diff --git a/addons/account/wizard/account_invoice_refund.py b/addons/account/wizard/account_invoice_refund.py index df4ad3494d2..ba48dd34fe2 100644 --- a/addons/account/wizard/account_invoice_refund.py +++ b/addons/account/wizard/account_invoice_refund.py @@ -181,9 +181,9 @@ class account_invoice_refund(osv.osv_memory): invoice = invoice[0] del invoice['id'] invoice_lines = inv_line_obj.browse(cr, uid, invoice['invoice_line'], context=context) - invoice_lines = inv_obj._refund_cleanup_lines(cr, uid, invoice_lines) + invoice_lines = inv_obj._refund_cleanup_lines(cr, uid, invoice_lines, context=context) tax_lines = inv_tax_obj.browse(cr, uid, invoice['tax_line'], context=context) - tax_lines = inv_obj._refund_cleanup_lines(cr, uid, tax_lines) + tax_lines = inv_obj._refund_cleanup_lines(cr, uid, tax_lines, context=context) invoice.update({ 'type': inv.type, 'date_invoice': date, diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py index 0a56c80766b..33ab3be209c 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis.py +++ b/addons/account_analytic_analysis/account_analytic_analysis.py @@ -352,11 +352,10 @@ class account_analytic_account(osv.osv): res[account.id] = 0.0 sale_ids = sale_obj.search(cr, uid, [('project_id','=', account.id), ('state', '=', 'manual')], context=context) for sale in sale_obj.browse(cr, uid, sale_ids, context=context): - if not sale.invoiced: - res[account.id] += sale.amount_untaxed - for invoice in sale.invoice_ids: - if invoice.state not in ('draft', 'cancel'): - res[account.id] -= invoice.amount_untaxed + res[account.id] += sale.amount_untaxed + for invoice in sale.invoice_ids: + if invoice.state != 'cancel': + res[account.id] -= invoice.amount_untaxed return res def _timesheet_ca_invoiced_calc(self, cr, uid, ids, name, arg, context=None): diff --git a/addons/account_cancel/i18n/hu.po b/addons/account_cancel/i18n/hu.po index 6b63bb37bb2..bab8304030f 100644 --- a/addons/account_cancel/i18n/hu.po +++ b/addons/account_cancel/i18n/hu.po @@ -7,19 +7,19 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2011-01-30 16:46+0000\n" -"Last-Translator: Krisztian Eyssen <krisz@eyssen.hu>\n" +"PO-Revision-Date: 2013-04-04 13:17+0000\n" +"Last-Translator: krnkris <Unknown>\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:42+0000\n" -"X-Generator: Launchpad (build 16532)\n" +"X-Launchpad-Export-Date: 2013-04-05 05:37+0000\n" +"X-Generator: Launchpad (build 16550)\n" #. module: account_cancel #: view:account.invoice:0 msgid "Cancel" -msgstr "" +msgstr "Sztornó" #~ msgid "Account Cancel" #~ msgstr "Érvénytelenítés" diff --git a/addons/account_followup/i18n/hu.po b/addons/account_followup/i18n/hu.po index a8fc4f8963c..e69bb7b38c0 100644 --- a/addons/account_followup/i18n/hu.po +++ b/addons/account_followup/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:05+0000\n" -"PO-Revision-Date: 2011-11-11 15:21+0000\n" -"Last-Translator: Krisztian Eyssen <krisz@eyssen.hu>\n" +"PO-Revision-Date: 2013-04-04 13:15+0000\n" +"Last-Translator: krnkris <Unknown>\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:11+0000\n" -"X-Generator: Launchpad (build 16532)\n" +"X-Launchpad-Export-Date: 2013-04-05 05:37+0000\n" +"X-Generator: Launchpad (build 16550)\n" #. module: account_followup #: model:email.template,subject:account_followup.email_template_account_followup_default @@ -22,12 +22,12 @@ msgstr "" #: model:email.template,subject:account_followup.email_template_account_followup_level1 #: model:email.template,subject:account_followup.email_template_account_followup_level2 msgid "${user.company_id.name} Payment Reminder" -msgstr "" +msgstr "${user.company_id.name} Fizetési felszólítás" #. module: account_followup #: help:res.partner,latest_followup_level_id:0 msgid "The maximum follow-up level" -msgstr "" +msgstr "Fizetési-emlékeztető szint maximuma" #. module: account_followup #: view:account_followup.stat:0 @@ -43,33 +43,33 @@ msgstr "Fizetési emlékeztető" #. module: account_followup #: view:account_followup.followup.line:0 msgid "%(date)s" -msgstr "" +msgstr "%(date)s" #. module: account_followup #: field:res.partner,payment_next_action_date:0 msgid "Next Action Date" -msgstr "" +msgstr "Következő művelet időpontja" #. module: account_followup #: view:account_followup.followup.line:0 #: field:account_followup.followup.line,manual_action:0 msgid "Manual Action" -msgstr "" +msgstr "Kézi művelet" #. module: account_followup #: field:account_followup.sending.results,needprinting:0 msgid "Needs Printing" -msgstr "" +msgstr "Nyomtatás szükséges" #. module: account_followup #: view:res.partner:0 msgid "⇾ Mark as Done" -msgstr "" +msgstr "⇾ Jelölje elvégzettnek" #. module: account_followup #: field:account_followup.followup.line,manual_action_note:0 msgid "Action To Do" -msgstr "" +msgstr "Elvégzendő művelet" #. module: account_followup #: field:account_followup.followup,company_id:0 @@ -94,34 +94,34 @@ msgstr "E-mail tárgya" #. module: account_followup #: view:account_followup.followup.line:0 msgid "%(user_signature)s" -msgstr "" +msgstr "%(user_signature)s" #. module: account_followup #: view:account_followup.followup.line:0 msgid "days overdue, do the following actions:" -msgstr "" +msgstr "a határidő napján, a következő műveleteket hajtsa végre:" #. module: account_followup #: view:account_followup.followup.line:0 msgid "Follow-up Steps" -msgstr "" +msgstr "Fizetési-emlékezetető lépései" #. module: account_followup #: field:account_followup.print,email_body:0 msgid "Email Body" -msgstr "" +msgstr "E-mail szövege" #. module: account_followup #: model:ir.actions.act_window,name:account_followup.action_account_followup_print msgid "Send Follow-Ups" -msgstr "" +msgstr "Fizetési-emlékezető küldése" #. module: account_followup #: report:account_followup.followup.print:0 #: code:addons/account_followup/account_followup.py:263 #, python-format msgid "Amount" -msgstr "" +msgstr "Összeg" #. module: account_followup #: help:res.partner,payment_next_action:0 @@ -129,11 +129,14 @@ msgid "" "This is the next action to be taken. It will automatically be set when the " "partner gets a follow-up level that requires a manual action. " msgstr "" +"Ez a következő elvégezni kívánt művelet. Ez automatikusan beállított amint " +"a partner elér egy olyan fizetési-emlékeztető szintet, ami kézi beavatkozást " +"igényel. " #. module: account_followup #: view:res.partner:0 msgid "No Responsible" -msgstr "" +msgstr "Nincs felelős" #. module: account_followup #: model:account_followup.followup.line,description:account_followup.demo_followup_line2 @@ -158,6 +161,24 @@ msgid "" "\n" "Best Regards,\n" msgstr "" +"\n" +"Tisztelt %(partner_name)s,\n" +"\n" +"Csalódottan vettük tudomásul, és ezért fizetési-emlékeztetőt vagyunk " +"kénytelenek küldeni, mivel a számlája már régebben esedékessé vált.\n" +"\n" +"Fontos, hogy azonnal fizessenek, egyéb esetben kénytelenek vagyunk elbírálni " +"a számlájuk lezárását, ami azzal jár, hogy nem leszünk képesek időben " +"szállítani az Önök vállalakozásának (termékeket/szolgáltatásokat).\n" +"Kérjük Önöket a fizetés 8 napon belüli pontos teljesítésére.\n" +"\n" +"Ha a fizetéssel kapcsolatban probléma merült fel, amit mi nem vettünk " +"figyelembe, akkor kérjük vegyék fel a könyvelési csoportunkkal a " +"kapcsolatot, hogy elháríthassuk azt amilyen gyorsan csak lehet.\n" +"\n" +"A lejárt számlák részleteit lentebb találják.\n" +"\n" +"Üdvözlettel,\n" #. module: account_followup #: model:email.template,body_html:account_followup.email_template_account_followup_level0 @@ -195,6 +216,39 @@ msgid "" "</div>\n" " " msgstr "" +"\n" +"<div style=\"font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-" +"serif; font-size: 12px; color: rgb(34, 34, 34); background-color: rgb(255, " +"255, 255); \">\n" +"\n" +" <p>Tisztelt ${object.name},</p>\n" +" <p>\n" +" Ha időközben kiegyenlítésre került, vagy a mi hibánkból adódóan téves, " +"akkor tárgytalan, \n" +"de adataink szerint a következő tétel kifizetés nélkül maradt. \n" +"Kérjük Önöket a fizetés 8 napon belüli pontos teljesítésére.\n" +"\n" +"Ha a levél elküldése előtt a fizetés már megtörtént akkor kérjük tekintsék " +"ezt tárgytalannak. Kérjük vegyék fel a kapcsolatot könyvelési " +"csoportunkkal. \n" +"\n" +" </p>\n" +"<br/>\n" +"Üdvözlettel,\n" +"<br/>\n" +" <br/>\n" +"${user.name}\n" +"\n" +"<br/>\n" +"<br/>\n" +"\n" +"\n" +"${object.get_followup_table_html() | safe}\n" +"\n" +" <br/>\n" +"\n" +"</div>\n" +" " #. module: account_followup #: view:account_followup.stat.by.partner:0 @@ -209,17 +263,17 @@ msgstr "Tartozik összesen" #. module: account_followup #: field:res.partner,payment_next_action:0 msgid "Next Action" -msgstr "" +msgstr "Következő művelet" #. module: account_followup #: view:account_followup.followup.line:0 msgid ": Partner Name" -msgstr "" +msgstr ": Partner neve" #. module: account_followup #: field:account_followup.followup.line,manual_action_responsible_id:0 msgid "Assign a Responsible" -msgstr "" +msgstr "Jelöljön ki egy felelőst" #. module: account_followup #: view:account_followup.followup:0 @@ -255,6 +309,16 @@ msgid "" " same customer, the actions of the most \n" " overdue invoice will be executed." msgstr "" +"Egy vevő kifizetetlen számlájának emlékeztetésére,\n" +" meghatározhat különböző műveleteket a vevő késedel-\n" +" métől függően. Ezek a műveletek fizetési-emlékeztető " +"szintekbe\n" +" csoportosítottak, melyek a számla fizetési határidő " +"dátumától\n" +" számított bizonyos napokon lesznek kapcsolva.\n" +" Ha több lejárt számlája is van ugyanannak a \n" +" vevőnek, akkor a leghosszabb nappal lejárt művelet \n" +" lesz elvégezve." #. module: account_followup #: report:account_followup.followup.print:0 @@ -269,7 +333,7 @@ msgstr "Partnerek" #. module: account_followup #: sql_constraint:account_followup.followup:0 msgid "Only one follow-up per company is allowed" -msgstr "" +msgstr "Vállalatonként csak egy fizetési-emlékeztető engedélyezett" #. module: account_followup #: code:addons/account_followup/wizard/account_followup_print.py:254 @@ -280,12 +344,12 @@ msgstr "Fizetési emlékeztető" #. module: account_followup #: help:account_followup.followup.line,send_letter:0 msgid "When processing, it will print a letter" -msgstr "" +msgstr "Ha el lesz végeve, akkor levelet fog nyomtatni" #. module: account_followup #: field:res.partner,payment_earliest_due_date:0 msgid "Worst Due Date" -msgstr "" +msgstr "Legroszabb leghoszabb lejárati idő" #. module: account_followup #: view:account_followup.stat:0 @@ -295,17 +359,17 @@ msgstr "Nem peresített" #. module: account_followup #: view:account_followup.print:0 msgid "Send emails and generate letters" -msgstr "" +msgstr "Küldjön e-mail-t és hozzon létre levelet" #. module: account_followup #: model:ir.actions.act_window,name:account_followup.action_customer_followup msgid "Manual Follow-Ups" -msgstr "" +msgstr "Kézi fizetési-emlékeztető" #. module: account_followup #: view:account_followup.followup.line:0 msgid "%(partner_name)s" -msgstr "" +msgstr "%(partner_name)s" #. module: account_followup #: model:email.template,body_html:account_followup.email_template_account_followup_level1 @@ -347,6 +411,40 @@ msgid "" "</div>\n" " " msgstr "" +"\n" +"<div style=\"font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-" +"serif; font-size: 12px; color: rgb(34, 34, 34); background-color: rgb(255, " +"255, 255); \">\n" +" \n" +" <p>Dear ${object.name},</p>\n" +" <p>\n" +" Csalódottan vettük tudomásul, és ezért fizetési-emlékeztetőt vagyunk " +"kénytelenek küldeni, mivel a számlája már régebben esedékessé vált.Fontos, " +"hogy azonnal fizessenek, egyéb esetben kénytelenek vagyunk elbírálni a " +"számlájuk lezárását, ami azzal jár, hogy nem leszünk képesek időben " +"szállítani az Önök vállalakozásának (termékeket/szolgáltatásokat).\n" +"Kérjük Önöket a fizetés 8 napon belüli pontos teljesítésére.\n" +"Ha a fizetéssel kapcsolatban probléma merült fel, amit mi nem vettünk " +"figyelembe, akkor kérjük vegyék fel a könyvelési csoportunkkal a " +"kapcsolatot, hogy elháríthassuk azt amilyen gyorsan csak lehet.\n" +"A lejárt számlák részleteit lentebb találják.\n" +" </p>\n" +"<br/>\n" +"Üdvözlettel,\n" +" \n" +"<br/>\n" +"<br/>\n" +"${user.name}\n" +" \n" +"<br/>\n" +"<br/>\n" +"\n" +"${object.get_followup_table_html() | safe}\n" +"\n" +" <br/>\n" +"\n" +"</div>\n" +" " #. module: account_followup #: field:account_followup.stat,debit:0 @@ -356,49 +454,49 @@ msgstr "Tartozik" #. module: account_followup #: model:ir.model,name:account_followup.model_account_followup_stat msgid "Follow-up Statistics" -msgstr "" +msgstr "Fizetési-emlékeztető statisztikák" #. module: account_followup #: view:res.partner:0 msgid "Send Overdue Email" -msgstr "" +msgstr "Lejárt dátumú fizetésről e-mail emlékeztető küldése" #. module: account_followup #: model:ir.model,name:account_followup.model_account_followup_followup_line msgid "Follow-up Criteria" -msgstr "" +msgstr "Fizetési-emlékeztető kritériom" #. module: account_followup #: help:account_followup.followup.line,sequence:0 msgid "Gives the sequence order when displaying a list of follow-up lines." -msgstr "Megadja a fizetési emlékeztető sorok listázási sorrendjét." +msgstr "Megadja a fizetési-emlékeztető sorok listázási sorrendjét." #. module: account_followup #: code:addons/account_followup/wizard/account_followup_print.py:166 #, python-format msgid " will be sent" -msgstr "" +msgstr " el lesz küldve" #. module: account_followup #: view:account_followup.followup.line:0 msgid ": User's Company Name" -msgstr "" +msgstr ": Felhasználó vállalata neve" #. module: account_followup #: view:account_followup.followup.line:0 #: field:account_followup.followup.line,send_letter:0 msgid "Send a Letter" -msgstr "" +msgstr "Levél küldése" #. module: account_followup #: model:ir.actions.act_window,name:account_followup.action_account_followup_definition_form msgid "Payment Follow-ups" -msgstr "" +msgstr "fizetési-emlékeztetők kifizetése" #. module: account_followup #: field:account_followup.followup.line,delay:0 msgid "Due Days" -msgstr "" +msgstr "Határidő túllépése napokban" #. module: account_followup #: field:account.move.line,followup_line_id:0 @@ -414,12 +512,12 @@ msgstr "Legutolsó fizetési emlékeztető" #. module: account_followup #: model:ir.ui.menu,name:account_followup.menu_manual_reconcile_followup msgid "Reconcile Invoices & Payments" -msgstr "" +msgstr "Számlák & Fizetések párosítása" #. module: account_followup #: model:ir.ui.menu,name:account_followup.account_followup_s msgid "Do Manual Follow-Ups" -msgstr "" +msgstr "Kézi fizetési-emlékeztető elvégzése" #. module: account_followup #: report:account_followup.followup.print:0 @@ -429,17 +527,17 @@ msgstr "P." #. module: account_followup #: field:account_followup.print,email_conf:0 msgid "Send Email Confirmation" -msgstr "" +msgstr "E-mail megerősítés küldése" #. module: account_followup #: view:account_followup.stat:0 msgid "Follow-up Entries with period in current year" -msgstr "" +msgstr "Fizetési-emlékeztető bejegyzések a tárgyi évben" #. module: account_followup #: field:account_followup.stat.by.partner,date_followup:0 msgid "Latest follow-up" -msgstr "" +msgstr "Legutóbbi fizetési-emlékeztető" #. module: account_followup #: field:account_followup.print,partner_lang:0 @@ -450,12 +548,12 @@ msgstr "E-mail küldése a partner nyelvén" #: code:addons/account_followup/wizard/account_followup_print.py:169 #, python-format msgid " email(s) sent" -msgstr "" +msgstr " e-mail(ek) elküldve" #. module: account_followup #: model:ir.model,name:account_followup.model_account_followup_print msgid "Print Follow-up & Send Mail to Customers" -msgstr "" +msgstr "Fizetési-emlékeztető nyomtatása & E-mail küldése a vevők részére" #. module: account_followup #: field:account_followup.followup.line,description:0 @@ -466,12 +564,12 @@ msgstr "Kinyomtatott üzenet" #: code:addons/account_followup/wizard/account_followup_print.py:155 #, python-format msgid "Anybody" -msgstr "" +msgstr "Bárki" #. module: account_followup #: help:account_followup.followup.line,send_email:0 msgid "When processing, it will send an email" -msgstr "" +msgstr "végrehajtáskor egy e-mailt fog küldeni" #. module: account_followup #: view:account_followup.stat.by.partner:0 @@ -481,7 +579,7 @@ msgstr "Emlékeztetendő partner" #. module: account_followup #: view:res.partner:0 msgid "Print Overdue Payments" -msgstr "" +msgstr "Határidőn túli fizetések nyomtatása" #. module: account_followup #: field:account_followup.followup.line,followup_id:0 @@ -494,11 +592,12 @@ msgstr "Fizetési emlékeztetők" #, python-format msgid "Email not sent because of email address of partner not filled in" msgstr "" +"E-mail nem lett elküldve, mert a partner e-mail címe nem lett kitöltve" #. module: account_followup #: model:ir.model,name:account_followup.model_account_followup_followup msgid "Account Follow-up" -msgstr "" +msgstr "Fizetési-emlékeztető könyvelés" #. module: account_followup #: help:res.partner,payment_responsible_id:0 @@ -506,11 +605,13 @@ msgid "" "Optionally you can assign a user to this field, which will make him " "responsible for the action." msgstr "" +"Választhat felhasználót is erre a mezőre, ami felelőssé teszi erre a " +"műveletre." #. module: account_followup #: model:ir.model,name:account_followup.model_account_followup_sending_results msgid "Results from the sending of the different letters and emails" -msgstr "" +msgstr "A különböző levelek és e-mailek küldéséből származó eredmény" #. module: account_followup #: constraint:account_followup.followup.line:0 @@ -518,27 +619,29 @@ msgid "" "Your description is invalid, use the right legend or %% if you want to use " "the percent character." msgstr "" +"A leírása érvénytelen, használja a jobb oldali feliratot vagy %% ha akarja a " +"százalék karaktert használja." #. module: account_followup #: code:addons/account_followup/wizard/account_followup_print.py:172 #, python-format msgid " manual action(s) assigned:" -msgstr "" +msgstr " kézi művelet(ek) hozzárendelve:" #. module: account_followup #: view:res.partner:0 msgid "Search Partner" -msgstr "" +msgstr "Partner keresés" #. module: account_followup #: model:ir.ui.menu,name:account_followup.account_followup_print_menu msgid "Send Letters and Emails" -msgstr "" +msgstr "Levelek és E-mailek küldése" #. module: account_followup #: view:account_followup.followup:0 msgid "Search Follow-up" -msgstr "" +msgstr "Fizetési-emlékeztető keresése" #. module: account_followup #: view:res.partner:0 @@ -549,12 +652,12 @@ msgstr "" #: code:addons/account_followup/wizard/account_followup_print.py:237 #, python-format msgid "Send Letters and Emails: Actions Summary" -msgstr "" +msgstr "Levelek és E-mailek küldése: Műveletek összegzése" #. module: account_followup #: view:account_followup.print:0 msgid "or" -msgstr "" +msgstr "vagy" #. module: account_followup #: view:res.partner:0 @@ -562,21 +665,23 @@ msgid "" "If not specified by the latest follow-up level, it will send from the " "default email template" msgstr "" +"Ha nincs meghatározva a legutóbbi fizetési-emlékeztető szinttel, akkor az " +"alapértelmezett e-mail sablonnal lesz elküldve" #. module: account_followup #: sql_constraint:account_followup.followup.line:0 msgid "Days of the follow-up levels must be different" -msgstr "" +msgstr "A fizetési-emlékeztető szintek napjainak különbözőeknek kell lenniük" #. module: account_followup #: view:res.partner:0 msgid "Click to mark the action as done." -msgstr "" +msgstr "Kattintson a művelet elvégzésének jelülésére." #. module: account_followup #: model:ir.ui.menu,name:account_followup.menu_action_followup_stat_follow msgid "Follow-Ups Analysis" -msgstr "" +msgstr "Fizetési-emlékeztető elemzések" #. module: account_followup #: help:res.partner,payment_next_action_date:0 @@ -586,11 +691,16 @@ msgid "" "action. Can be practical to set manually e.g. to see if he keeps his " "promises." msgstr "" +"Ez az amikor kézi fizetési-emlékeztető szükséges. A mai nap lesz beállítva, " +"ha a partner egy olyan fizetési-emlékeztető szintet kap ami kézi " +"beavatkozást igényel. Praktikus lehet kézire állítani pl. megfigyelni, hogy " +"betartja-e a szavát." #. module: account_followup #: view:res.partner:0 msgid "Print overdue payments report independent of follow-up line" msgstr "" +"fizetési-emlékeztető soroktól független lejárt fizetési tételek nyomtatása" #. module: account_followup #: help:account_followup.print,date:0 @@ -609,7 +719,7 @@ msgstr "Fizetési emlékeztető küldés időpontja" #: view:res.partner:0 #: field:res.partner,payment_responsible_id:0 msgid "Follow-up Responsible" -msgstr "" +msgstr "Fizetési-emlékeztető felelőse" #. module: account_followup #: model:email.template,body_html:account_followup.email_template_account_followup_level2 @@ -646,6 +756,37 @@ msgid "" "</div>\n" " " msgstr "" +"\n" +"<div style=\"font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-" +"serif; font-size: 12px; color: rgb(34, 34, 34); background-color: rgb(255, " +"255, 255); \">\n" +" \n" +" <p>Dear ${object.name},</p>\n" +" <p>\n" +" A többszörös fizetési-emlékeztető ellenére, még mindig nem történt meg a " +"számla kiegyenlítése.\n" +"Ha nem történik meg a kiegyenlítés 8 napon belül, törvényes úton vagyunk " +"kénytelenek az adósságot behajtani, minden további felszólítás nélkül.\n" +"Úgy gondoljuk, hogy ez nem lesz szükséges lépés a lenti részletekkel " +"kapcsolatban.\n" +"Az üggyel kapcsolatban felmerült kérdésekben, kérjük vegyék fel a " +"kapcsolatot a könyvelési csoportunkkal.\n" +"</p>\n" +"<br/>\n" +"Tisztelttel,\n" +"<br/>\n" +"<br/>\n" +"${user.name}\n" +"<br/>\n" +"<br/>\n" +"\n" +"\n" +"${object.get_followup_table_html() | safe}\n" +"\n" +" <br/>\n" +"\n" +"</div>\n" +" " #. module: account_followup #: report:account_followup.followup.print:0 @@ -655,7 +796,7 @@ msgstr "Bizonylat: vevő folyószámla kivonat" #. module: account_followup #: model:ir.ui.menu,name:account_followup.account_followup_menu msgid "Follow-up Levels" -msgstr "" +msgstr "Fizetési-emlékeztető szintek" #. module: account_followup #: model:account_followup.followup.line,description:account_followup.demo_followup_line4 @@ -678,40 +819,54 @@ msgid "" "Best Regards,\n" " " msgstr "" +"\n" +"Tisztelt %(partner_name)s,\n" +"\n" +"A többszörös fizetési-emlékeztető ellenére, még mindig nem történt meg a " +"számla kiegyenlítése.\n" +"Ha nem történik meg a kiegyenlítés 8 napon belül, törvényes úton vagyunk " +"kénytelenek az adósságot behajtani, minden további felszólítás nélkül.\n" +"Úgy gondoljuk, hogy ez nem lesz szükséges lépés a lenti részletekkel " +"kapcsolatban.\n" +"Az üggyel kapcsolatban felmerült kérdésekben, kérjük vegyék fel a " +"kapcsolatot a könyvelési csoportunkkal.\n" +"\n" +"Üdvözlettel,\n" +" " #. module: account_followup #: field:res.partner,payment_amount_due:0 msgid "Amount Due" -msgstr "" +msgstr "Esedékes összeg" #. module: account_followup #: field:account.move.line,followup_date:0 msgid "Latest Follow-up" -msgstr "Legutolsó fizetési emlékeztető" +msgstr "Legutobbi fizetési emlékeztető" #. module: account_followup #: view:account_followup.sending.results:0 msgid "Download Letters" -msgstr "" +msgstr "Levelek letöltése" #. module: account_followup #: field:account_followup.print,company_id:0 #: field:res.partner,unreconciled_aml_ids:0 msgid "unknown" -msgstr "" +msgstr "ismeretlen" #. module: account_followup #: code:addons/account_followup/account_followup.py:314 #, python-format msgid "Printed overdue payments report" -msgstr "" +msgstr "Lejárt fizetési tételek jelentésének nyomtatása" #. module: account_followup #: help:account_followup.followup.line,manual_action:0 msgid "" "When processing, it will set the manual action to be taken for that " "customer. " -msgstr "" +msgstr "Végrehajtáskor, a vevőhöz a kézi műveletet fogja beállítani. " #. module: account_followup #: view:res.partner:0 @@ -721,18 +876,25 @@ msgid "" " order to exclude it from the next follow-up " "actions." msgstr "" +"Alább a vevő ügyleteinek története.\n" +" Ellenőrizheti a \"Nincs fizetési-emlékeztető\" " +"soron\n" +" a következő fizetési-emlékeztető műveletekből " +"való kizárását." #. module: account_followup #: code:addons/account_followup/wizard/account_followup_print.py:171 #, python-format msgid " email(s) should have been sent, but " -msgstr "" +msgstr " ki kellett volna küldeni az e-mail(ek)t, de " #. module: account_followup #: help:account_followup.print,test_print:0 msgid "" "Check if you want to print follow-ups without changing follow-ups level." msgstr "" +"Ellenőrizze, hogy a fizetési-emlékeztető szintek változtatása nélkül " +"szeretné a fizetési-emlékeztetők nyomtatást." #. module: account_followup #: model:ir.model,name:account_followup.model_account_move_line @@ -742,12 +904,12 @@ msgstr "Könyvelési tételsorok" #. module: account_followup #: report:account_followup.followup.print:0 msgid "Total:" -msgstr "" +msgstr "Összesen:" #. module: account_followup #: field:account_followup.followup.line,email_template_id:0 msgid "Email Template" -msgstr "" +msgstr "E-mail sablon" #. module: account_followup #: field:account_followup.print,summary:0 @@ -758,7 +920,7 @@ msgstr "Összegzés" #: view:account_followup.followup.line:0 #: field:account_followup.followup.line,send_email:0 msgid "Send an Email" -msgstr "" +msgstr "Egy E-amil küldése" #. module: account_followup #: field:account_followup.stat,credit:0 @@ -768,7 +930,7 @@ msgstr "Követel" #. module: account_followup #: field:res.partner,payment_amount_overdue:0 msgid "Amount Overdue" -msgstr "" +msgstr "Lejárt összeg" #. module: account_followup #: help:res.partner,latest_followup_level_id_without_lit:0 @@ -776,12 +938,14 @@ msgid "" "The maximum follow-up level without taking into account the account move " "lines with litigation" msgstr "" +"A maximum fizetési-emlékeztető szint ami megtehető anélkül, hogy az ne " +"kerüljön peres eléjárásra" #. module: account_followup #: view:account_followup.stat:0 #: field:res.partner,latest_followup_date:0 msgid "Latest Follow-up Date" -msgstr "" +msgstr "Legutóbbi fizetési-emlékeztető dátuma." #. module: account_followup #: model:email.template,body_html:account_followup.email_template_account_followup_default @@ -814,6 +978,34 @@ msgid "" "</div>\n" " " msgstr "" +"\n" +"<div style=\"font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-" +"serif; font-size: 12px; color: rgb(34, 34, 34); background-color: rgb(255, " +"255, 255); \">\n" +" \n" +" <p>Tisztelt ${object.name},</p>\n" +" <p>\n" +" Ha időközben kiegyenlítésre került, vagy a mi hibánkból adódóan téves, " +"akkor tárgytalan, \n" +"de adataink szerint a következő tétel kifizetés nélkül maradt. \n" +"Kérjük Önöket a fizetés 8 napon belüli pontos teljesítésére.\n" +"Ha a levél elküldése előtt a fizetés már megtörtént akkor kérjük tekintsék " +"ezt tárgytalannak. Kérjük vegyék fel a kapcsolatot könyvelési " +"csoportunkkal. \n" +" </p>\n" +"<br/>\n" +"Üdvözlettel,\n" +"<br/>\n" +"<br/>\n" +"${user.name}\n" +"<br/>\n" +"<br/>\n" +"\n" +"${object.get_followup_table_html() | safe}\n" +"\n" +"<br/>\n" +"</div>\n" +" " #. module: account_followup #: field:account.move.line,result:0 @@ -826,17 +1018,17 @@ msgstr "Egyenleg" #. module: account_followup #: help:res.partner,payment_note:0 msgid "Payment Note" -msgstr "" +msgstr "Megjegyzés a fizetéshez" #. module: account_followup #: view:res.partner:0 msgid "My Follow-ups" -msgstr "" +msgstr "Fizetési-emlékeztetőim" #. module: account_followup #: view:account_followup.followup.line:0 msgid "%(company_name)s" -msgstr "" +msgstr "%(company_name)s" #. module: account_followup #: model:account_followup.followup.line,description:account_followup.demo_followup_line1 @@ -854,6 +1046,18 @@ msgid "" "\n" "Best Regards,\n" msgstr "" +"\n" +"Dear %(partner_name)s,\n" +"\n" +" Ha időközben kiegyenlítésre került, vagy a mi hibánkból adódóan téves, " +"akkor tárgytalan, de adataink szerint a következő tétel kifizetés nélkül " +"maradt. Kérjük Önöket a fizetés 8 napon belüli pontos teljesítésére.\n" +"\n" +"Ha a levél elküldése előtt a fizetés már megtörtént akkor kérjük tekintsék " +"ezt tárgytalannak. Kérjük vegyék fel a kapcsolatot könyvelési " +"csoportunkkal. \n" +"\n" +"Üdvözlettel,\n" #. module: account_followup #: field:account_followup.stat,date_move_last:0 @@ -870,12 +1074,12 @@ msgstr "Időszak" #: code:addons/account_followup/wizard/account_followup_print.py:228 #, python-format msgid "%s partners have no credits and as such the action is cleared" -msgstr "" +msgstr "%s a partnernek nincs hitele azért a művelet törölve lett" #. module: account_followup #: model:ir.actions.report.xml,name:account_followup.account_followup_followup_report msgid "Follow-up Report" -msgstr "" +msgstr "Fizetési-emlékeztető jelentés" #. module: account_followup #: view:res.partner:0 @@ -883,6 +1087,8 @@ msgid "" ", the latest payment follow-up\n" " was:" msgstr "" +", a legutóbbi fizetési-emlékeztető kifizetés\n" +" ez volt:" #. module: account_followup #: view:account_followup.print:0 @@ -892,7 +1098,7 @@ msgstr "Mégse" #. module: account_followup #: view:account_followup.sending.results:0 msgid "Close" -msgstr "" +msgstr "Lezár" #. module: account_followup #: view:account_followup.stat:0 @@ -908,23 +1114,23 @@ msgstr "Maximális fizetési emlékeztető szint" #: code:addons/account_followup/wizard/account_followup_print.py:171 #, python-format msgid " had unknown email address(es)" -msgstr "" +msgstr " ismeretlen e-mail címe(i) van(nak)" #. module: account_followup #: view:res.partner:0 msgid "Responsible" -msgstr "" +msgstr "Felelős" #. module: account_followup #: model:ir.ui.menu,name:account_followup.menu_finance_followup #: view:res.partner:0 msgid "Payment Follow-up" -msgstr "" +msgstr "Fizetési-emlékeztető kifizetés" #. module: account_followup #: view:account_followup.followup.line:0 msgid ": Current Date" -msgstr "" +msgstr ": Jelenlegi dátum" #. module: account_followup #: view:account_followup.print:0 @@ -933,16 +1139,20 @@ msgid "" " set the manual actions per customer, according to " "the follow-up levels defined." msgstr "" +"Ez a művelet fizetési-emlékeztető e-mail küldéseket indít, levelet nyomtat " +"és\n" +" beállítja a vevőnkénti kézi műveletet, a fizetési-" +"emlékeztető szintek beállításának megfelelően." #. module: account_followup #: field:account_followup.followup.line,name:0 msgid "Follow-Up Action" -msgstr "" +msgstr "Fizetési-emlékeztető művelet" #. module: account_followup #: view:account_followup.stat:0 msgid "Including journal entries marked as a litigation" -msgstr "" +msgstr "Beleértve a peres megjelölésű jelentés bejegyzéseket" #. module: account_followup #: report:account_followup.followup.print:0 @@ -955,7 +1165,7 @@ msgstr "Megjegyzés" #. module: account_followup #: view:account_followup.sending.results:0 msgid "Summary of actions" -msgstr "" +msgstr "Műveletek összegzése" #. module: account_followup #: report:account_followup.followup.print:0 @@ -965,7 +1175,7 @@ msgstr "Hiv." #. module: account_followup #: view:account_followup.followup.line:0 msgid "After" -msgstr "" +msgstr "Utána" #. module: account_followup #: view:account_followup.stat:0 @@ -975,7 +1185,7 @@ msgstr "Tárgyév" #. module: account_followup #: field:res.partner,latest_followup_level_id_without_lit:0 msgid "Latest Follow-up Level without litigation" -msgstr "" +msgstr "Legitóbbi per nélküli fizetési-emlékeztetőt szint" #. module: account_followup #: model:ir.actions.act_window,help:account_followup.action_account_manual_reconcile_receivable @@ -985,6 +1195,10 @@ msgid "" " </p>\n" " " msgstr "" +"<p>\n" +" Nem talált jelentés tartalmat.\n" +" </p>\n" +" " #. module: account_followup #: view:account.move.line:0 @@ -994,7 +1208,7 @@ msgstr "Partner tételek" #. module: account_followup #: view:account_followup.stat:0 msgid "Follow-up lines" -msgstr "" +msgstr "Fizetési emlékeztető sorok" #. module: account_followup #: model:account_followup.followup.line,description:account_followup.demo_followup_line3 @@ -1015,6 +1229,21 @@ msgid "" "\n" "Best Regards,\n" msgstr "" +"\n" +"Tisztelt %(partner_name)s,\n" +"\n" +" A többszörös fizetési-emlékeztető ellenére, még mindig nem történt meg a " +"számla kiegyenlítése.\n" +"Ha nem történik meg a kiegyenlítés 8 napon belül, törvényes úton vagyunk " +"kénytelenek az adósságot behajtani, minden további felszólítás nélkül.\n" +"\n" +"Úgy gondoljuk, hogy ez nem lesz szükséges lépés a lenti részletekkel " +"kapcsolatban.\n" +"\n" +"Az üggyel kapcsolatban felmerült kérdésekben, kérjük vegyék fel a " +"kapcsolatot a könyvelési csoportunkkal.\n" +"\n" +"Üdvözlettel,\n" #. module: account_followup #: help:account_followup.print,partner_lang:0 @@ -1036,6 +1265,13 @@ msgid "" "installed\n" " using to top right icon." msgstr "" +"Írja ide ennek a levélnek a levél bemutatását,\n" +" a fizetési-emlékeztető szint szerint. " +"Használhatóak a\n" +" következő kulcsszavak a szövegben. Meg kell " +"lennie\n" +" az összes jobb felső ikon szerinti nyelv " +"fordításban is!" #. module: account_followup #: view:account_followup.stat:0 @@ -1051,7 +1287,7 @@ msgstr "Név" #. module: account_followup #: field:res.partner,latest_followup_level_id:0 msgid "Latest Follow-up Level" -msgstr "" +msgstr "Legitóbbi fizetési-emlékeztető szint" #. module: account_followup #: field:account_followup.stat,date_move:0 @@ -1062,23 +1298,23 @@ msgstr "Első tétel" #. module: account_followup #: model:ir.model,name:account_followup.model_account_followup_stat_by_partner msgid "Follow-up Statistics by Partner" -msgstr "" +msgstr "Fizetési-emlékeztető partnerenkénti statisztika" #. module: account_followup #: code:addons/account_followup/wizard/account_followup_print.py:172 #, python-format msgid " letter(s) in report" -msgstr "" +msgstr " level(ek) a jelentésben" #. module: account_followup #: view:res.partner:0 msgid "Partners with Overdue Credits" -msgstr "" +msgstr "Lejárt fizetési hitelekkel rendelkező partnerek" #. module: account_followup #: view:res.partner:0 msgid "Customer Followup" -msgstr "" +msgstr "Vevői fizetési-emlékeztető" #. module: account_followup #: model:ir.actions.act_window,help:account_followup.action_account_followup_definition_form @@ -1094,22 +1330,33 @@ msgid "" " </p>\n" " " msgstr "" +"<p class=\"oe_view_nocontent_create\">\n" +" Kattintson a fizetési-emlékeztető szint és műveletének " +"létrehozásához.\n" +" </p><p>\n" +" Minden lépéshez, határozza meg a műveletet amit a lejárat " +"után annyi nappal el fog végezni.\n" +" Lehetséges nyomtatás és e-mail sablon használatával egy " +"üzenet eljuttatása a vevő\n" +" részére.\n" +" </p>\n" +" " #. module: account_followup #: code:addons/account_followup/wizard/account_followup_print.py:166 #, python-format msgid "Follow-up letter of " -msgstr "" +msgstr "Fizetési-emlékeztető levél ide " #. module: account_followup #: view:res.partner:0 msgid "The" -msgstr "" +msgstr "A" #. module: account_followup #: view:account_followup.print:0 msgid "Send follow-ups" -msgstr "" +msgstr "Fizetési-emlékeztető küldése" #. module: account_followup #: view:account.move.line:0 @@ -1124,7 +1371,7 @@ msgstr "Sorszám" #. module: account_followup #: view:res.partner:0 msgid "Follow-ups To Do" -msgstr "" +msgstr "Még végrehejtandó fizetési-emlékeztető" #. module: account_followup #: report:account_followup.followup.print:0 @@ -1143,26 +1390,30 @@ msgid "" "the reminder. Could be negative if you want to send a polite alert " "beforehand." msgstr "" +"A számla lejárati dátuma utáni napok száma, amíg várakozik a felszólítás " +"küldése előtt. Negatív is lehet, ha egy udvarias levelet szeretne küldeni a " +"lejárati dátumra vonatkozólag." #. module: account_followup #: help:res.partner,latest_followup_date:0 msgid "Latest date that the follow-up level of the partner was changed" msgstr "" +"Legutóbbi dátum amikor a vevőnek a fizetési-emlékeztető szintje változott" #. module: account_followup #: field:account_followup.print,test_print:0 msgid "Test Print" -msgstr "" +msgstr "Nyomtatás teszt" #. module: account_followup #: view:account_followup.followup.line:0 msgid ": User Name" -msgstr "" +msgstr ": Felhasználó neve" #. module: account_followup #: view:res.partner:0 msgid "Accounting" -msgstr "" +msgstr "Könyvelés" #. module: account_followup #: field:account_followup.stat,blocked:0 @@ -1172,7 +1423,7 @@ msgstr "Zárolt" #. module: account_followup #: field:res.partner,payment_note:0 msgid "Customer Payment Promise" -msgstr "" +msgstr "Vevő fizetésre vonatkozó igérete" #, python-format #~ msgid "Follwoup Summary" diff --git a/addons/account_voucher/i18n/hu.po b/addons/account_voucher/i18n/hu.po index 746ffe5b247..1a50a813042 100644 --- a/addons/account_voucher/i18n/hu.po +++ b/addons/account_voucher/i18n/hu.po @@ -7,19 +7,19 @@ 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-03-26 15:03+0000\n" +"PO-Revision-Date: 2013-04-04 11:34+0000\n" "Last-Translator: krnkris <Unknown>\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-27 04:36+0000\n" -"X-Generator: Launchpad (build 16540)\n" +"X-Launchpad-Export-Date: 2013-04-05 05:37+0000\n" +"X-Generator: Launchpad (build 16550)\n" #. module: account_voucher #: field:account.bank.statement.line,voucher_id:0 msgid "Reconciliation" -msgstr "" +msgstr "Párosítás" #. module: account_voucher #: model:ir.model,name:account_voucher.model_account_config_settings @@ -51,7 +51,7 @@ msgstr "Nyitott vevő tételek" #: view:account.voucher:0 #: view:sale.receipt.report:0 msgid "Group By..." -msgstr "Csoportosítás" +msgstr "Csoportosítás ezzel..." #. module: account_voucher #: help:account.voucher,writeoff_amount:0 @@ -102,7 +102,7 @@ msgstr "Számla kifizetése" #. module: account_voucher #: view:account.voucher:0 msgid "Are you sure you want to cancel this receipt?" -msgstr "" +msgstr "Biztos, hogy vissza akarja vonni ezt a bevételi bizonylatot?" #. module: account_voucher #: view:account.voucher:0 @@ -137,6 +137,8 @@ msgid "" "You can not change the journal as you already reconciled some statement " "lines!" msgstr "" +"Nem tudja a naplót megváltoztatni mivel a kivonatok egyes sorait már " +"párosította!" #. module: account_voucher #: view:account.voucher:0 @@ -160,6 +162,15 @@ msgid "" " </p>\n" " " msgstr "" +"<p class=\"oe_view_nocontent_create\">\n" +" Kattintson vásárlási bevételi bizonylat rögzítéséhez. \n" +" </p><p>\n" +" Ha a vásárlási bevételi bizonylat igazolva lett, rögzítheti " +"a \n" +" vásárlási bevételi bizonylathoz kapcsolódó beszállítói " +"kifizetést.\n" +" </p>\n" +" " #. module: account_voucher #: view:account.voucher:0 @@ -169,7 +180,7 @@ msgstr "Nyugták keresése" #. module: account_voucher #: field:account.voucher,writeoff_acc_id:0 msgid "Counterpart Account" -msgstr "" +msgstr "Ellenszámla" #. module: account_voucher #: field:account.voucher,account_id:0 @@ -191,7 +202,7 @@ msgstr "Rendben" #. module: account_voucher #: field:account.voucher.line,reconcile:0 msgid "Full Reconcile" -msgstr "" +msgstr "Teljes párosítás" #. module: account_voucher #: field:account.voucher,date_due:0 @@ -215,7 +226,7 @@ msgstr "Üzenetek" #: model:ir.actions.act_window,name:account_voucher.action_purchase_receipt #: model:ir.ui.menu,name:account_voucher.menu_action_purchase_receipt msgid "Purchase Receipts" -msgstr "" +msgstr "Vásárlások bevételi bizonylatai" #. module: account_voucher #: field:account.voucher.line,move_line_id:0 @@ -271,11 +282,18 @@ msgid "" " </p>\n" " " msgstr "" +"<p class=\"oe_view_nocontent_create\">\n" +" Kattintson értékesítési bevételi bizonylat létrehozásához.\n" +" </p><p>\n" +" Ha az értékesítési bizonylat igazolva lett, rögzítheti az \n" +" értékesítéshez tartozó vevői befizetést.\n" +" </p>\n" +" " #. module: account_voucher #: help:account.voucher,message_unread:0 msgid "If checked new messages require your attention." -msgstr "" +msgstr "Ha be van jelölve, akkor figyelje az új üzeneteket." #. module: account_voucher #: model:ir.model,name:account_voucher.model_account_bank_statement_line @@ -298,17 +316,17 @@ msgstr "ÁFA" #: code:addons/account_voucher/account_voucher.py:879 #, python-format msgid "Invalid Action!" -msgstr "" +msgstr "Érvénytelen lépés!" #. module: account_voucher #: field:account.voucher,comment:0 msgid "Counterpart Comment" -msgstr "" +msgstr "Ellenoldali meglyegyzés" #. module: account_voucher #: field:account.voucher.line,account_analytic_id:0 msgid "Analytic Account" -msgstr "Gyűjtőkód" +msgstr "Gyűjtő/elemző könyvelés" #. module: account_voucher #: help:account.voucher,message_summary:0 @@ -316,11 +334,13 @@ msgid "" "Holds the Chatter summary (number of messages, ...). This summary is " "directly in html format in order to be inserted in kanban views." msgstr "" +"A chettelés összegzést megállítja (üzenetek száma,...). Ez az összegzés " +"direkt HTML formátumú ahhoz hogy beilleszthető legyen a kanban nézetekbe." #. module: account_voucher #: view:account.voucher:0 msgid "Total Allocation" -msgstr "" +msgstr "Összes kiosztás" #. module: account_voucher #: view:account.voucher:0 @@ -330,7 +350,7 @@ msgstr "Fizetési információ" #. module: account_voucher #: view:account.voucher:0 msgid "(update)" -msgstr "" +msgstr "(frissítés)" #. module: account_voucher #: view:account.voucher:0 @@ -349,20 +369,20 @@ msgstr "Számlák importálása" #: code:addons/account_voucher/account_voucher.py:1112 #, python-format msgid "Wrong voucher line" -msgstr "Nem megfelelő nyugta sorok" +msgstr "Nem megfelelő nyugta sor" #. module: account_voucher #: selection:account.voucher,pay_now:0 #: selection:sale.receipt.report,pay_now:0 msgid "Pay Later or Group Funds" -msgstr "Későbbi fizetés" +msgstr "Fizessen később vagy csoportosítsa a pénzeket" #. module: account_voucher #: view:account.voucher:0 #: selection:account.voucher,type:0 #: selection:sale.receipt.report,type:0 msgid "Receipt" -msgstr "Befizetés" +msgstr "Bevételi bizonylat" #. module: account_voucher #: code:addons/account_voucher/account_voucher.py:1018 @@ -372,6 +392,9 @@ msgid "" "settings, to manage automatically the booking of accounting entries related " "to differences between exchange rates." msgstr "" +"Be kell állítani a 'Átváltási arány nyereség számlája' a könyvelés " +"beállításainál, ahhoz, hogy kezelni tudja az automatikus könyvelését azoknak " +"a számla tételeknek, melyek az átváltási arányok különbségéből adódhatnak." #. module: account_voucher #: view:account.voucher:0 @@ -399,7 +422,7 @@ msgstr "Szállítói nyugta" #. module: account_voucher #: field:account.voucher,message_follower_ids:0 msgid "Followers" -msgstr "" +msgstr "Követők" #. module: account_voucher #: selection:account.voucher.line,type:0 @@ -410,13 +433,13 @@ msgstr "Tartozik" #: code:addons/account_voucher/account_voucher.py:1547 #, python-format msgid "Unable to change journal !" -msgstr "" +msgstr "Naplót nem lehet megváltoztatni !" #. module: account_voucher #: view:sale.receipt.report:0 #: field:sale.receipt.report,nbr:0 msgid "# of Voucher Lines" -msgstr "Nyugtasorok száma" +msgstr "# nyugta sor száma" #. module: account_voucher #: view:sale.receipt.report:0 @@ -446,6 +469,13 @@ msgid "" " </p>\n" " " msgstr "" +"<p class=\"oe_view_nocontent_create\">\n" +" Kattintson új beszállítói fizetés létrehozásához.\n" +" </p><p>\n" +" OpenERP segít a kifizetéseinek, valamint a beszállítók " +"részére még fizetendő mérleg könnyű nyomon követéséhez.\n" +" </p>\n" +" " #. module: account_voucher #: view:account.voucher:0 @@ -460,12 +490,12 @@ msgstr "Nyugta tételek" #. module: account_voucher #: field:account.voucher,name:0 msgid "Memo" -msgstr "Megnevezés" +msgstr "Emlékeztető" #. module: account_voucher #: view:account.voucher:0 msgid "Are you sure to unreconcile and cancel this record ?" -msgstr "" +msgstr "Biztosan visszavonja a bejegyzés párosítását?" #. module: account_voucher #: field:account.voucher,is_multi_currency:0 @@ -494,17 +524,25 @@ msgid "" "\n" "* The 'Cancelled' status is used when user cancel voucher." msgstr "" +" * A 'Tervezet' állapotot használja amint egy felhasználó létrehoz egy új és " +"még le nem igazolt nyugtát. \n" +"* 'Pro-forma' lesz, ha a nyugta Pro-forma állapotú, a nyugtának még nincs " +"nyugta száma. \n" +"* 'Elküldött' állapotú, ha egy felhasználó létrehozta a nyugtát, egy nyugta " +"számot generált hozzá, és a könyvelésben egy nyugta bevitel létre lett hozva " +" \n" +"* A 'Visszavonva' állapot lesz, ha egy felhasználó visszavonta a nyugtát." #. module: account_voucher #: field:account.voucher,writeoff_amount:0 msgid "Difference Amount" -msgstr "" +msgstr "Különbség számla" #. module: account_voucher #: view:sale.receipt.report:0 #: field:sale.receipt.report,due_delay:0 msgid "Avg. Due Delay" -msgstr "Álagos fizetési határidő" +msgstr "Álagos fizetési késedelem" #. module: account_voucher #: code:addons/account_voucher/invoice.py:34 @@ -543,12 +581,24 @@ msgid "" " </p>\n" " " msgstr "" +"<p class=\"oe_view_nocontent_create\">\n" +" Kattintson új kifizetés rögzítéséhez. \n" +" </p><p>\n" +" Vigye be a vásárlót és a fizetési módot és utána, vagy " +"hozzon\n" +" létre kézzel egy fizetési rekordot, vagy az OpenERP fel fog " +"ajánlani\n" +" automatikusan a fizetéshez tartozó összeegyeztetést a\n" +" nyitott számlákkal vagy értékesítési bevételi " +"bizonylatokkal.\n" +" </p>\n" +" " #. module: account_voucher #: field:account.config.settings,expense_currency_exchange_account_id:0 #: field:res.company,expense_currency_exchange_account_id:0 msgid "Loss Exchange Rate Account" -msgstr "" +msgstr "Árfolyamveszteség számla" #. module: account_voucher #: view:account.voucher:0 @@ -572,7 +622,7 @@ msgstr "Ellenőrizendő" #: code:addons/account_voucher/account_voucher.py:1194 #, python-format msgid "change" -msgstr "" +msgstr "módosítás" #. module: account_voucher #: code:addons/account_voucher/account_voucher.py:1014 @@ -582,6 +632,9 @@ msgid "" "settings, to manage automatically the booking of accounting entries related " "to differences between exchange rates." msgstr "" +"Be kell állítani a 'Árfolyamveszteség számla' a könyvelés beállításoknál, " +"ahhoz, hogy kezelni tudja automatikusan a könyvelési tételek rögzítését, " +"melyek az átváltási árfolyam különbségekkel összefüggenek." #. module: account_voucher #: view:account.voucher:0 @@ -599,11 +652,13 @@ msgid "" "Fields with internal purpose only that depicts if the voucher is a multi " "currency one or not" msgstr "" +"Belső használatú mezők, melyek azt ábrázolják, hogy a nyugták több " +"pénzneműek vagy nem" #. module: account_voucher #: view:account.invoice:0 msgid "Register Payment" -msgstr "Kifizetés" +msgstr "Kifizetés rögzítés" #. module: account_voucher #: field:account.statement.from.invoice.lines,line_ids:0 @@ -618,7 +673,7 @@ msgstr "December" #. module: account_voucher #: view:sale.receipt.report:0 msgid "Group by month of Invoice Date" -msgstr "" +msgstr "Csoportosítás számla dátuma alapján" #. module: account_voucher #: view:sale.receipt.report:0 @@ -636,7 +691,7 @@ msgstr "Pénznem" #. module: account_voucher #: view:account.statement.from.invoice.lines:0 msgid "Payable and Receivables" -msgstr "Vevők és szállítók" +msgstr "Fizetendők & Bevételek" #. module: account_voucher #: view:account.voucher:0 @@ -651,7 +706,7 @@ msgstr "Nyugta állapota" #. module: account_voucher #: view:account.voucher:0 msgid "Are you sure to unreconcile this record?" -msgstr "" +msgstr "Biztosan törölni szeretné ennek a rekordnak a párosítását?" #. module: account_voucher #: field:account.voucher,company_id:0 @@ -664,18 +719,18 @@ msgstr "Vállalat" #. module: account_voucher #: help:account.voucher,paid:0 msgid "The Voucher has been totally paid." -msgstr "A nyugta ki lett egyenlítve" +msgstr "A nyugta teljesen ki lett egyenlítve" #. module: account_voucher #: selection:account.voucher,payment_option:0 msgid "Reconcile Payment Balance" -msgstr "" +msgstr "Fizetési egyenleg párosítás" #. module: account_voucher #: code:addons/account_voucher/account_voucher.py:975 #, python-format msgid "Configuration Error !" -msgstr "" +msgstr "Beállítási hiba!" #. module: account_voucher #: view:account.voucher:0 @@ -687,7 +742,7 @@ msgstr "Nyugta tervezetek" #: view:sale.receipt.report:0 #: field:sale.receipt.report,price_total_tax:0 msgid "Total With Tax" -msgstr "Bruttó érték" +msgstr "Bruttó érték adóval" #. module: account_voucher #: view:account.voucher:0 @@ -699,18 +754,18 @@ msgstr "Beszerzési nyugta" #: field:account.voucher,state:0 #: view:sale.receipt.report:0 msgid "Status" -msgstr "" +msgstr "Állapot" #. module: account_voucher #: view:account.voucher:0 msgid "Allocation" -msgstr "" +msgstr "Kiosztás" #. module: account_voucher #: view:account.statement.from.invoice.lines:0 #: view:account.voucher:0 msgid "or" -msgstr "" +msgstr "vagy" #. module: account_voucher #: selection:sale.receipt.report,month:0 @@ -720,7 +775,7 @@ msgstr "Augusztus" #. module: account_voucher #: view:account.voucher:0 msgid "Validate Payment" -msgstr "" +msgstr "Fizetés jóváhagyása" #. module: account_voucher #: help:account.voucher,audit:0 @@ -728,6 +783,8 @@ msgid "" "Check this box if you are unsure of that journal entry and if you want to " "note it as 'to be reviewed' by an accounting expert." msgstr "" +"Jelölje be, ha bizonytalan a napló tétel kontírozásában. Ennek hatására " +"könyvelő szekértő által 'ellenőrizendő'-ként jelölődik meg." #. module: account_voucher #: selection:sale.receipt.report,month:0 @@ -738,7 +795,7 @@ msgstr "Október" #: code:addons/account_voucher/account_voucher.py:976 #, python-format msgid "Please activate the sequence of selected journal !" -msgstr "" +msgstr "Kérem a sorozat aktiválását a kiválasztott naplóra !" #. module: account_voucher #: selection:sale.receipt.report,month:0 @@ -748,23 +805,23 @@ msgstr "Június" #. module: account_voucher #: field:account.voucher,payment_rate_currency_id:0 msgid "Payment Rate Currency" -msgstr "" +msgstr "Fizetési pénznem aránya" #. module: account_voucher #: field:account.voucher,paid:0 msgid "Paid" -msgstr "" +msgstr "Rendezett" #. module: account_voucher #: model:ir.actions.act_window,name:account_voucher.action_sale_receipt #: model:ir.ui.menu,name:account_voucher.menu_action_sale_receipt msgid "Sales Receipts" -msgstr "" +msgstr "Értékesítési bevételi bizonylatok" #. module: account_voucher #: field:account.voucher,message_is_follower:0 msgid "Is a Follower" -msgstr "" +msgstr "Ez egy követő" #. module: account_voucher #: field:account.voucher,analytic_id:0 @@ -791,7 +848,7 @@ msgstr "Kiterjesztett szűrők" #. module: account_voucher #: field:account.voucher,paid_amount_in_company_currency:0 msgid "Paid Amount in Company Currency" -msgstr "" +msgstr "Kifizetett összeg a vállalat pénznemében" #. module: account_voucher #: field:account.bank.statement.line,amount_reconciled:0 @@ -807,7 +864,7 @@ msgstr "Azonnali kifizetés" #. module: account_voucher #: field:account.voucher.line,type:0 msgid "Dr/Cr" -msgstr "" +msgstr "T/K" #. module: account_voucher #: field:account.voucher,pre_line:0 @@ -818,7 +875,7 @@ msgstr "Előző kifizetések ?" #: code:addons/account_voucher/account_voucher.py:1112 #, python-format msgid "The invoice you are willing to pay is not valid anymore." -msgstr "" +msgstr "A kifizetni kívánt számla már nem érvényes." #. module: account_voucher #: selection:sale.receipt.report,month:0 @@ -829,52 +886,52 @@ msgstr "Január" #: model:ir.actions.act_window,name:account_voucher.action_voucher_list #: model:ir.ui.menu,name:account_voucher.menu_encode_entries_by_voucher msgid "Journal Vouchers" -msgstr "Nyugták" +msgstr "Nyugták naplói" #. module: account_voucher #: model:ir.model,name:account_voucher.model_res_company msgid "Companies" -msgstr "" +msgstr "Vállalatok" #. module: account_voucher #: field:account.voucher,message_summary:0 msgid "Summary" -msgstr "" +msgstr "Összegzés" #. module: account_voucher #: field:account.voucher,active:0 msgid "Active" -msgstr "" +msgstr "Aktív" #. module: account_voucher #: code:addons/account_voucher/account_voucher.py:982 #, python-format msgid "Please define a sequence on the journal." -msgstr "" +msgstr "Kérem egy sorozat meghatározását a naplón." #. module: account_voucher #: model:ir.actions.act_window,name:account_voucher.act_pay_voucher #: model:ir.actions.act_window,name:account_voucher.action_vendor_receipt #: model:ir.ui.menu,name:account_voucher.menu_action_vendor_receipt msgid "Customer Payments" -msgstr "" +msgstr "Vevői befizetések" #. module: account_voucher #: model:ir.actions.act_window,name:account_voucher.action_sale_receipt_report_all #: model:ir.ui.menu,name:account_voucher.menu_action_sale_receipt_report_all #: view:sale.receipt.report:0 msgid "Sales Receipts Analysis" -msgstr "" +msgstr "Értékesítési bevételi bizonylatok elemzései" #. module: account_voucher #: view:sale.receipt.report:0 msgid "Group by Invoice Date" -msgstr "" +msgstr "Számla dátuma szerinti csoportosítása" #. module: account_voucher #: view:account.voucher:0 msgid "Post" -msgstr "Könyvelés" +msgstr "Elküld" #. module: account_voucher #: view:account.voucher:0 @@ -885,7 +942,7 @@ msgstr "Számlák és kifizetetlen tételek" #: view:sale.receipt.report:0 #: field:sale.receipt.report,price_total:0 msgid "Total Without Tax" -msgstr "Nettó érték" +msgstr "Nettó, adó nélküli érték" #. module: account_voucher #: view:account.voucher:0 @@ -921,7 +978,7 @@ msgstr "Bankkivonat" #. module: account_voucher #: view:account.bank.statement:0 msgid "onchange_amount(amount)" -msgstr "" +msgstr "onchange_amount(amount)" #. module: account_voucher #: selection:sale.receipt.report,month:0 @@ -954,19 +1011,19 @@ msgstr "Nyugta tételsorok" #: view:account.statement.from.invoice.lines:0 #: view:account.voucher:0 msgid "Cancel" -msgstr "Mégsem" +msgstr "Visszavonás" #. module: account_voucher #: model:ir.actions.client,name:account_voucher.action_client_invoice_menu msgid "Open Invoicing Menu" -msgstr "" +msgstr "Számlázási menü megnyitása" #. module: account_voucher #: selection:account.voucher,state:0 #: view:sale.receipt.report:0 #: selection:sale.receipt.report,state:0 msgid "Pro-forma" -msgstr "Pro forma" +msgstr "Pro-forma" #. module: account_voucher #: view:account.voucher:0 @@ -979,6 +1036,8 @@ msgstr "Könyvelési tételsorok" #, python-format msgid "Please define default credit/debit accounts on the journal \"%s\"." msgstr "" +"Kérem meghatározni az alapértelmezett követelés/tartozás könyvelést a naplón " +"\"%s\"." #. module: account_voucher #: selection:account.voucher,type:0 @@ -995,7 +1054,7 @@ msgstr "Fizetés" #. module: account_voucher #: view:account.voucher:0 msgid "Currency Options" -msgstr "" +msgstr "Pénznem lehetőségek" #. module: account_voucher #: help:account.voucher,payment_option:0 @@ -1005,6 +1064,10 @@ msgid "" "either choose to keep open this difference on the partner's account, or " "reconcile it with the payment(s)" msgstr "" +"Ez a mező megkönnyíti a választást ahhoz, hogy mit szeretne tenni a " +"kifizetett összeg és a kiosztott összeg közti különbségekkel. Hagyhatja " +"nyitottan ezt a különbséget a partner számláján, vagy párosíthatja a " +"fizetés(ek)el." #. module: account_voucher #: model:ir.actions.act_window,help:account_voucher.action_sale_receipt_report_all @@ -1018,16 +1081,24 @@ msgid "" " </p>\n" " " msgstr "" +"<p>\n" +" Erről a jelentésről, a vevőnek elküldött számlákról és fizetési\n" +" határidőkről és késve fizetésről áttekintést kaphat. A \n" +" keresési eszköz használható a számla beszámolók személyre\n" +" szabásához és így, az elemzést az igényének megfelelően " +"alakíthatja.\n" +" </p>\n" +" " #. module: account_voucher #: view:account.voucher:0 msgid "Posted Vouchers" -msgstr "" +msgstr "Elküldött nyugták" #. module: account_voucher #: field:account.voucher,payment_rate:0 msgid "Exchange Rate" -msgstr "" +msgstr "Árfolyam arány" #. module: account_voucher #: view:account.voucher:0 @@ -1047,7 +1118,7 @@ msgstr "Május" #. module: account_voucher #: view:account.voucher:0 msgid "Sale Receipt" -msgstr "" +msgstr "Értékesítési bevételi bizonylat" #. module: account_voucher #: view:account.voucher:0 @@ -1066,7 +1137,7 @@ msgstr "Belső megjegyzések" #: view:account.voucher:0 #: field:account.voucher,line_cr_ids:0 msgid "Credits" -msgstr "Követel" +msgstr "Követelések" #. module: account_voucher #: field:account.voucher.line,amount_original:0 @@ -1076,7 +1147,7 @@ msgstr "Eredeti összeg" #. module: account_voucher #: view:account.voucher:0 msgid "Purchase Receipt" -msgstr "" +msgstr "Vásárlási bevételi bizonylatok" #. module: account_voucher #: help:account.voucher,payment_rate:0 @@ -1084,6 +1155,8 @@ msgid "" "The specific rate that will be used, in this voucher, between the selected " "currency (in 'Payment Rate Currency' field) and the voucher currency." msgstr "" +"Az arány, mely ezen nyugtán lesz használva, a kiválasztott pénznem (a " +"'Fizetési pénznem aránya' mezőben) és a nyugta pénzneme közt." #. module: account_voucher #: view:account.voucher:0 @@ -1115,12 +1188,12 @@ msgstr "Február" #. module: account_voucher #: view:account.voucher:0 msgid "Supplier Invoices and Outstanding transactions" -msgstr "Bejövő számlák és kifizetetlen tételek" +msgstr "Beszállítók bejövő számlái és kifizetetlen tételek" #. module: account_voucher #: field:account.voucher,reference:0 msgid "Ref #" -msgstr "Hiv. szám" +msgstr "Hiv. szám #" #. module: account_voucher #: view:sale.receipt.report:0 @@ -1132,7 +1205,7 @@ msgstr "Év" #: field:account.config.settings,income_currency_exchange_account_id:0 #: field:res.company,income_currency_exchange_account_id:0 msgid "Gain Exchange Rate Account" -msgstr "" +msgstr "Árfolyamnyereség számla" #. module: account_voucher #: selection:account.voucher,type:0 @@ -1148,7 +1221,7 @@ msgstr "Április" #. module: account_voucher #: help:account.voucher,tax_id:0 msgid "Only for tax excluded from price" -msgstr "" +msgstr "Csak az árakból kihagyott adók" #. module: account_voucher #: field:account.voucher,type:0 @@ -1158,7 +1231,7 @@ msgstr "Alapértelmezett típus" #. module: account_voucher #: help:account.voucher,message_ids:0 msgid "Messages and communication history" -msgstr "" +msgstr "Üzenetek és kommunikációs történet" #. module: account_voucher #: model:ir.model,name:account_voucher.model_account_statement_from_invoice_lines @@ -1182,12 +1255,16 @@ msgid "" "The amount of the voucher must be the same amount as the one on the " "statement line." msgstr "" +"A nyugtán lévő összegnek ugyanannak kell lennie mint ami a kivonat sorában " +"szerepel." #. module: account_voucher #: code:addons/account_voucher/account_voucher.py:879 #, python-format msgid "Cannot delete voucher(s) which are already opened or paid." msgstr "" +"Nem lehet olyan nyugtá(ka)t törölni, melyek meg lettek nyitva vagy ki lettek " +"fozetve." #. module: account_voucher #: help:account.voucher,date:0 @@ -1197,7 +1274,7 @@ msgstr "Könyvelési tételek teljesítési dátuma" #. module: account_voucher #: model:mail.message.subtype,name:account_voucher.mt_voucher_state_change msgid "Status Change" -msgstr "" +msgstr "Állapotváltozás" #. module: account_voucher #: selection:account.voucher,payment_option:0 @@ -1225,7 +1302,7 @@ msgstr "Nettó érték" #. module: account_voucher #: model:ir.model,name:account_voucher.model_sale_receipt_report msgid "Sales Receipt Statistics" -msgstr "Értékesítési nyugta statisztika" +msgstr "Értékesítési bevételi bizonylatok statisztikái" #. module: account_voucher #: view:account.voucher:0 @@ -1244,14 +1321,14 @@ msgstr "Nyitott egyenleg" #. module: account_voucher #: model:mail.message.subtype,description:account_voucher.mt_voucher_state_change msgid "Status <b>changed</b>" -msgstr "" +msgstr "Állapot <b>megváltozott</b>" #. module: account_voucher #: code:addons/account_voucher/account_voucher.py:1014 #: code:addons/account_voucher/account_voucher.py:1018 #, python-format msgid "Insufficient Configuration!" -msgstr "" +msgstr "Nem megfelelő beállítás!" #. module: account_voucher #: help:account.voucher,active:0 @@ -1260,6 +1337,9 @@ msgid "" "inactive, which allow to hide the customer/supplier payment while the bank " "statement isn't confirmed." msgstr "" +"Alapértelmezetten, a tervezet bank kivonathoz párosított nyugták nem lesznek " +"aktívak, így el lehet tüntetni a vevő/beszállító fizetéseket amíg a banki " +"kivonatok nem kerülnek jóváhagyásra." #~ msgid "Particulars" #~ msgstr "Adatok" @@ -1310,9 +1390,6 @@ msgstr "" #~ msgid "Want to remove accounting entries too ?" #~ msgstr "A könyvelési tételeket is törölni szeretné?" -#~ msgid "Sales Receipt" -#~ msgstr "Nyugta" - #~ msgid "Unreconciliation" #~ msgstr "Párosítás visszavonása" @@ -1485,3 +1562,6 @@ msgstr "" #~ msgid "Canceled" #~ msgstr "Érvénytelenített" + +#~ msgid "Sales Receipt" +#~ msgstr "Értékesítési bevételi bizonylat" diff --git a/addons/auth_oauth/static/src/js/auth_oauth.js b/addons/auth_oauth/static/src/js/auth_oauth.js index 7ee83bd99e9..131ae5c1c42 100644 --- a/addons/auth_oauth/static/src/js/auth_oauth.js +++ b/addons/auth_oauth/static/src/js/auth_oauth.js @@ -5,6 +5,7 @@ openerp.auth_oauth = function(instance) { start: function(parent, params) { var self = this; var d = this._super.apply(this, arguments); + this.$el.hide(); this.$el.on('click', 'a.zocial', this.on_oauth_sign_in); this.oauth_providers = []; if(this.params.oauth_error === 1) { @@ -24,6 +25,8 @@ openerp.auth_oauth = function(instance) { var db = this.$("form [name=db]").val(); if (db) { this.rpc("/auth_oauth/list_providers", { dbname: db }).done(this.on_oauth_loaded); + } else { + this.$el.show(); } }, on_oauth_loaded: function(result) { @@ -32,6 +35,7 @@ openerp.auth_oauth = function(instance) { if (this.oauth_providers.length === 1 && params.type === 'signup') { this.do_oauth_sign_in(this.oauth_providers[0]); } else { + this.$el.show(); this.$('.oe_oauth_provider_login_button').remove(); var buttons = QWeb.render("auth_oauth.Login.button",{"widget":this}); this.$(".oe_login_pane form ul").after(buttons); @@ -57,7 +61,7 @@ openerp.auth_oauth = function(instance) { state: JSON.stringify(state), }; var url = provider.auth_endpoint + '?' + $.param(params); - window.location = url; + instance.web.redirect(url); }, _oauth_state: function(provider) { // return the state object sent back with the redirected uri diff --git a/addons/board/static/src/js/dashboard.js b/addons/board/static/src/js/dashboard.js index bd9625a4fa8..3489b686e1b 100644 --- a/addons/board/static/src/js/dashboard.js +++ b/addons/board/static/src/js/dashboard.js @@ -419,8 +419,10 @@ instance.board.AddToDashboard = instance.web.search.Input.extend({ instance.web.SearchView.include({ add_common_inputs: function() { this._super(); - (new instance.board.AddToDashboard(this)); - + var vm = this.getParent().getParent(); + if (vm.inner_action && vm.inner_action.views) { + (new instance.board.AddToDashboard(this)); + } } }); diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index 0dd075d48e6..64bad21ede1 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -103,16 +103,16 @@ Dashboard for CRM will include: 'crm_action_rule_demo.xml', ], 'test': [ - 'test/process/communication_with_customer.yml', - 'test/process/lead2opportunity2win.yml', - 'test/process/lead2opportunity_assign_salesmen.yml', - 'test/process/merge_opportunity.yml', - 'test/process/cancel_lead.yml', - 'test/process/segmentation.yml', - 'test/process/phonecalls.yml', - 'test/ui/crm_demo.yml', - 'test/ui/duplicate_lead.yml', - 'test/ui/delete_lead.yml', + 'test/crm_lead_message.yml', + 'test/lead2opportunity2win.yml', + 'test/lead2opportunity_assign_salesmen.yml', + 'test/crm_lead_merge.yml', + 'test/crm_lead_cancel.yml', + 'test/segmentation.yml', + 'test/phonecalls.yml', + 'test/crm_lead_onchange.yml', + 'test/crm_lead_copy.yml', + 'test/crm_lead_unlink.yml', ], 'installable': True, 'application': True, diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 56990f0e8f9..3f676329765 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -22,6 +22,7 @@ from openerp.addons.base_status.base_stage import base_stage import crm from datetime import datetime +from operator import itemgetter from openerp.osv import fields, osv import time from openerp import tools @@ -628,12 +629,13 @@ class crm_lead(base_stage, format_address, osv.osv): opportunities = self.browse(cr, uid, ids, context=context) sequenced_opps = [] for opportunity in opportunities: + sequence = -1 if opportunity.stage_id and opportunity.stage_id.state != 'cancel': - sequenced_opps.append((opportunity.stage_id.sequence, opportunity)) - else: - sequenced_opps.append((-1, opportunity)) - sequenced_opps.sort(key=lambda tup: tup[0], reverse=True) - opportunities = [opportunity for sequence, opportunity in sequenced_opps] + sequence = opportunity.stage_id.sequence + sequenced_opps.append(((int(sequence != -1 and opportunity.type == 'opportunity'), sequence, -opportunity.id), opportunity)) + + sequenced_opps.sort(reverse=True) + opportunities = map(itemgetter(1), sequenced_opps) ids = [opportunity.id for opportunity in opportunities] highest = opportunities[0] opportunities_rest = opportunities[1:] @@ -652,11 +654,10 @@ class crm_lead(base_stage, format_address, osv.osv): opportunities.extend(opportunities_rest) self._merge_notify(cr, uid, highest, opportunities, context=context) # Check if the stage is in the stages of the sales team. If not, assign the stage with the lowest sequence - if merged_data.get('type') == 'opportunity' and merged_data.get('section_id'): - section_stages = self.pool.get('crm.case.section').read(cr, uid, merged_data['section_id'], ['stage_ids'], context=context) - if merged_data.get('stage_id') not in section_stages['stage_ids']: - stages_sequences = self.pool.get('crm.case.stage').search(cr, uid, [('id','in',section_stages['stage_ids'])], order='sequence', limit=1, context=context) - merged_data['stage_id'] = stages_sequences and stages_sequences[0] or False + if merged_data.get('section_id'): + section_stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('section_ids', 'in', merged_data['section_id']), ('type', '=', merged_data.get('type'))], order='sequence', context=context) + if merged_data.get('stage_id') not in section_stage_ids: + merged_data['stage_id'] = section_stage_ids and section_stage_ids[0] or False # Write merged data into first opportunity self.write(cr, uid, [highest.id], merged_data, context=context) # Delete tail opportunities diff --git a/addons/crm/crm_lead_data.xml b/addons/crm/crm_lead_data.xml index 8ee352f25c0..e410cbe3d85 100644 --- a/addons/crm/crm_lead_data.xml +++ b/addons/crm/crm_lead_data.xml @@ -7,68 +7,68 @@ <field name="name">New</field> <field eval="1" name="case_default"/> <field name="state">draft</field> - <field eval="'10'" name="probability"/> - <field eval="'10'" name="sequence"/> + <field eval="0" name="probability"/> + <field eval="10" name="sequence"/> <field name="type">both</field> </record> <record model="crm.case.stage" id="stage_lead2"> <field name="name">Opportunity</field> <field eval="1" name="case_default"/> <field name="state">open</field> - <field eval="'20'" name="probability"/> - <field eval="'11'" name="sequence"/> + <field eval="20" name="probability"/> + <field eval="20" name="sequence"/> + <field name="type">lead</field> + </record> + <record model="crm.case.stage" id="stage_lead7"> + <field name="name">Dead</field> + <field eval="1" name="case_default"/> + <field eval="False" name="fold"/> + <field name="state">cancel</field> + <field eval="0" name="probability"/> + <field eval="30" name="sequence"/> <field name="type">lead</field> </record> <record model="crm.case.stage" id="stage_lead3"> <field name="name">Qualification</field> <field eval="1" name="case_default"/> <field name="state">open</field> - <field eval="'20'" name="probability"/> - <field eval="'12'" name="sequence"/> + <field eval="20" name="probability"/> + <field eval="100" name="sequence"/> <field name="type">opportunity</field> </record> <record model="crm.case.stage" id="stage_lead4"> <field name="name">Proposition</field> <field eval="1" name="case_default"/> <field name="state">open</field> - <field eval="'40'" name="probability"/> - <field eval="'13'" name="sequence"/> + <field eval="40" name="probability"/> + <field eval="110" name="sequence"/> <field name="type">opportunity</field> </record> <record model="crm.case.stage" id="stage_lead5"> <field name="name">Negotiation</field> <field eval="1" name="case_default"/> <field name="state">open</field> - <field eval="'60'" name="probability"/> - <field eval="'14'" name="sequence"/> + <field eval="60" name="probability"/> + <field eval="120" name="sequence"/> <field name="type">opportunity</field> </record> <record model="crm.case.stage" id="stage_lead6"> <field name="name">Won</field> <field eval="1" name="case_default"/> <field name="state">done</field> - <field eval="'100'" name="probability"/> - <field eval="'15'" name="sequence"/> + <field eval="100" name="probability"/> + <field eval="130" name="sequence"/> <field eval="1" name="on_change"/> <field name="type">opportunity</field> </record> - <record model="crm.case.stage" id="stage_lead7"> - <field name="name">Dead</field> - <field eval="1" name="case_default"/> - <field eval="False" name="fold"/> - <field name="state">cancel</field> - <field eval="'0'" name="probability"/> - <field eval="'16'" name="sequence"/> - <field name="type">lead</field> - </record> <record model="crm.case.stage" id="stage_lead8"> <field name="name">Lost</field> <field eval="1" name="case_default"/> <field eval="True" name="fold"/> <field eval="1" name="on_change"/> <field name="state">cancel</field> - <field eval="'0'" name="probability"/> - <field eval="'17'" name="sequence"/> + <field eval="0" name="probability"/> + <field eval="140" name="sequence"/> <field name="type">opportunity</field> </record> diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index df28d240a0c..894df92b70f 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -100,6 +100,7 @@ <button name="case_cancel" string="Cancel Case" type="object" states="draft,open,pending"/> <field name="stage_id" widget="statusbar" clickable="True" + domain="['&', '|', ('case_default', '=', True), ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]" on_change="onchange_stage_id(stage_id)"/> </header> <sheet> diff --git a/addons/crm/security/ir.model.access.csv b/addons/crm/security/ir.model.access.csv index 74394d3c5ce..52648c8e347 100644 --- a/addons/crm/security/ir.model.access.csv +++ b/addons/crm/security/ir.model.access.csv @@ -11,9 +11,7 @@ access_crm_lead_manager,crm.lead.manager,model_crm_lead,base.group_sale_manager, access_crm_phonecall_manager,crm.phonecall.manager,model_crm_phonecall,base.group_sale_manager,1,1,1,1
access_crm_case_categ,crm.case.categ,model_crm_case_categ,base.group_user,1,0,0,0
access_crm_lead,crm.lead,model_crm_lead,base.group_sale_salesman,1,1,1,0
-access_crm_lead_all,crm.lead.all,model_crm_lead,base.group_user,1,0,0,0
access_crm_phonecall,crm.phonecall,model_crm_phonecall,base.group_sale_salesman,1,1,1,0
-access_crm_phonecall_all,crm.phonecall.all,model_crm_phonecall,base.group_user,1,0,0,0
access_crm_case_section_user,crm.case.section.user,model_crm_case_section,base.group_sale_salesman,1,1,1,0
access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1
access_crm_case_stage,crm.case.stage,model_crm_case_stage,,1,0,0,0
diff --git a/addons/crm/test/process/cancel_lead.yml b/addons/crm/test/crm_lead_cancel.yml index edaf844952a..edaf844952a 100644 --- a/addons/crm/test/process/cancel_lead.yml +++ b/addons/crm/test/crm_lead_cancel.yml diff --git a/addons/crm/test/ui/duplicate_lead.yml b/addons/crm/test/crm_lead_copy.yml index b6071ae9f9d..b6071ae9f9d 100644 --- a/addons/crm/test/ui/duplicate_lead.yml +++ b/addons/crm/test/crm_lead_copy.yml diff --git a/addons/crm/test/process/merge_opportunity.yml b/addons/crm/test/crm_lead_merge.yml index c50af5214e6..b14f9272df9 100644 --- a/addons/crm/test/process/merge_opportunity.yml +++ b/addons/crm/test/crm_lead_merge.yml @@ -37,20 +37,19 @@ I check for the resulting merged opp (based on name and partner). - !python {model: crm.lead}: | - merge_id = self.search(cr, uid, [('name', '=', 'Test lead 1'), ('partner_id','=', ref("base.res_partner_1"))]) + merge_id = self.search(cr, uid, [('name', '=', 'Test opportunity 1'), ('partner_id','=', ref("base.res_partner_5"))]) assert merge_id, 'Fail to create merge opportunity wizard' merge_result = self.browse(cr, uid, merge_id)[0] - assert merge_result.partner_id.id == ref("base.res_partner_1"), 'Partner mismatch: when merging leads/opps with different m2o values, the first not null value prevails (the other are dropped)' - assert merge_result.description == 'This is the description of the test lead 1.\n\nThis is the description of the test lead 2.\n\nThis is the description of the test opp 1.', 'Description mismatch: when merging leads/opps with different text values, these values should get concatenated and separated with line returns' + assert merge_result.description == 'This is the description of the test opp 1.\n\nThis is the description of the test lead 1.\n\nThis is the description of the test lead 2.', 'Description mismatch: when merging leads/opps with different text values, these values should get concatenated and separated with line returns' assert merge_result.type == 'opportunity', 'Type mismatch: when at least one opp in involved in the merge, the result should be a new opp (instead of %s)' % merge_result.type - The other (tailing) leads/opps shouldn't exist anymore. - !python {model: crm.lead}: | - tailing_lead = self.search(cr, uid, [('id', '=', ref('test_crm_lead_02'))]) + tailing_lead = self.search(cr, uid, [('id', '=', ref('test_crm_lead_01'))]) assert not tailing_lead, 'This tailing lead (id %s) should not exist anymore' % ref('test_crm_lead_02') - tailing_opp = self.search(cr, uid, [('id', '=', ref('test_crm_opp_01'))]) + tailing_opp = self.search(cr, uid, [('id', '=', ref('test_crm_lead_02'))]) assert not tailing_opp, 'This tailing opp (id %s) should not exist anymore' % ref('test_crm_opp_01') - I want to test leads merge. Start by creating two leads (with the same partner). diff --git a/addons/crm/test/process/communication_with_customer.yml b/addons/crm/test/crm_lead_message.yml index 221a4ab634f..221a4ab634f 100644 --- a/addons/crm/test/process/communication_with_customer.yml +++ b/addons/crm/test/crm_lead_message.yml diff --git a/addons/crm/test/ui/crm_demo.yml b/addons/crm/test/crm_lead_onchange.yml index 9154ffdf513..9154ffdf513 100644 --- a/addons/crm/test/ui/crm_demo.yml +++ b/addons/crm/test/crm_lead_onchange.yml diff --git a/addons/crm/test/ui/delete_lead.yml b/addons/crm/test/crm_lead_unlink.yml index 49713039f22..49713039f22 100644 --- a/addons/crm/test/ui/delete_lead.yml +++ b/addons/crm/test/crm_lead_unlink.yml diff --git a/addons/crm/test/process/lead2opportunity2win.yml b/addons/crm/test/lead2opportunity2win.yml index 94e7149ef77..94e7149ef77 100644 --- a/addons/crm/test/process/lead2opportunity2win.yml +++ b/addons/crm/test/lead2opportunity2win.yml diff --git a/addons/crm/test/process/lead2opportunity_assign_salesmen.yml b/addons/crm/test/lead2opportunity_assign_salesmen.yml index 0edd3b8edce..0edd3b8edce 100644 --- a/addons/crm/test/process/lead2opportunity_assign_salesmen.yml +++ b/addons/crm/test/lead2opportunity_assign_salesmen.yml diff --git a/addons/crm/test/process/phonecalls.yml b/addons/crm/test/phonecalls.yml index 51a933f3223..51a933f3223 100644 --- a/addons/crm/test/process/phonecalls.yml +++ b/addons/crm/test/phonecalls.yml diff --git a/addons/crm/test/process/segmentation.yml b/addons/crm/test/segmentation.yml index f3801b80ec6..f3801b80ec6 100644 --- a/addons/crm/test/process/segmentation.yml +++ b/addons/crm/test/segmentation.yml diff --git a/addons/document/document_view.xml b/addons/document/document_view.xml index 68f294b251c..c3bd5ad3f56 100644 --- a/addons/document/document_view.xml +++ b/addons/document/document_view.xml @@ -258,7 +258,9 @@ name="Documents" action="action_document_file_form" id="menu_document_files" - parent="menu_document_doc"/> + parent="menu_document_doc" + sequence="0" + /> <record model="ir.actions.act_window" id="action_document_file_directory_form"> <field name="type">ir.actions.act_window</field> diff --git a/addons/document_ftp/ftpserver/abstracted_fs.py b/addons/document_ftp/ftpserver/abstracted_fs.py index a83843eb1a5..4a2d6e5e1ec 100644 --- a/addons/document_ftp/ftpserver/abstracted_fs.py +++ b/addons/document_ftp/ftpserver/abstracted_fs.py @@ -325,7 +325,7 @@ class abstracted_fs(object): """ Get cr, uid, pool from a node """ assert node - db = openerp.registry.(node.context.dbname).db + db = openerp.registry(node.context.dbname).db return db.cursor(), node.context.uid def get_node_cr(self, node): diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py index 15926336697..2177add8878 100644 --- a/addons/hr_expense/hr_expense.py +++ b/addons/hr_expense/hr_expense.py @@ -228,6 +228,8 @@ class hr_expense_expense(osv.osv): for exp in self.browse(cr, uid, ids, context=context): if not exp.employee_id.address_home_id: raise osv.except_osv(_('Error!'), _('The employee must have a home address.')) + if not exp.employee_id.address_home_id.property_account_payable.id: + raise osv.except_osv(_('Error!'), _('The employee must have a payable account set on his home address.')) company_currency = exp.company_id.currency_id.id diff_currency_p = exp.currency_id.id <> company_currency @@ -333,6 +335,8 @@ class hr_expense_expense(osv.osv): acc = line.product_id.property_account_expense if not acc: acc = line.product_id.categ_id.property_account_expense_categ + if not acc: + raise osv.except_osv(_('Error!'), _('No purchase account found for the product %s (or for his category), please configure one.') % (line.product_id.name)) else: acc = property_obj.get(cr, uid, 'property_account_expense_categ', 'product.category', context={'force_company': company.id}) if not acc: diff --git a/addons/hr_expense/hr_expense_view.xml b/addons/hr_expense/hr_expense_view.xml index 49ea2f0ab9e..eab24b06717 100644 --- a/addons/hr_expense/hr_expense_view.xml +++ b/addons/hr_expense/hr_expense_view.xml @@ -112,7 +112,7 @@ <field name="date_value" string="Expense Date"/> <field name="name"/> <field name="ref"/> - <field domain="[('type','in',['normal','contract']), ('parent_id','!=',False)]" name="analytic_account" groups="analytic.group_analytic_accounting"/> + <field domain="[('type','in',['normal','contract'])]" name="analytic_account" groups="analytic.group_analytic_accounting"/> <field name="uom_id" on_change="onchange_uom(product_id, uom_id, context)"/> <field name="unit_amount"/> <field name="unit_quantity"/> diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index 8c715149ff8..4e113a23510 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -184,6 +184,16 @@ class hr_holidays(osv.osv): ('date_check2', "CHECK ( (type='add') OR (date_from <= date_to))", "The start date must be anterior to the end date."), ('date_check', "CHECK ( number_of_days_temp >= 0 )", "The number of days must be greater than 0."), ] + + def copy(self, cr, uid, id, default=None, context=None): + if default is None: + default = {} + if context is None: + context = {} + default = default.copy() + default['date_from'] = False + default['date_to'] = False + return super(hr_holidays, self).copy(cr, uid, id, default, context=context) def _create_resource_leave(self, cr, uid, leaves, context=None): '''This method will create entry in resource calendar leave object at the time of holidays validated ''' diff --git a/addons/lunch/lunch.py b/addons/lunch/lunch.py index 9f18c391eec..efad6fd6944 100644 --- a/addons/lunch/lunch.py +++ b/addons/lunch/lunch.py @@ -169,7 +169,7 @@ class lunch_order(osv.Model): line_ref = self.pool.get("lunch.order.line") if view_type == 'form': doc = etree.XML(res['arch']) - pref_ids = line_ref.search(cr, uid, [('user_id', '=', uid)], order='create_date desc', context=context) + pref_ids = line_ref.search(cr, uid, [('user_id', '=', uid)], order='id desc', context=context) xml_start = etree.Element("div") #If there are no preference (it's the first time for the user) if len(pref_ids)==0: @@ -215,63 +215,70 @@ class lunch_order(osv.Model): currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id #For each preferences that we get, we will create the XML structure - for key,value in categories.items(): + for key, value in categories.items(): xml_pref_1 = etree.Element("div") - xml_pref_1.set('class','oe_lunch_30pc') + xml_pref_1.set('class', 'oe_lunch_30pc') xml_pref_2 = etree.Element("h2") xml_pref_2.text = key xml_pref_1.append(xml_pref_2) i = 0 value = value.values() + #TODO: sorted_values is used for a quick and dirty hack in order to display the 5 last orders of each categories. + #It would be better to fetch only the 5 items to display instead of fetching everything then sorting them in order to keep only the 5 last. + #NB: The note could also be ignored + we could fetch the preferences on the most ordered products instead of the last ones... + sorted_values = {} for val in value: - for pref in val.values(): - #We only show 5 preferences per category (or it will be too long) - if i==5: break - i+=1 - xml_pref_3 = etree.Element("div") - xml_pref_3.set('class','oe_lunch_vignette') - xml_pref_1.append(xml_pref_3) - - xml_pref_4 = etree.Element("span") - xml_pref_4.set('class','oe_lunch_button') - xml_pref_3.append(xml_pref_4) - - xml_pref_5 = etree.Element("button") - xml_pref_5.set('name',"add_preference_"+str(pref.id)) - xml_pref_5.set('class','oe_link oe_i oe_button_plus') - xml_pref_5.set('type','object') - xml_pref_5.set('string','+') - xml_pref_4.append(xml_pref_5) - - xml_pref_6 = etree.Element("button") - xml_pref_6.set('name',"add_preference_"+str(pref.id)) - xml_pref_6.set('class','oe_link oe_button_add') - xml_pref_6.set('type','object') - xml_pref_6.set('string',_("Add")) - xml_pref_4.append(xml_pref_6) - - xml_pref_7 = etree.Element("div") - xml_pref_7.set('class','oe_group_text_button') - xml_pref_3.append(xml_pref_7) - - xml_pref_8 = etree.Element("div") - xml_pref_8.set('class','oe_lunch_text') - xml_pref_8.text = escape(pref.product_id.name)+str(" ") - xml_pref_7.append(xml_pref_8) - - price = pref.product_id.price or 0.0 - cur = currency.name or '' - xml_pref_9 = etree.Element("span") - xml_pref_9.set('class','oe_tag') - xml_pref_9.text = str(price)+str(" ")+cur - xml_pref_8.append(xml_pref_9) - - xml_pref_10 = etree.Element("div") - xml_pref_10.set('class','oe_grey') - xml_pref_10.text = escape(pref.note or '') - xml_pref_3.append(xml_pref_10) - - xml_start.append(xml_pref_1) + for elmt in val.values(): + sorted_values[elmt.id] = elmt + for key, pref in sorted(sorted_values.iteritems(), key=lambda (k, v): (k, v), reverse=True): + #We only show 5 preferences per category (or it will be too long) + if i == 5: + break + i += 1 + xml_pref_3 = etree.Element("div") + xml_pref_3.set('class','oe_lunch_vignette') + xml_pref_1.append(xml_pref_3) + + xml_pref_4 = etree.Element("span") + xml_pref_4.set('class','oe_lunch_button') + xml_pref_3.append(xml_pref_4) + + xml_pref_5 = etree.Element("button") + xml_pref_5.set('name',"add_preference_"+str(pref.id)) + xml_pref_5.set('class','oe_link oe_i oe_button_plus') + xml_pref_5.set('type','object') + xml_pref_5.set('string','+') + xml_pref_4.append(xml_pref_5) + + xml_pref_6 = etree.Element("button") + xml_pref_6.set('name',"add_preference_"+str(pref.id)) + xml_pref_6.set('class','oe_link oe_button_add') + xml_pref_6.set('type','object') + xml_pref_6.set('string',_("Add")) + xml_pref_4.append(xml_pref_6) + + xml_pref_7 = etree.Element("div") + xml_pref_7.set('class','oe_group_text_button') + xml_pref_3.append(xml_pref_7) + + xml_pref_8 = etree.Element("div") + xml_pref_8.set('class','oe_lunch_text') + xml_pref_8.text = escape(pref.product_id.name)+str(" ") + xml_pref_7.append(xml_pref_8) + + price = pref.product_id.price or 0.0 + cur = currency.name or '' + xml_pref_9 = etree.Element("span") + xml_pref_9.set('class','oe_tag') + xml_pref_9.text = str(price)+str(" ")+cur + xml_pref_8.append(xml_pref_9) + + xml_pref_10 = etree.Element("div") + xml_pref_10.set('class','oe_grey') + xml_pref_10.text = escape(pref.note or '') + xml_pref_3.append(xml_pref_10) + + xml_start.append(xml_pref_1) first_node = doc.xpath("//div[@name='preferences']") if first_node and len(first_node)>0: diff --git a/addons/mail/mail_group.py b/addons/mail/mail_group.py index bb66c909ad6..93f363a740e 100644 --- a/addons/mail/mail_group.py +++ b/addons/mail/mail_group.py @@ -144,11 +144,19 @@ class mail_group(osv.Model): search_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'view_message_search') params = { 'search_view_id': search_ref and search_ref[1] or False, - 'domain': [('model', '=', 'mail.group'), ('res_id', '=', mail_group_id)], - 'context': {'default_model': 'mail.group', 'default_res_id': mail_group_id, 'search_default_message_unread': True}, + 'domain': [ + ('model', '=', 'mail.group'), + ('res_id', '=', mail_group_id), + ], + 'context': { + 'default_model': 'mail.group', + 'default_res_id': mail_group_id, + }, 'res_model': 'mail.message', 'thread_level': 1, - 'header_description': self._generate_header_description(cr, uid, group, context=context) + 'header_description': self._generate_header_description(cr, uid, group, context=context), + 'view_mailbox': True, + 'compose_placeholder': 'Send a message to the group', } cobj = self.pool.get('ir.actions.client') newref = cobj.copy(cr, SUPERUSER_ID, ref[1], default={'params': str(params), 'name': vals['name']}, context=context) diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml index 77c0b8f6c86..5ccee40d5c7 100644 --- a/addons/mail/mail_group_view.xml +++ b/addons/mail/mail_group_view.xml @@ -7,7 +7,6 @@ <field name="tag">mail.wall</field> <field name="res_model">mail.message</field> <field name="context">{ - 'search_default_message_unread': True }</field> <field name="params">{ 'read_action': 'read' diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py index c5a7e227465..ab2b6f3e922 100644 --- a/addons/mail/mail_mail.py +++ b/addons/mail/mail_mail.py @@ -256,7 +256,19 @@ class mail_mail(osv.Model): body = self.send_get_mail_body(cr, uid, mail, partner=partner, context=context) subject = self.send_get_mail_subject(cr, uid, mail, partner=partner, context=context) body_alternative = tools.html2plaintext(body) - email_to = ['%s <%s>' % (partner.name, partner.email)] if partner else tools.email_split(mail.email_to) + + # generate email_to, heuristic: + # 1. if 'partner' is specified and there is a related document: Followers of 'Doc' <email> + # 2. if 'partner' is specified, but no related document: Partner Name <email> + # 3; fallback on mail.email_to that we split to have an email addresses list + if partner and mail.record_name: + sanitized_record_name = re.sub(r'[^\w+.]+', '-', mail.record_name) + email_to = [_('"Followers of %s" <%s>') % (sanitized_record_name, partner.email)] + elif partner: + email_to = ['%s <%s>' % (partner.name, partner.email)] + else: + email_to = tools.email_split(mail.email_to) + return { 'body': body, 'body_alternative': body_alternative, diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 8442891f3f9..4f830b21e50 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -268,19 +268,25 @@ class mail_message(osv.Model): domain = [('partner_id', '=', user_pid), ('message_id', 'in', msg_ids)] if not create_missing: domain += [('starred', '=', not starred)] + values = { + 'starred': starred + } + if starred: + values['read'] = False + notif_ids = notification_obj.search(cr, uid, domain, context=context) # all message have notifications: already set them as (un)starred if len(notif_ids) == len(msg_ids) or not create_missing: - notification_obj.write(cr, uid, notif_ids, {'starred': starred}, context=context) + notification_obj.write(cr, uid, notif_ids, values, context=context) return starred # some messages do not have notifications: find which one, create notification, update starred status notified_msg_ids = [notification.message_id.id for notification in notification_obj.browse(cr, uid, notif_ids, context=context)] to_create_msg_ids = list(set(msg_ids) - set(notified_msg_ids)) for msg_id in to_create_msg_ids: - notification_obj.create(cr, uid, {'partner_id': user_pid, 'starred': starred, 'message_id': msg_id}, context=context) - notification_obj.write(cr, uid, notif_ids, {'starred': starred}, context=context) + notification_obj.create(cr, uid, dict(values, partner_id=user_pid, message_id=msg_id), context=context) + notification_obj.write(cr, uid, notif_ids, values, context=context) return starred #------------------------------------------------------ diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index aff451a9935..2527b4cf035 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -470,6 +470,8 @@ class mail_thread(osv.AbstractModel): """ assert isinstance(message, Message), 'message must be an email.message.Message at this point' message_id = message.get('Message-Id') + email_from = decode_header(message, 'From') + email_to = decode_header(message, 'To') references = decode_header(message, 'References') in_reply_to = decode_header(message, 'In-Reply-To') @@ -483,8 +485,8 @@ class mail_thread(osv.AbstractModel): model_pool = self.pool.get(model) if thread_id and model and model_pool and model_pool.exists(cr, uid, thread_id) \ and hasattr(model_pool, 'message_update'): - _logger.debug('Routing mail with Message-Id %s: direct reply to model: %s, thread_id: %s, custom_values: %s, uid: %s', - message_id, model, thread_id, custom_values, uid) + _logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to model: %s, thread_id: %s, custom_values: %s, uid: %s', + email_from, email_to, message_id, model, thread_id, custom_values, uid) return [(model, thread_id, custom_values, uid)] # Verify whether this is a reply to a private message @@ -495,8 +497,8 @@ class mail_thread(osv.AbstractModel): ], limit=1, context=context) if message_ids: message = self.pool.get('mail.message').browse(cr, uid, message_ids[0], context=context) - _logger.debug('Routing mail with Message-Id %s: direct reply to a private message: %s, custom_values: %s, uid: %s', - message_id, message.id, custom_values, uid) + _logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to a private message: %s, custom_values: %s, uid: %s', + email_from, email_to, message_id, message.id, custom_values, uid) return [(message.model, message.res_id, custom_values, uid)] # 2. Look for a matching mail.alias entry @@ -523,10 +525,11 @@ class mail_thread(osv.AbstractModel): # Note: recognized partners will be added as followers anyway # user_id = self._message_find_user_id(cr, uid, message, context=context) user_id = uid - _logger.debug('No matching user_id for the alias %s', alias.alias_name) + _logger.info('No matching user_id for the alias %s', alias.alias_name) routes.append((alias.alias_model_id.model, alias.alias_force_thread_id, \ eval(alias.alias_defaults), user_id)) - _logger.debug('Routing mail with Message-Id %s: direct alias match: %r', message_id, routes) + _logger.info('Routing mail from %s to %s with Message-Id %s: direct alias match: %r', + email_from, email_to, message_id, routes) return routes # 3. Fallback to the provided parameters, if they work @@ -541,14 +544,14 @@ class mail_thread(osv.AbstractModel): except: thread_id = False assert thread_id and hasattr(model_pool, 'message_update') or hasattr(model_pool, 'message_new'), \ - "No possible route found for incoming message with Message-Id %s. " \ - "Create an appropriate mail.alias or force the destination model." % message_id + "No possible route found for incoming message from %s to %s (Message-Id %s:)." \ + "Create an appropriate mail.alias or force the destination model." % (email_from, email_to, message_id) if thread_id and not model_pool.exists(cr, uid, thread_id): _logger.warning('Received mail reply to missing document %s! Ignoring and creating new document instead for Message-Id %s', - thread_id, message_id) + thread_id, message_id) thread_id = None - _logger.debug('Routing mail with Message-Id %s: fallback to model:%s, thread_id:%s, custom_values:%s, uid:%s', - message_id, model, thread_id, custom_values, uid) + _logger.info('Routing mail from %s to %s with Message-Id %s: fallback to model:%s, thread_id:%s, custom_values:%s, uid:%s', + email_from, email_to, message_id, model, thread_id, custom_values, uid) return [(model, thread_id, custom_values, uid)] def message_process(self, cr, uid, model, message, custom_values=None, @@ -598,12 +601,24 @@ class mail_thread(osv.AbstractModel): if isinstance(message, unicode): message = message.encode('utf-8') msg_txt = email.message_from_string(message) - routes = self.message_route(cr, uid, msg_txt, model, - thread_id, custom_values, - context=context) + + # parse the message, verify we are not in a loop by checking message_id is not duplicated msg = self.message_parse(cr, uid, msg_txt, save_original=save_original, context=context) if strip_attachments: msg.pop('attachments', None) + if msg.get('message_id'): # should always be True as message_parse generate one if missing + existing_msg_ids = self.pool.get('mail.message').search(cr, SUPERUSER_ID, [ + ('message_id', '=', msg.get('message_id')), + ], context=context) + if existing_msg_ids: + _logger.info('Ignored mail from %s to %s with Message-Id %s:: found duplicated Message-Id during processing', + msg.get('from'), msg.get('to'), msg.get('message_id')) + return False + + # find possible routes for the message + routes = self.message_route(cr, uid, msg_txt, model, + thread_id, custom_values, + context=context) # postpone setting msg.partner_ids after message_post, to avoid double notifications partner_ids = msg.pop('partner_ids', []) @@ -800,7 +815,7 @@ class mail_thread(osv.AbstractModel): # as RFC2822 requires timezone offset in Date headers. stored_date = parsed_date.replace(tzinfo=pytz.utc) else: - stored_date = parsed_date.astimezone(pytz.utc) + stored_date = parsed_date.astimezone(tz=pytz.utc) except Exception: _logger.warning('Failed to parse Date header %r in incoming mail ' 'with message-id %r, assuming current date/time.', @@ -819,7 +834,7 @@ class mail_thread(osv.AbstractModel): if parent_ids: msg_dict['parent_id'] = parent_ids[0] - msg_dict['body'], msg_dict['attachments'] = self._message_extract_payload(message) + msg_dict['body'], msg_dict['attachments'] = self._message_extract_payload(message, save_original=save_original) return msg_dict #------------------------------------------------------ @@ -958,12 +973,15 @@ class mail_thread(osv.AbstractModel): ], limit=1, context=context) if author_ids: kwargs['author_id'] = author_ids[0] + author_id = kwargs.get('author_id') + if author_id is None: # keep False values + author_id = self.pool.get('mail.message')._get_default_author(cr, uid, context=context) # 1: Handle content subtype: if plaintext, converto into HTML if content_subtype == 'plaintext': body = tools.plaintext2html(body) - # 2: Private message: add recipients (recipients and author of parent message) + # 2: Private message: add recipients (recipients and author of parent message) - current author # + legacy-code management (! we manage only 4 and 6 commands) partner_ids = set() kwargs_partner_ids = kwargs.pop('partner_ids', []) @@ -976,11 +994,13 @@ class mail_thread(osv.AbstractModel): partner_ids.add(partner_id) else: pass # we do not manage anything else - if parent_id and model == 'mail.thread': + if parent_id and not model: parent_message = mail_message.browse(cr, uid, parent_id, context=context) - partner_ids |= set([partner.id for partner in parent_message.partner_ids]) + private_followers = set([partner.id for partner in parent_message.partner_ids]) if parent_message.author_id: - partner_ids.add(parent_message.author_id.id) + private_followers.add(parent_message.author_id.id) + private_followers -= set([author_id]) + partner_ids |= private_followers # 3. Attachments # - HACK TDE FIXME: Chatter: attachments linked to the document (not done JS-side), load the message @@ -1041,6 +1061,7 @@ class mail_thread(osv.AbstractModel): values = kwargs values.update({ + 'author_id': author_id, 'model': model, 'res_id': thread_id or False, 'body': body, diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 9805c9d3a61..bacc42baaac 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -568,7 +568,6 @@ text-shadow: none; width: 100%; } -.openerp .oe_followers button.oe_invite, .openerp .oe_followers button.oe_follower.oe_following{ color: white; background-color: #3465A4; @@ -626,6 +625,8 @@ height: 32px; overflow: hidden; white-space: nowrap; + text-overflow: ellipsis; + margin-right: 10px; } .openerp .oe_followers .oe_partner img{ width: 32px; diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index fadba98281f..ec4feed82e2 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -1208,7 +1208,7 @@ openerp.mail = function (session) { this.author_id = datasets.author_id || false; this.thread_level = (datasets.thread_level+1) || 0; datasets.partner_ids = datasets.partner_ids || []; - if (datasets.author_id && ! _.contains(datasets.partner_ids, datasets.author_id) && datasets.author_id[0]) { + if (datasets.author_id && !_.contains(_.flatten(datasets.partner_ids),datasets.author_id[0]) && datasets.author_id[0]) { datasets.partner_ids.push(datasets.author_id); } this.partner_ids = datasets.partner_ids; @@ -1389,7 +1389,10 @@ openerp.mail = function (session) { if (this.options.help) { no_message.html(this.options.help); } - no_message.appendTo(this.$el); + if (!this.$el.find(".oe_view_nocontent").length) + { + no_message.appendTo(this.$el); + } }, /** diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index b26ef06f5e4..db53a60cdbc 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -246,7 +246,11 @@ <!-- message itself --> <div class="oe_msg_content"> <h1 t-if="(widget.show_record_name or widget.subject) and !widget.thread_level" class="oe_msg_title"> - <a t-if="widget.options.show_link and widget.show_record_name" class="oe_mail_action_model" t-attf-href="#model=#{widget.model}&id=#{widget.res_id}"><t t-raw="widget.record_name"/></a><span t-if="!widget.options.show_link and widget.show_record_name"><t t-raw="widget.record_name"/></span><t t-if="widget.show_record_name">: </t> + <a t-if="widget.options.show_link and widget.show_record_name" class="oe_mail_action_model" t-attf-href="#model=#{widget.model}&id=#{widget.res_id}"> + <t t-raw="widget.record_name"/> + </a> + <span t-if="!widget.options.show_link and widget.show_record_name"><t t-raw="widget.record_name"/></span> + <t t-if="widget.show_record_name and widget.subject">: </t> <t t-if="widget.subject" t-raw="widget.subject"/> </h1> <div class="oe_msg_body"> diff --git a/addons/mail/static/src/xml/mail_followers.xml b/addons/mail/static/src/xml/mail_followers.xml index 960c399ecce..88f38146de3 100644 --- a/addons/mail/static/src/xml/mail_followers.xml +++ b/addons/mail/static/src/xml/mail_followers.xml @@ -30,7 +30,7 @@ --> <div t-name="mail.followers.partner" class='oe_partner'> <img class="oe_mail_thumbnail oe_mail_frame" t-attf-src="{record.avatar_url}"/> - <a t-attf-href="#model=res.partner&id=#{record.id}"><t t-raw="record.name"/></a> + <a t-attf-href="#model=res.partner&id=#{record.id}" t-att-title="record.name"><t t-esc="record.name"/></a> <img t-if="widget.session.debug" class="oe_edit_subtype" t-att-src='_s + "/mail/static/src/img/icon-edit.gif"' title="Edit Subtype" t-att-data-id="record.id"/> <span t-if="widget.view_is_editable" class="oe_remove_follower oe_e" title="Remove this follower" t-att-data-id="record.id">X</span> </div> diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py index 2d0019c0b8a..7eea66b3b90 100644 --- a/addons/mail/tests/test_mail_features.py +++ b/addons/mail/tests/test_mail_features.py @@ -280,7 +280,8 @@ class test_mail(TestMailBase): 'message_post: mail.mail notifications should have been auto-deleted!') # Test: notifications emails: to a and b, c is email only, r is author - test_emailto = ['Administrator <a@a>', 'Bert Tartopoils <b@b>'] + # test_emailto = ['Administrator <a@a>', 'Bert Tartopoils <b@b>'] + test_emailto = ['"Followers of -Pigs-" <a@a>', '"Followers of -Pigs-" <b@b>'] self.assertEqual(len(sent_emails), 2, 'message_post: notification emails wrong number of send emails') self.assertEqual(set([m['email_to'][0] for m in sent_emails]), set(test_emailto), @@ -353,7 +354,8 @@ class test_mail(TestMailBase): self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg2_id)]), 'mail.mail notifications should have been auto-deleted!') # Test: emails send by server (to a, b, c, d) - test_emailto = [u'Administrator <a@a>', u'Bert Tartopoils <b@b>', u'Carine Poilvache <c@c>', u'D\xe9d\xe9 Grosbedon <d@d>'] + # test_emailto = [u'Administrator <a@a>', u'Bert Tartopoils <b@b>', u'Carine Poilvache <c@c>', u'D\xe9d\xe9 Grosbedon <d@d>'] + test_emailto = [u'"Followers of Pigs" <a@a>', u'"Followers of Pigs" <b@b>', u'"Followers of Pigs" <c@c>', u'"Followers of Pigs" <d@d>'] # self.assertEqual(len(sent_emails), 3, 'sent_email number of sent emails incorrect') for sent_email in sent_emails: self.assertEqual(sent_email['email_from'], 'Raoul Grosbedon <r@r>', diff --git a/addons/mail/tests/test_mail_gateway.py b/addons/mail/tests/test_mail_gateway.py index eb6ba22067b..a68011298c7 100644 --- a/addons/mail/tests/test_mail_gateway.py +++ b/addons/mail/tests/test_mail_gateway.py @@ -116,8 +116,11 @@ class TestMailgateway(TestMailBase): frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com') sent_emails = self._build_email_kwargs_list # Test: one group created by mailgateway administrator - self.assertTrue(len(frog_groups) == 1) + self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) + res = self.mail_group.perm_read(cr, uid, [frog_group.id], details=False) + self.assertEqual(res[0].get('create_uid'), uid, + 'message_process: group should have been created by uid as alias_user__id is False on the alias') # Test: one message that is the incoming email self.assertEqual(len(frog_group.message_ids), 1, 'message_process: newly created group should have the incoming email in message_ids') @@ -150,9 +153,12 @@ class TestMailgateway(TestMailBase): self._init_mock_build_email() frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com') sent_emails = self._build_email_kwargs_list - # Test: one group created by raoul - self.assertTrue(len(frog_groups) == 1) + # Test: one group created by Raoul + self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) + res = self.mail_group.perm_read(cr, uid, [frog_group.id], details=False) + self.assertEqual(res[0].get('create_uid'), self.user_raoul_id, + 'message_process: group should have been created by alias_user_id') # Test: one message that is the incoming email self.assertEqual(len(frog_group.message_ids), 1, 'message_process: newly created group should have the incoming email in message_ids') @@ -175,8 +181,8 @@ class TestMailgateway(TestMailBase): # Do: incoming email from a known partner that is also an user that can create a mail.group self.res_users.create(cr, uid, {'partner_id': p1id, 'login': 'sylvie', 'groups_id': [(6, 0, [self.group_employee_id])]}) frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com') - # Test: one group created by Sylvie - self.assertTrue(len(frog_groups) == 1) + # Test: one group created by Raoul (or Sylvie maybe, if we implement it) + self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: one message that is the incoming email self.assertEqual(len(frog_group.message_ids), 1, @@ -195,6 +201,7 @@ class TestMailgateway(TestMailBase): # Do: even with a wrong destination, a reply should end up in the correct thread frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other@gmail.com', + msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>', to='erroneous@example.com>', subject='Re: news', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) # Test: no group 'Re: news' created, still only 1 Frogs group @@ -205,12 +212,30 @@ class TestMailgateway(TestMailBase): 'message_process: reply on Frogs should not have created a duplicate group with old subject') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: one new message - self.assertTrue(len(frog_group.message_ids) == 2, 'message_process: group should contain 2 messages after reply') + self.assertEqual(len(frog_group.message_ids), 2, 'message_process: group should contain 2 messages after reply') # Test: author (and not recipient) added as follower frog_follower_ids = set([p.id for p in frog_group.message_follower_ids]) self.assertEqual(frog_follower_ids, set([p1id, p2id]), 'message_process: after reply, group should have 2 followers') + # Do: due to some issue, same email goes back into the mailgateway + frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other@gmail.com', + msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>', + subject='Re: news', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) + # Test: no group 'Re: news' created, still only 1 Frogs group + self.assertEqual(len(frog_groups), 0, + 'message_process: reply on Frogs should not have created a new group with new subject') + frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) + self.assertEqual(len(frog_groups), 1, + 'message_process: reply on Frogs should not have created a duplicate group with old subject') + frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) + # Test: no new message + self.assertEqual(len(frog_group.message_ids), 2, 'message_process: message with already existing message_id should not have been duplicated') + # Test: message_id is still unique + msg_ids = self.mail_message.search(cr, uid, [('message_id', 'ilike', '<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>')]) + self.assertEqual(len(msg_ids), 1, + 'message_process: message with already existing message_id should not have been duplicated') + # -------------------------------------------------- # Test3: email_from and partner finding # -------------------------------------------------- @@ -223,6 +248,7 @@ class TestMailgateway(TestMailBase): # Do: post a new message, with a known partner -> duplicate emails -> partner format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>', to='erroneous@example.com>', subject='Re: news (2)', + msg_id='<1198923581.41972151344608186760.JavaMail.new1@agrolait.com>', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) @@ -236,6 +262,7 @@ class TestMailgateway(TestMailBase): self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'}) format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>', to='erroneous@example.com>', subject='Re: news (3)', + msg_id='<1198923581.41972151344608186760.JavaMail.new2@agrolait.com>', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) @@ -250,6 +277,7 @@ class TestMailgateway(TestMailBase): self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'}) format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>', to='erroneous@example.com>', subject='Re: news (3)', + msg_id='<1198923581.41972151344608186760.JavaMail.new3@agrolait.com>', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) @@ -265,23 +293,32 @@ class TestMailgateway(TestMailBase): # Do: incoming email with model that does not accepts incoming emails must raise self.assertRaises(AssertionError, - format_and_process, - MAIL_TEMPLATE, to='noone@example.com', subject='spam', extra='', model='res.country') + format_and_process, + MAIL_TEMPLATE, + to='noone@example.com', subject='spam', extra='', model='res.country', + msg_id='<1198923581.41972151344608186760.JavaMail.new4@agrolait.com>') # Do: incoming email without model and without alias must raise self.assertRaises(AssertionError, - format_and_process, - MAIL_TEMPLATE, to='noone@example.com', subject='spam', extra='') + format_and_process, + MAIL_TEMPLATE, + to='noone@example.com', subject='spam', extra='', + msg_id='<1198923581.41972151344608186760.JavaMail.new5@agrolait.com>') # Do: incoming email with model that accepting incoming emails as fallback - frog_groups = format_and_process(MAIL_TEMPLATE, to='noone@example.com', subject='Spammy', extra='', model='mail.group') + frog_groups = format_and_process(MAIL_TEMPLATE, + to='noone@example.com', + subject='Spammy', extra='', model='mail.group', + msg_id='<1198923581.41972151344608186760.JavaMail.new6@agrolait.com>') self.assertEqual(len(frog_groups), 1, 'message_process: erroneous email but with a fallback model should have created a new mail.group') # Do: incoming email in plaintext should be stored as html - frog_groups = format_and_process(MAIL_TEMPLATE_PLAINTEXT, to='groups@example.com', subject='Frogs Return', extra='', msg_id='<deadcafe.1337@smtp.agrolait.com>') + frog_groups = format_and_process(MAIL_TEMPLATE_PLAINTEXT, + to='groups@example.com', subject='Frogs Return', extra='', + msg_id='<deadcafe.1337@smtp.agrolait.com>') # Test: one group created with one message - self.assertTrue(len(frog_groups) == 1) + self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) msg = frog_group.message_ids[0] # Test: plain text content should be wrapped and stored as html @@ -305,19 +342,27 @@ class TestMailgateway(TestMailBase): # Reply to msg1, make sure the reply is properly attached using the various reply identification mechanisms # 0. Direct alias match - reply_msg1 = format(MAIL_TEMPLATE, to='Pretty Pigs <group+pigs@example.com>', extra='In-Reply-To: %s' % msg1.message_id) + reply_msg1 = format(MAIL_TEMPLATE, to='Pretty Pigs <group+pigs@example.com>', + extra='In-Reply-To: %s' % msg1.message_id, + msg_id='<1198923581.41972151344608186760.JavaMail.2@agrolait.com>') self.mail_group.message_process(cr, uid, None, reply_msg1) # 1. In-Reply-To header - reply_msg2 = format(MAIL_TEMPLATE, to='erroneous@example.com', extra='In-Reply-To: %s' % msg1.message_id) + reply_msg2 = format(MAIL_TEMPLATE, to='erroneous@example.com', + extra='In-Reply-To: %s' % msg1.message_id, + msg_id='<1198923581.41972151344608186760.JavaMail.3@agrolait.com>') self.mail_group.message_process(cr, uid, None, reply_msg2) # 2. References header - reply_msg3 = format(MAIL_TEMPLATE, to='erroneous@example.com', extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id) + reply_msg3 = format(MAIL_TEMPLATE, to='erroneous@example.com', + extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id, + msg_id='<1198923581.41972151344608186760.JavaMail.4@agrolait.com>') self.mail_group.message_process(cr, uid, None, reply_msg3) # 3. Subject contains [<ID>] + model passed to message+process -> only attached to group, but not to mail (not in msg1.child_ids) - reply_msg4 = format(MAIL_TEMPLATE, to='erroneous@example.com', extra='', subject='Re: [%s] 1' % self.group_pigs_id) + reply_msg4 = format(MAIL_TEMPLATE, to='erroneous@example.com', + extra='', subject='Re: [%s] 1' % self.group_pigs_id, + msg_id='<1198923581.41972151344608186760.JavaMail.5@agrolait.com>') self.mail_group.message_process(cr, uid, 'mail.group', reply_msg4) group_pigs.refresh() @@ -327,4 +372,55 @@ class TestMailgateway(TestMailBase): def test_20_private_discussion(self): """ Testing private discussion between partners. """ - pass + cr, uid = self.cr, self.uid + + # Do: Raoul writes to Bert and Administrator, with a thread_model in context that should not be taken into account + msg1_pids = [self.partner_admin_id, self.partner_bert_id] + msg1_id = self.mail_thread.message_post(cr, self.user_raoul_id, False, + partner_ids=msg1_pids, + subtype='mail.mt_comment', + context={'thread_model': 'mail.group'}) + + # Test: message recipients + msg = self.mail_message.browse(cr, uid, msg1_id) + msg_pids = [p.id for p in msg.partner_ids] + msg_nids = [p.id for p in msg.notified_partner_ids] + test_pids = msg1_pids + test_nids = msg1_pids + self.assertEqual(set(msg_pids), set(test_pids), + 'message_post: private discussion: incorrect recipients') + self.assertEqual(set(msg_nids), set(test_nids), + 'message_post: private discussion: incorrect notified recipients') + self.assertEqual(msg.model, False, + 'message_post: private discussion: context key "thread_model" not correctly ignored when having no res_id') + + # Do: Bert replies through mailgateway (is a customer) + msg2_id = self.mail_thread.message_post(cr, uid, False, + author_id=self.partner_bert_id, + parent_id=msg1_id, subtype='mail.mt_comment') + + # Test: message recipients + msg = self.mail_message.browse(cr, uid, msg2_id) + msg_pids = [p.id for p in msg.partner_ids] + msg_nids = [p.id for p in msg.notified_partner_ids] + test_pids = [self.partner_admin_id, self.partner_raoul_id] + test_nids = test_pids + self.assertEqual(set(msg_pids), set(test_pids), + 'message_post: private discussion: incorrect recipients when replying') + self.assertEqual(set(msg_nids), set(test_nids), + 'message_post: private discussion: incorrect notified recipients when replying') + + # Do: Administrator replies + msg3_id = self.mail_thread.message_post(cr, uid, False, + parent_id=msg2_id, subtype='mail.mt_comment') + + # Test: message recipients + msg = self.mail_message.browse(cr, uid, msg3_id) + msg_pids = [p.id for p in msg.partner_ids] + msg_nids = [p.id for p in msg.notified_partner_ids] + test_pids = [self.partner_bert_id, self.partner_raoul_id] + test_nids = test_pids + self.assertEqual(set(msg_pids), set(test_pids), + 'message_post: private discussion: incorrect recipients when replying') + self.assertEqual(set(msg_nids), set(test_nids), + 'message_post: private discussion: incorrect notified recipients when replying') diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 66e7149ac6d..629dd6a88f0 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -175,11 +175,17 @@ class mail_compose_message(osv.TransientModel): :param int res_id: id of the document record this mail is related to """ doc_name_get = self.pool.get(model).name_get(cr, uid, [res_id], context=context) + record_name = False if doc_name_get: record_name = doc_name_get[0][1] - else: - record_name = False - return {'model': model, 'res_id': res_id, 'record_name': record_name} + values = { + 'model': model, + 'res_id': res_id, + 'record_name': record_name, + } + if record_name: + values['subject'] = 'Re: %s' % record_name + return values def get_message_data(self, cr, uid, message_id, context=None): """ Returns a defaults-like dict with initial values for the composition @@ -197,7 +203,7 @@ class mail_compose_message(osv.TransientModel): # create subject re_prefix = _('Re:') - reply_subject = tools.ustr(message_data.subject or '') + reply_subject = tools.ustr(message_data.subject or message_data.record_name or '') if not (reply_subject.startswith('Re:') or reply_subject.startswith(re_prefix)) and message_data.subject: reply_subject = "%s %s" % (re_prefix, reply_subject) # get partner_ids from original message diff --git a/addons/mrp/stock.py b/addons/mrp/stock.py index 1ff121c78bd..2feffee94a1 100644 --- a/addons/mrp/stock.py +++ b/addons/mrp/stock.py @@ -45,7 +45,7 @@ class StockMove(osv.osv): procurement_obj = self.pool.get('procurement.order') product_obj = self.pool.get('product.product') processed_ids = [move.id] - if move.product_id.supply_method == 'produce' and move.product_id.procure_method == 'make_to_order': + if move.product_id.supply_method == 'produce': bis = bom_obj.search(cr, uid, [ ('product_id','=',move.product_id.id), ('bom_id','=',False), diff --git a/addons/plugin/plugin_handler.py b/addons/plugin/plugin_handler.py index 0664af1c92e..f13fc255a6d 100644 --- a/addons/plugin/plugin_handler.py +++ b/addons/plugin/plugin_handler.py @@ -4,7 +4,8 @@ Created on 18 oct. 2011 @author: openerp ''' -from openerp.osv import fields, osv +from openerp.osv import osv +from openerp.tools.translate import _ class plugin_handler(osv.osv_memory): _name = 'plugin.handler' @@ -29,7 +30,7 @@ class plugin_handler(osv.osv_memory): partner_ids = partner_obj.search(cr, uid, [('email', 'like', address_email)]) res_id = partner_ids and partner_ids[0] or 0 url = self._make_url(cr, uid, res_id, 'res.partner') - return ('res.partner', res_id , url) + return ('res.partner', res_id, url) def document_get(self, cr, uid, email): """ @@ -48,7 +49,7 @@ class plugin_handler(osv.osv_memory): message_id = msg.get('message_id') msg_id = False if message_id: - msg_ids = mail_message_obj.search(cr, uid, [('message_id','=', message_id)]) + msg_ids = mail_message_obj.search(cr, uid, [('message_id', '=', message_id)]) msg_id = len(msg_ids) and msg_ids[0] or False if not msg_id and parent_id: msg_id = parent_id @@ -57,8 +58,8 @@ class plugin_handler(osv.osv_memory): res_id = msg.res_id model = msg.model url = self._make_url(cr, uid, res_id, model) - name = self.pool.get(model).name_get(cr, uid, [res_id])[0][1] - return (model,res_id, url,name) + name = self.pool.get(model).name_get(cr, uid, [res_id])[0][1] + return (model, res_id, url, name) def document_type(self, cr, uid, context=None): """ @@ -94,26 +95,25 @@ class plugin_handler(osv.osv_memory): model_obj = self.pool.get(model) msg = self.pool.get('mail.thread').message_parse(cr, uid, email) message_id = msg.get('message-id') - mail_ids = mail_message.search(cr, uid, [('message_id','=',message_id),('res_id','=',res_id),('model','=',model)]) - - if message_id and mail_ids : + mail_ids = mail_message.search(cr, uid, [('message_id', '=', message_id), ('res_id', '=', res_id), ('model', '=', model)]) + if message_id and mail_ids: mail_record = mail_message.browse(cr, uid, mail_ids)[0] res_id = mail_record.res_id - notify = "Email already pushed" + notify = _("Email already pushed") elif res_id == 0: if model == 'res.partner': - notify = 'User the Partner button to create a new partner' + notify = _('Use the Partner button to create a new partner') else: res_id = model_obj.message_process(cr, uid, model, email) - notify = "Mail successfully pushed, a new %s has been created " % model + notify = _("Mail successfully pushed, a new %s has been created.") % model else: model_obj.message_post(cr, uid, [res_id], - body= msg.get('body'), - subject= msg.get('subject'), - type= 'email', - parent_id= msg.get('parent_id'), - attachments= msg.get('attachments')) - notify = "Mail successfully pushed" + body=msg.get('body'), + subject=msg.get('subject'), + type='email', + parent_id=msg.get('parent_id'), + attachments=msg.get('attachments')) + notify = _("Mail successfully pushed") url = self._make_url(cr, uid, res_id, model) return (model, res_id, url, notify) @@ -154,16 +154,17 @@ class plugin_handler(osv.osv_memory): message_id = msg.get('message-id') push_mail = self.push_message(cr, uid, model, headers, res_id) res_id = push_mail[1] - model = push_mail[0] + model = push_mail[0] + notify = push_mail[3] for name in attachments.keys(): attachment_ids = ir_attachment_obj.search(cr, uid, [('res_model', '=', model), ('res_id', '=', res_id), ('datas_fname', '=', name)]) if attachment_ids: - attach_ids.append( attachment_ids[0]) + attach_ids.append(attachment_ids[0]) else: - vals = {"res_model": model, "res_id": res_id, "name": name, "datas" :attachments[name], "datas_fname" : name} + vals = {"res_model": model, "res_id": res_id, "name": name, "datas": attachments[name], "datas_fname": name} attach_ids.append(ir_attachment_obj.create(cr, uid, vals)) - mail_ids = mail_message.search(cr, uid, [('message_id','=',message_id),('res_id','=',res_id),('model','=',model)]) + mail_ids = mail_message.search(cr, uid, [('message_id', '=', message_id), ('res_id', '=', res_id), ('model', '=', model)]) if mail_ids: - ids = mail_message.write(cr, uid, mail_ids[0], { 'attachment_ids': [(6, 0, attach_ids)],'body':body,'body_html':body_html}) + mail_message.write(cr, uid, mail_ids[0], {'attachment_ids': [(6, 0, attach_ids)], 'body': body, 'body_html': body_html}) url = self._make_url(cr, uid, res_id, model) - return (model, res_id, url) + return (model, res_id, url, notify) diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj index 75fe271e5d6..f9ac3e31553 100644 --- a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj +++ b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj @@ -17,6 +17,7 @@ <UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
@@ -29,7 +30,6 @@ <MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
- <IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
@@ -53,9 +53,8 @@ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
- <Reference Include="CookComputing.XmlRpcV2, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\OpenERPOutlookPlugin\bin\Release\CookComputing.XmlRpcV2.dll</HintPath>
+ <Reference Include="CookComputing.XmlRpcV2">
+ <HintPath>..\CookComputing.XmlRpcV2.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
@@ -81,7 +80,7 @@ <ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
- <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
@@ -91,7 +90,7 @@ </BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
- <ProductName>Windows Installer 3.1</ProductName>
+ <ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin.sln b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin.sln index f4705664cf4..ad53769e5b4 100644 --- a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin.sln +++ b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin.sln @@ -1,6 +1,6 @@
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenERPOutlookPlugin", "OpenERPOutlookPlugin\OpenERPOutlookPlugin.csproj", "{F4B2219B-F235-400F-81B4-92F15250BBA4}"
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "OpenERPOutlookPluginSetup", "OpenERPOutlookPluginSetup\OpenERPOutlookPluginSetup.vdproj", "{96333293-0156-4998-9065-42721CEB0368}"
diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/Connect.cs b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/Connect.cs index 1336c7f7695..dae4db88aa2 100644 --- a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/Connect.cs +++ b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/Connect.cs @@ -303,6 +303,7 @@ namespace OpenERPOutlookPlugin foreach (outlook.MailItem mailitem in Tools.MailItems())
{
+
Object[] contact = Cache.OpenERPOutlookPlugin.RedirectPartnerPage(mailitem);
if ((int)contact[1] > 0)
diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/OpenERPOutlookPlugin.cs b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/OpenERPOutlookPlugin.cs index b057201b8d1..e1d45318ee4 100644 --- a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/OpenERPOutlookPlugin.cs +++ b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/OpenERPOutlookPlugin.cs @@ -95,7 +95,6 @@ namespace OpenERPOutlookPlugin /*
* Will open the url into the web browser.
*/
-
System.Diagnostics.Process.Start(web_url.ToString());
}
@@ -163,9 +162,16 @@ namespace OpenERPOutlookPlugin args.Add(attachments);
object push_mail = this.Connection.Execute("plugin.handler", "push_message_outlook", args.ToArray());
object[] push = (object[])push_mail;
- this.RedirectWeb(push[2].ToString());
- return true;
+ if (Convert.ToInt32(push[1]) == 0)
+ {
+ MessageBox.Show(push[3].ToString());
+ }
+ else
+ {
+ this.RedirectWeb(push[2].ToString());
+ }
+ return true;
}
public long CreatePartnerRecord(string name)
{
diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup32.msi b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup32.msi Binary files differindex a31471c28ba..9d9dd5d3ad3 100644 --- a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup32.msi +++ b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup32.msi diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup64.msi b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup64.msi Binary files differindex 87cac88be70..0c2fa88bb24 100644 --- a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup64.msi +++ b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup64.msi diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index d2cf15b54f3..660434ba53e 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -295,7 +295,8 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal return; } //try to push an order to the server - (new instance.web.Model('pos.order')).get_func('create_from_ui')([order]) + // shadow : true is to prevent a spinner to appear in case of timeout + (new instance.web.Model('pos.order')).call('create_from_ui',[[order]],undefined,{ shadow:true }) .fail(function(unused, event){ //don't show error popup if it fails event.preventDefault(); diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js index 874c387ea23..cec48dbe72f 100644 --- a/addons/point_of_sale/static/src/js/widgets.js +++ b/addons/point_of_sale/static/src/js/widgets.js @@ -794,7 +794,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa renderElement: function() { var self = this; this._super(); - this.$('.oe_pos_synch-notification-button').click(function(){ + this.$el.click(function(){ self.pos.flush(); }); }, @@ -879,6 +879,8 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa instance.web.unblockUI(); self.$('.loader').animate({opacity:0},1500,'swing',function(){self.$('.loader').hide();}); + self.pos.flush(); + }).fail(function(){ // error when loading models data from the backend instance.web.unblockUI(); return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_pos_session_opening']], ['res_id']) diff --git a/addons/portal/portal_view.xml b/addons/portal/portal_view.xml index d56e277c3fb..1ff98bdc77f 100644 --- a/addons/portal/portal_view.xml +++ b/addons/portal/portal_view.xml @@ -21,7 +21,6 @@ <field name="params" eval=""{ 'domain': [ ('to_read', '=', True), - ('starred', '=', False), ], 'show_compose_message': False, 'show_link': False, @@ -40,6 +39,7 @@ </field> </record> + <!-- TODO: remove me in 8.0 --> <record id="action_mail_star_feeds_portal" model="ir.actions.client"> <field name="name">To-do</field> <field name="tag">mail.wall</field> @@ -67,6 +67,9 @@ </p> </field> </record> + <menuitem name="To-do" id="portal_mail_starfeeds" parent="portal_messages" + action="action_mail_star_feeds_portal" sequence="20" groups="base.group_no_one"/> + <!-- end --> <record id="action_mail_archives_feeds_portal" model="ir.actions.client"> <field name="name">Archives</field> @@ -84,7 +87,6 @@ 'show_compose_message': False, 'show_link': False, 'view_mailbox': True, - 'read_action': 'read' }""/> <field name="help" type="html"> <p> @@ -98,8 +100,6 @@ <menuitem name="Inbox" id="portal_inbox" parent="portal_messages" action="action_mail_inbox_feeds_portal" sequence="10" groups="portal.group_portal"/> - <menuitem name="To-do" id="portal_mail_starfeeds" parent="portal_messages" - action="action_mail_star_feeds_portal" sequence="20" groups="portal.group_portal"/> <menuitem name="Archives" id="portal_mail_archivesfeeds" parent="portal_messages" action="action_mail_archives_feeds_portal" sequence="30" groups="portal.group_portal"/> @@ -107,7 +107,7 @@ Create menu items that we'll leave empty for now - they'll be filled up by other portal modules. --> - <menuitem name="Quotations and Sales Orders" id="portal_orders" parent="portal_menu" sequence="20"/> + <menuitem name="Billing" id="portal_orders" parent="portal_menu" sequence="20"/> <menuitem name="After Sale Services" id="portal_after_sales" parent="portal_menu" sequence="30"/> <menuitem name="Projects" id="portal_projects" parent="portal_menu" sequence="40"/> diff --git a/addons/portal_sale/portal_sale.py b/addons/portal_sale/portal_sale.py index a6ca616ad2f..cd3b702d3c5 100644 --- a/addons/portal_sale/portal_sale.py +++ b/addons/portal_sale/portal_sale.py @@ -59,19 +59,8 @@ class sale_order(osv.Model): assert len(ids) == 1 document = self.browse(cr, uid, ids[0], context=context) partner = document.partner_id - # TDE note: this code should be improved: used a real invite wizard instead of an ugly email if partner.id not in document.message_follower_ids: self.message_subscribe(cr, uid, ids, [partner.id], context=context) - mail_values = { - 'recipient_ids': [(4, partner.id)], - 'subject': 'Invitation to follow %s' % document.name_get()[0][1], - 'body_html': 'You have been invited to follow %s' % document.name_get()[0][1], - 'auto_delete': True, - 'type': 'email', - } - mail_obj = self.pool.get('mail.mail') - mail_id = mail_obj.create(cr, uid, mail_values, context=context) - mail_obj.send(cr, uid, [mail_id], context=context) return super(sale_order, self).action_button_confirm(cr, uid, ids, context=context) def get_signup_url(self, cr, uid, ids, context=None): diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index 73707e39807..757cce2ae95 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -374,7 +374,7 @@ class product_pricelist_item(osv.osv): result.append((line.id, line.name)) result.append((-1, _('Other Pricelist'))) - result.append((-2, _('Partner section of the product form'))) + result.append((-2, _('Supplier Prices on the product form'))) return result _name = "product.pricelist.item" diff --git a/addons/product/product.py b/addons/product/product.py index 33225c92c6f..82b37f7b9e8 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -588,10 +588,13 @@ class product_product(osv.osv): # Check if the product is last product of this template other_product_ids = self.search(cr, uid, [('product_tmpl_id', '=', tmpl_id), ('id', '!=', product.id)], context=context) if not other_product_ids: - unlink_product_tmpl_ids.append(tmpl_id) + unlink_product_tmpl_ids.append(tmpl_id) unlink_ids.append(product.id) + res = super(product_product, self).unlink(cr, uid, unlink_ids, context=context) + # delete templates after calling super, as deleting template could lead to deleting + # products due to ondelete='cascade' self.pool.get('product.template').unlink(cr, uid, unlink_product_tmpl_ids, context=context) - return super(product_product, self).unlink(cr, uid, unlink_ids, context=context) + return res def onchange_uom(self, cursor, user, ids, uom_id, uom_po_id): if uom_id and uom_po_id: diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml index ddb1ab3809f..00e925fd6a0 100644 --- a/addons/product/product_view.xml +++ b/addons/product/product_view.xml @@ -581,6 +581,7 @@ <field name="delay"/> <field name="company_id" groups="base.group_multi_company" widget="selection"/> </group> + <p groups="product.group_purchase_pricelist" class="oe_grey">The prices below will only be taken into account when your pricelist is set as based on supplier prices.</p> <field groups="product.group_purchase_pricelist" name="pricelist_ids"> <tree editable="bottom" string="Pricelist"> <field name="min_quantity"/> diff --git a/addons/project/project_data.xml b/addons/project/project_data.xml index 025327d70b3..7bf1a623a2c 100644 --- a/addons/project/project_data.xml +++ b/addons/project/project_data.xml @@ -21,6 +21,7 @@ <record id="all_projects_account" model="account.analytic.account"> <field name="name">Projects</field> <field name="code">3</field> + <field name="type">view</field> </record> <function id="parent_project_default_set" model="ir.values" name="set" eval="('default',False,'parent_id', [('project.project', False)], all_projects_account, True, False, False, False, True)"/> diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index 01dab2962f3..f8f6510cd49 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -137,6 +137,13 @@ class project_issue(base_stage, osv.osv): res = {} for issue in self.browse(cr, uid, ids, context=context): + + # if the working hours on the project are not defined, use default ones (8 -> 12 and 13 -> 17 * 5), represented by None + if not issue.project_id or not issue.project_id.resource_calendar_id: + working_hours = None + else: + working_hours = issue.project_id.resource_calendar_id.id + res[issue.id] = {} for field in fields: duration = 0 @@ -150,20 +157,24 @@ class project_issue(base_stage, osv.osv): ans = date_open - date_create date_until = issue.date_open #Calculating no. of working hours to open the issue - if issue.project_id.resource_calendar_id: - hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id, + hours = cal_obj._interval_hours_get(cr, uid, working_hours, date_create, - date_open) + date_open, + timezone_from_uid=issue.user_id.id or uid, + exclude_leaves=False, + context=context) elif field in ['working_hours_close','day_close']: if issue.date_closed: date_close = datetime.strptime(issue.date_closed, "%Y-%m-%d %H:%M:%S") date_until = issue.date_closed ans = date_close - date_create #Calculating no. of working hours to close the issue - if issue.project_id.resource_calendar_id: - hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id, - date_create, - date_close) + hours = cal_obj._interval_hours_get(cr, uid, working_hours, + date_create, + date_close, + timezone_from_uid=issue.user_id.id or uid, + exclude_leaves=False, + context=context) elif field in ['days_since_creation']: if issue.create_date: days_since_creation = datetime.today() - datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S") @@ -182,27 +193,12 @@ class project_issue(base_stage, osv.osv): resource_ids = res_obj.search(cr, uid, [('user_id','=',issue.user_id.id)]) if resource_ids and len(resource_ids): resource_id = resource_ids[0] - duration = float(ans.days) - if issue.project_id and issue.project_id.resource_calendar_id: - duration = float(ans.days) * 24 - - new_dates = cal_obj.interval_min_get(cr, uid, - issue.project_id.resource_calendar_id.id, - date_create, - duration, resource=resource_id) - no_days = [] - date_until = datetime.strptime(date_until, '%Y-%m-%d %H:%M:%S') - for in_time, out_time in new_dates: - if in_time.date not in no_days: - no_days.append(in_time.date) - if out_time > date_until: - break - duration = len(no_days) + duration = float(ans.days) + float(ans.seconds)/(24*3600) if field in ['working_hours_open','working_hours_close']: res[issue.id][field] = hours - else: - res[issue.id][field] = abs(float(duration)) + elif field in ['day_open','day_close']: + res[issue.id][field] = duration return res diff --git a/addons/project_issue/report/project_issue_report.py b/addons/project_issue/report/project_issue_report.py index a5eb903a742..199a971c4ad 100644 --- a/addons/project_issue/report/project_issue_report.py +++ b/addons/project_issue/report/project_issue_report.py @@ -63,9 +63,9 @@ class project_issue_report(osv.osv): 'project_id':fields.many2one('project.project', 'Project',readonly=True), 'version_id': fields.many2one('project.issue.version', 'Version'), 'user_id' : fields.many2one('res.users', 'Assigned to',readonly=True), - 'partner_id': fields.many2one('res.partner','Contact',domain="[('object_id.model', '=', 'project.issue')]"), + 'partner_id': fields.many2one('res.partner','Contact'), 'channel_id': fields.many2one('crm.case.channel', 'Channel',readonly=True), - 'task_id': fields.many2one('project.task', 'Task',domain="[('object_id.model', '=', 'project.issue')]" ), + 'task_id': fields.many2one('project.task', 'Task'), 'email': fields.integer('# Emails', size=128, readonly=True), } @@ -96,8 +96,8 @@ class project_issue_report(osv.osv): c.channel_id, c.task_id, date_trunc('day',c.create_date) as create_date, - extract('epoch' from (c.date_open-c.create_date))/(3600*24) as delay_open, - extract('epoch' from (c.date_closed-c.date_open))/(3600*24) as delay_close, + c.day_open as delay_open, + c.day_close as delay_close, (SELECT count(id) FROM mail_message WHERE model='project.issue' AND res_id=c.id) AS email FROM diff --git a/addons/purchase/res_config.py b/addons/purchase/res_config.py index b773c57adb1..f5f2dfcdda5 100644 --- a/addons/purchase/res_config.py +++ b/addons/purchase/res_config.py @@ -65,6 +65,11 @@ Example: Product: this product is deprecated, do not purchase more than 5. 'default_invoice_method': 'manual', } + def onchange_purchase_analytic_plans(self, cr, uid, ids, module_purchase_analytic_plans, context=None): + """ change group_analytic_account_for_purchases following module_purchase_analytic_plans """ + if not module_purchase_analytic_plans: + return {} + return {'value': {'group_analytic_account_for_purchases': module_purchase_analytic_plans}} @@ -81,6 +86,8 @@ class account_config_settings(osv.osv_memory): def onchange_purchase_analytic_plans(self, cr, uid, ids, module_purchase_analytic_plans, context=None): """ change group_analytic_account_for_purchases following module_purchase_analytic_plans """ + if not module_purchase_analytic_plans: + return {} return {'value': {'group_analytic_account_for_purchases': module_purchase_analytic_plans}} # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase/res_config_view.xml b/addons/purchase/res_config_view.xml index 7f1cfc64f39..276dc892392 100644 --- a/addons/purchase/res_config_view.xml +++ b/addons/purchase/res_config_view.xml @@ -67,7 +67,7 @@ <label for="module_purchase_requisition"/> </div> <div> - <field name="module_purchase_analytic_plans" class="oe_inline"/> + <field name="module_purchase_analytic_plans" on_change="onchange_purchase_analytic_plans(module_purchase_analytic_plans, context)" class="oe_inline"/> <label for="module_purchase_analytic_plans"/> </div> <div> @@ -109,7 +109,7 @@ <label for="group_analytic_account_for_purchases"/> </div> <div> - <field name="module_purchase_analytic_plans" on_change="onchange_purchase_analytic_plans(module_purchase_analytic_plans)" class="oe_inline"/> + <field name="module_purchase_analytic_plans" on_change="onchange_purchase_analytic_plans(module_purchase_analytic_plans, context)" class="oe_inline"/> <label for="module_purchase_analytic_plans"/> </div> </xpath> diff --git a/addons/resource/resource.py b/addons/resource/resource.py index 727ca93d7c9..73a6e2a3ec8 100644 --- a/addons/resource/resource.py +++ b/addons/resource/resource.py @@ -19,7 +19,9 @@ # ############################################################################## +import pytz from datetime import datetime, timedelta +from dateutil import rrule import math from faces import * from openerp.osv import fields, osv @@ -212,45 +214,108 @@ class resource_calendar(osv.osv): @return : Total number of working hours based dt_from and dt_end and resource if supplied. """ - if not id: - return 0.0 - dt_leave = self._get_leaves(cr, uid, id, resource) - hours = 0.0 - - current_hour = dt_from.hour - - while (dt_from <= dt_to): - cr.execute("select hour_from,hour_to from resource_calendar_attendance where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.weekday(),id)) - der = cr.fetchall() - for (hour_from,hour_to) in der: - if hours != 0.0:#For first time of the loop only,hours will be 0 - current_hour = hour_from - leave_flag = False - if (hour_to>=current_hour): - dt_check = dt_from.strftime('%Y-%m-%d') - for leave in dt_leave: - if dt_check == leave: - dt_check = datetime.strptime(dt_check, "%Y-%m-%d") + timedelta(days=1) - leave_flag = True - - if leave_flag: - break - else: - d1 = dt_from - d2 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60)) + return self._interval_hours_get(cr, uid, id, dt_from, dt_to, resource_id=resource) - if hours != 0.0:#For first time of the loop only,hours will be 0 - d1 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(current_hour)), int((current_hour%1) * 60)) - - if dt_from.day == dt_to.day: - if hour_from <= dt_to.hour <= hour_to: - d2 = dt_to - dt_from = d2 - hours += (d2-d1).seconds - dt_from = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(current_hour)), int((current_hour%1) * 60)) + timedelta(days=1) - current_hour = 0.0 + def _interval_hours_get(self, cr, uid, id, dt_from, dt_to, resource_id=False, timezone_from_uid=None, exclude_leaves=True, context=None): + """ Calculates the Total Working hours based on given start_date to + end_date, If resource id is supplied that it will consider the source + leaves also in calculating the hours. - return (hours/3600) + @param dt_from : date start to calculate hours + @param dt_end : date end to calculate hours + @param resource_id: optional resource id, If given resource leave will be + considered. + @param timezone_from_uid: optional uid, if given we will considerer + working hours in that user timezone + @param exclude_leaves: optionnal, if set to True (default) we will exclude + resource leaves from working hours + @param context: current request context + @return : Total number of working hours based dt_from and dt_end and + resource if supplied. + """ + utc_tz = pytz.timezone('UTC') + local_tz = utc_tz + + if timezone_from_uid: + users_obj = self.pool.get('res.users') + user_timezone = users_obj.browse(cr, uid, timezone_from_uid, context=context).partner_id.tz + if user_timezone: + try: + local_tz = pytz.timezone(user_timezone) + except pytz.UnknownTimeZoneError: + pass # fallback to UTC as local timezone + + def utc_to_local_zone(naive_datetime): + utc_dt = utc_tz.localize(naive_datetime, is_dst=False) + return utc_dt.astimezone(local_tz) + + def float_time_convert(float_val): + factor = float_val < 0 and -1 or 1 + val = abs(float_val) + return (factor * int(math.floor(val)), int(round((val % 1) * 60))) + + # Get slots hours per day + # {day_of_week: [(8, 12), (13, 17), ...], ...} + hours_range_per_weekday = {} + if id: + cr.execute("select dayofweek, hour_from,hour_to from resource_calendar_attendance where calendar_id=%s order by hour_from", (id,)) + for weekday, hour_from, hour_to in cr.fetchall(): + weekday = int(weekday) + hours_range_per_weekday.setdefault(weekday, []) + hours_range_per_weekday[weekday].append((hour_from, hour_to)) + else: + # considering default working hours (Monday -> Friday, 8 -> 12, 13 -> 17) + for weekday in range(5): + hours_range_per_weekday[weekday] = [(8, 12), (13, 17)] + + ## Interval between dt_from - dt_to + ## + ## dt_from dt_to + ## =============|==================|============ + ## [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] + ## + ## [ : start of range + ## ] : end of range + ## + ## case 1: range end before interval start (skip) + ## case 2: range overlap interval start (fit start to internal) + ## case 3: range within interval + ## case 4: range overlap interval end (fit end to interval) + ## case 5: range start after interval end (skip) + + interval_start = utc_to_local_zone(dt_from) + interval_end = utc_to_local_zone(dt_to) + hours_timedelta = timedelta() + + # Get leaves for requested resource + dt_leaves = set([]) + if exclude_leaves and id: + dt_leaves = set(self._get_leaves(cr, uid, id, resource=resource_id)) + + for day in rrule.rrule(rrule.DAILY, dtstart=interval_start, + until=interval_end+timedelta(days=1), + byweekday=hours_range_per_weekday.keys()): + if exclude_leaves and day.strftime('%Y-%m-%d') in dt_leaves: + # XXX: futher improve leave management to allow for partial day leave + continue + for (range_from, range_to) in hours_range_per_weekday.get(day.weekday(), []): + range_from_hour, range_from_min = float_time_convert(range_from) + range_to_hour, range_to_min = float_time_convert(range_to) + daytime_start = local_tz.localize(day.replace(hour=range_from_hour, minute=range_from_min, second=0, tzinfo=None)) + daytime_end = local_tz.localize(day.replace(hour=range_to_hour, minute=range_to_min, second=0, tzinfo=None)) + + # case 1 & 5: time range out of interval + if daytime_end < interval_start or daytime_start > interval_end: + continue + # case 2 & 4: adjust start, end to fit within interval + daytime_start = max(daytime_start, interval_start) + daytime_end = min(daytime_end, interval_end) + + # case 2+, 4+, 3 + hours_timedelta += (daytime_end - daytime_start) + + # return timedelta converted to hours + return (hours_timedelta.days * 24.0 + hours_timedelta.seconds / 3600.0) resource_calendar() diff --git a/addons/resource/test/resource.yml b/addons/resource/test/resource.yml index 5b7fa108101..28604518b7b 100644 --- a/addons/resource/test/resource.yml +++ b/addons/resource/test/resource.yml @@ -40,12 +40,13 @@ I check Actual working hours on resource 'Developer' from this week - !python {model: resource.calendar}: | - from datetime import datetime, timedelta + from datetime import datetime + from dateutil.relativedelta import relativedelta now = datetime.now() - dt_from = now - timedelta(days=now.weekday()) - dt_to = dt_from+ timedelta(days=6) + dt_from = now - relativedelta(days=now.weekday(), hour=8, minute=30) + dt_to = dt_from + relativedelta(days=6, hour=17) hours = self.interval_hours_get(cr, uid, ref('timesheet_group1'), dt_from, dt_to, resource=ref('resource_developer')) - assert hours > 27 , 'Invalid Total Week working hour calculated' + assert hours > 27 , 'Invalid Total Week working hour calculated, got %r, expected > 27' % hours - Project Analysis work is of 20 hours which will start from Week start so i will calculate working schedule for resource Analyst for the same. - diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py index 6548591da1e..ec2307ca983 100644 --- a/addons/sale/res_config.py +++ b/addons/sale/res_config.py @@ -143,6 +143,8 @@ class account_config_settings(osv.osv_memory): def onchange_sale_analytic_plans(self, cr, uid, ids, module_sale_analytic_plans, context=None): """ change group_analytic_account_for_sales following module_sale_analytic_plans """ + if not module_sale_analytic_plans: + return {} return {'value': {'group_analytic_account_for_sales': module_sale_analytic_plans}} # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 5ee22f3c569..d1b4236cd4e 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -543,6 +543,9 @@ class sale_order(osv.osv): invoice_ref += o.name + '|' self.write(cr, uid, [o.id], {'state': 'progress'}) cr.execute('insert into sale_order_invoice_rel (order_id,invoice_id) values (%s,%s)', (o.id, res)) + #remove last '|' in invoice_ref + if len(invoice_ref) >= 1: + invoice_ref = invoice_ref[:-1] invoice.write(cr, uid, [res], {'origin': invoice_ref, 'name': invoice_ref}) else: for order, il in val: diff --git a/addons/sale/wizard/sale_line_invoice.py b/addons/sale/wizard/sale_line_invoice.py index 8bb52b12c1e..656e21a2963 100644 --- a/addons/sale/wizard/sale_line_invoice.py +++ b/addons/sale/wizard/sale_line_invoice.py @@ -25,6 +25,7 @@ from openerp.tools.translate import _ class sale_order_line_make_invoice(osv.osv_memory): _name = "sale.order.line.make.invoice" _description = "Sale OrderLine Make_invoice" + def make_invoices(self, cr, uid, ids, context=None): """ To make invoices. @@ -81,34 +82,30 @@ class sale_order_line_make_invoice(osv.osv_memory): sales_order_obj = self.pool.get('sale.order') for line in sales_order_line_obj.browse(cr, uid, context.get('active_ids', []), context=context): if (not line.invoiced) and (line.state not in ('draft', 'cancel')): - if not line.order_id.id in invoices: - invoices[line.order_id.id] = [] - line_id = sales_order_line_obj.invoice_line_create(cr, uid, - [line.id]) + if not line.order_id in invoices: + invoices[line.order_id] = [] + line_id = sales_order_line_obj.invoice_line_create(cr, uid, [line.id]) for lid in line_id: - invoices[line.order_id.id].append((line, lid)) - for result in invoices.values(): - order = result[0][0].order_id - il = map(lambda x: x[1], result) + invoices[line.order_id].append(lid) + for order, il in invoices.items(): res = make_invoice(order, il) cr.execute('INSERT INTO sale_order_invoice_rel \ (order_id,invoice_id) values (%s,%s)', (order.id, res)) - flag = True - data_sale = sales_order_obj.browse(cr, uid, line.order_id.id, context=context) sales_order_obj.message_post(cr, uid, [order.id], body=_("Invoice created"), context=context) + data_sale = sales_order_obj.browse(cr, uid, order.id, context=context) for line in data_sale.order_line: if not line.invoiced: flag = False break if flag: - sales_order_obj.signal_manual_invoice(cr, uid, [line.order_id.id]) - sales_order_obj.write(cr, uid, [line.order_id.id], {'state': 'progress'}) + wf_service.trg_validate(uid, 'sale.order', order.id, 'manual_invoice', cr) + sales_order_obj.write(cr, uid, [order.id], {'state': 'progress'}) if not invoices: raise osv.except_osv(_('Warning!'), _('Invoice cannot be created for this Sales Order Line due to one of the following reasons:\n1.The state of this sales order line is either "draft" or "cancel"!\n2.The Sales Order Line is Invoiced!')) if context.get('open_invoices', False): - return self.open_invoices( cr, uid, ids, res, context=context) + return self.open_invoices(cr, uid, ids, res, context=context) return {'type': 'ir.actions.act_window_close'} def open_invoices(self, cr, uid, ids, invoice_ids, context=None): @@ -118,7 +115,7 @@ class sale_order_line_make_invoice(osv.osv_memory): form_id = form_res and form_res[1] or False tree_res = ir_model_data.get_object_reference(cr, uid, 'account', 'invoice_tree') tree_id = tree_res and tree_res[1] or False - + return { 'name': _('Invoice'), 'view_type': 'form', diff --git a/addons/sale/wizard/sale_make_invoice.py b/addons/sale/wizard/sale_make_invoice.py index 0898dad21b1..47716018caa 100644 --- a/addons/sale/wizard/sale_make_invoice.py +++ b/addons/sale/wizard/sale_make_invoice.py @@ -39,7 +39,7 @@ class sale_make_invoice(osv.osv_memory): record_id = context and context.get('active_id', False) order = self.pool.get('sale.order').browse(cr, uid, record_id, context=context) if order.state == 'draft': - raise osv.except_osv(_('Warning!'),'You cannot create invoice when sales order is not confirmed.') + raise osv.except_osv(_('Warning!'), _('You cannot create invoice when sales order is not confirmed.')) return False def make_invoices(self, cr, uid, ids, context=None): @@ -50,8 +50,11 @@ class sale_make_invoice(osv.osv_memory): if context is None: context = {} data = self.read(cr, uid, ids)[0] - order_obj.action_invoice_create(cr, uid, context.get(('active_ids'), []), data['grouped'], date_invoice = data['invoice_date']) - order_obj.signal_manual_invoice(cr, uid, context.get(('active_ids'), [])) + for sale_order in order_obj.browse(cr, uid, context.get(('active_ids'), []), context=context): + if sale_order.state != 'manual': + raise osv.except_osv(_('Warning!'), _("You shouldn't manually invoice the following sale order %s") % (sale_order.name)) + + order_obj.action_invoice_create(cr, uid, context.get(('active_ids'), []), data['grouped'], date_invoice=data['invoice_date']) for o in order_obj.browse(cr, uid, context.get(('active_ids'), []), context=context): for i in o.invoice_ids: @@ -60,7 +63,7 @@ class sale_make_invoice(osv.osv_memory): result = mod_obj.get_object_reference(cr, uid, 'account', 'action_invoice_tree1') id = result and result[1] or False result = act_obj.read(cr, uid, [id], context=context)[0] - result['domain'] = "[('id','in', ["+','.join(map(str,newinv))+"])]" + result['domain'] = "[('id','in', [" + ','.join(map(str, newinv)) + "])]" return result diff --git a/addons/sale/wizard/sale_make_invoice.xml b/addons/sale/wizard/sale_make_invoice.xml index ced64a0f79d..de680feb049 100644 --- a/addons/sale/wizard/sale_make_invoice.xml +++ b/addons/sale/wizard/sale_make_invoice.xml @@ -6,16 +6,16 @@ <field name="model">sale.make.invoice</field> <field name="arch" type="xml"> <form string="Create invoices" version="7.0"> - <header> - <button name="make_invoices" string="Create Invoices" type="object" class="oe_highlight" /> - or - <button string="Cancel" class="oe_link" special="cancel" /> - </header> <separator colspan="4" string="Do you really want to create the invoice(s)?" /> <group> <field name="grouped"/> <field name="invoice_date"/> </group> + <footer> + <button name="make_invoices" string="Create Invoices" type="object" class="oe_highlight"/> + or + <button string="Cancel" class="oe_link" special="cancel" /> + </footer> </form> </field> </record> diff --git a/addons/stock/wizard/stock_traceability.py b/addons/stock/wizard/stock_traceability.py index 123a76acd43..8d5fd1ed10d 100644 --- a/addons/stock/wizard/stock_traceability.py +++ b/addons/stock/wizard/stock_traceability.py @@ -53,6 +53,7 @@ class action_traceability(osv.osv_memory): 'domain': "[('id','in',["+','.join(map(str, ids))+"])]", 'name': ((type1=='move_history_ids2') and _('Upstream Traceability')) or _('Downstream Traceability'), 'view_mode': 'tree', + 'view_type': 'tree', 'res_model': 'stock.move', 'field_parent': type1, 'view_id': (view_id,'View'), |
