diff --git a/openerp/addons/base/i18n/af.po b/openerp/addons/base/i18n/af.po
index 72547d34bc1..87150c74641 100644
--- a/openerp/addons/base/i18n/af.po
+++ b/openerp/addons/base/i18n/af.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/am.po b/openerp/addons/base/i18n/am.po
index 7fa923c0660..31d0553c768 100644
--- a/openerp/addons/base/i18n/am.po
+++ b/openerp/addons/base/i18n/am.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/ar.po b/openerp/addons/base/i18n/ar.po
index b50c02ca98d..afe9a26e63a 100644
--- a/openerp/addons/base/i18n/ar.po
+++ b/openerp/addons/base/i18n/ar.po
@@ -5430,7 +5430,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/base.pot b/openerp/addons/base/i18n/base.pot
index 9484a376151..55c648f89af 100644
--- a/openerp/addons/base/i18n/base.pot
+++ b/openerp/addons/base/i18n/base.pot
@@ -5217,7 +5217,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/bg.po b/openerp/addons/base/i18n/bg.po
index 02da984c8b3..bb9f54a129d 100644
--- a/openerp/addons/base/i18n/bg.po
+++ b/openerp/addons/base/i18n/bg.po
@@ -5572,7 +5572,7 @@ msgstr "Преводи"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Брой на остъпката"
#. module: base
diff --git a/openerp/addons/base/i18n/bs.po b/openerp/addons/base/i18n/bs.po
index 80691631cf8..1cd99f744ad 100644
--- a/openerp/addons/base/i18n/bs.po
+++ b/openerp/addons/base/i18n/bs.po
@@ -5439,7 +5439,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/ca.po b/openerp/addons/base/i18n/ca.po
index 58c927285eb..6e9d7d6a6e7 100644
--- a/openerp/addons/base/i18n/ca.po
+++ b/openerp/addons/base/i18n/ca.po
@@ -5709,7 +5709,7 @@ msgstr "Traduccions"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Omplenat del número"
#. module: base
diff --git a/openerp/addons/base/i18n/cs.po b/openerp/addons/base/i18n/cs.po
index 1a20a156fe9..e356d0b0973 100644
--- a/openerp/addons/base/i18n/cs.po
+++ b/openerp/addons/base/i18n/cs.po
@@ -5529,7 +5529,7 @@ msgstr "Překlady"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Zarovnání čísla"
#. module: base
diff --git a/openerp/addons/base/i18n/da.po b/openerp/addons/base/i18n/da.po
index 2fa355ab21a..2968a29195b 100644
--- a/openerp/addons/base/i18n/da.po
+++ b/openerp/addons/base/i18n/da.po
@@ -5431,7 +5431,7 @@ msgstr "Oversættelser"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/de.po b/openerp/addons/base/i18n/de.po
index 4dbe8f4c0cf..c2fe1af3b93 100644
--- a/openerp/addons/base/i18n/de.po
+++ b/openerp/addons/base/i18n/de.po
@@ -5702,7 +5702,7 @@ msgstr "Übersetzungen"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Stellenanzahl"
#. module: base
diff --git a/openerp/addons/base/i18n/el.po b/openerp/addons/base/i18n/el.po
index 4bca6580496..9e5cc4245c9 100644
--- a/openerp/addons/base/i18n/el.po
+++ b/openerp/addons/base/i18n/el.po
@@ -5614,7 +5614,7 @@ msgstr "Μεταφράσεις"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Συμπλήρωση αριθμών"
#. module: base
diff --git a/openerp/addons/base/i18n/en_GB.po b/openerp/addons/base/i18n/en_GB.po
index 45a31676521..d013bbc9be6 100644
--- a/openerp/addons/base/i18n/en_GB.po
+++ b/openerp/addons/base/i18n/en_GB.po
@@ -5669,8 +5669,8 @@ msgstr "Translations"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
-msgstr "Number padding"
+msgid "Number Padding"
+msgstr "Number Padding"
#. module: base
#: view:ir.actions.report.xml:0
diff --git a/openerp/addons/base/i18n/es.po b/openerp/addons/base/i18n/es.po
index 75c938bb99f..b21773bb137 100644
--- a/openerp/addons/base/i18n/es.po
+++ b/openerp/addons/base/i18n/es.po
@@ -5723,7 +5723,7 @@ msgstr "Traducciones"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Relleno del número"
#. module: base
diff --git a/openerp/addons/base/i18n/es_AR.po b/openerp/addons/base/i18n/es_AR.po
index f22db5e97a5..3eac408dd86 100644
--- a/openerp/addons/base/i18n/es_AR.po
+++ b/openerp/addons/base/i18n/es_AR.po
@@ -4778,7 +4778,7 @@ msgstr "Traducciones"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Relleno del número"
#. module: base
diff --git a/openerp/addons/base/i18n/es_CL.po b/openerp/addons/base/i18n/es_CL.po
index 6a7b66979ae..6e1328dd1d4 100644
--- a/openerp/addons/base/i18n/es_CL.po
+++ b/openerp/addons/base/i18n/es_CL.po
@@ -5725,7 +5725,7 @@ msgstr "Traducciones"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Relleno del número"
#. module: base
diff --git a/openerp/addons/base/i18n/es_EC.po b/openerp/addons/base/i18n/es_EC.po
index 172217838e6..62371e70beb 100644
--- a/openerp/addons/base/i18n/es_EC.po
+++ b/openerp/addons/base/i18n/es_EC.po
@@ -5712,7 +5712,7 @@ msgstr "Traducciones"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Relleno del número"
#. module: base
diff --git a/openerp/addons/base/i18n/et.po b/openerp/addons/base/i18n/et.po
index 6062726cdc9..f5efbb2f667 100644
--- a/openerp/addons/base/i18n/et.po
+++ b/openerp/addons/base/i18n/et.po
@@ -5488,7 +5488,7 @@ msgstr "Tõlked"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Arvu täidistus"
#. module: base
diff --git a/openerp/addons/base/i18n/eu.po b/openerp/addons/base/i18n/eu.po
index 8b92327e5ac..0c1ac0ac100 100644
--- a/openerp/addons/base/i18n/eu.po
+++ b/openerp/addons/base/i18n/eu.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/fa.po b/openerp/addons/base/i18n/fa.po
index 584d51a545e..517a9b87e19 100644
--- a/openerp/addons/base/i18n/fa.po
+++ b/openerp/addons/base/i18n/fa.po
@@ -5496,7 +5496,7 @@ msgstr "برگردانها"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "پیمایش شمارگانی"
#. module: base
diff --git a/openerp/addons/base/i18n/fa_AF.po b/openerp/addons/base/i18n/fa_AF.po
index d730070ecf9..1e0010a8fb4 100644
--- a/openerp/addons/base/i18n/fa_AF.po
+++ b/openerp/addons/base/i18n/fa_AF.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/fi.po b/openerp/addons/base/i18n/fi.po
index 16526bf9807..c47ec894821 100644
--- a/openerp/addons/base/i18n/fi.po
+++ b/openerp/addons/base/i18n/fi.po
@@ -5664,7 +5664,7 @@ msgstr "Käännökset"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Täytenumerot"
#. module: base
diff --git a/openerp/addons/base/i18n/fr.po b/openerp/addons/base/i18n/fr.po
index 6fb9188fd3c..6ce408bc01a 100644
--- a/openerp/addons/base/i18n/fr.po
+++ b/openerp/addons/base/i18n/fr.po
@@ -5717,7 +5717,7 @@ msgstr "Traductions"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Remplissage"
#. module: base
diff --git a/openerp/addons/base/i18n/gl.po b/openerp/addons/base/i18n/gl.po
index 8547223c29c..b2e33836902 100644
--- a/openerp/addons/base/i18n/gl.po
+++ b/openerp/addons/base/i18n/gl.po
@@ -5695,7 +5695,7 @@ msgstr "Traducións"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Número de enchido"
#. module: base
diff --git a/openerp/addons/base/i18n/he.po b/openerp/addons/base/i18n/he.po
index 0e14797c6ee..07fda35ca86 100644
--- a/openerp/addons/base/i18n/he.po
+++ b/openerp/addons/base/i18n/he.po
@@ -5472,7 +5472,7 @@ msgstr "תרגומים"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/hr.po b/openerp/addons/base/i18n/hr.po
index e82d8fb80cc..f7186b309ac 100644
--- a/openerp/addons/base/i18n/hr.po
+++ b/openerp/addons/base/i18n/hr.po
@@ -5553,7 +5553,7 @@ msgstr "Prijevodi"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Dopunjavanje na duljinu"
#. module: base
diff --git a/openerp/addons/base/i18n/hu.po b/openerp/addons/base/i18n/hu.po
index 043b188ece7..35e0b0fb423 100644
--- a/openerp/addons/base/i18n/hu.po
+++ b/openerp/addons/base/i18n/hu.po
@@ -5666,8 +5666,8 @@ msgstr "Fordítások"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
-msgstr "Number padding"
+msgid "Number Padding"
+msgstr "Number Padding"
#. module: base
#: view:ir.actions.report.xml:0
diff --git a/openerp/addons/base/i18n/hy.po b/openerp/addons/base/i18n/hy.po
index f47eb825bc2..2ab57b9b7fa 100644
--- a/openerp/addons/base/i18n/hy.po
+++ b/openerp/addons/base/i18n/hy.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/id.po b/openerp/addons/base/i18n/id.po
index 969f42eb804..dc1d81aa8bb 100644
--- a/openerp/addons/base/i18n/id.po
+++ b/openerp/addons/base/i18n/id.po
@@ -5435,7 +5435,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/is.po b/openerp/addons/base/i18n/is.po
index f0973c0a8e4..6f29f97bb15 100644
--- a/openerp/addons/base/i18n/is.po
+++ b/openerp/addons/base/i18n/is.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/it.po b/openerp/addons/base/i18n/it.po
index 3a106c0498a..bbd01e7eaaf 100644
--- a/openerp/addons/base/i18n/it.po
+++ b/openerp/addons/base/i18n/it.po
@@ -5713,7 +5713,7 @@ msgstr "Traduzioni"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Riempimento Numero"
#. module: base
diff --git a/openerp/addons/base/i18n/ja.po b/openerp/addons/base/i18n/ja.po
index 2d6310e5312..b3f7126abf8 100644
--- a/openerp/addons/base/i18n/ja.po
+++ b/openerp/addons/base/i18n/ja.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/kk.po b/openerp/addons/base/i18n/kk.po
index 1df9844334b..2473306dac8 100644
--- a/openerp/addons/base/i18n/kk.po
+++ b/openerp/addons/base/i18n/kk.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/ko.po b/openerp/addons/base/i18n/ko.po
index 0025fb970e6..d4552dceb23 100644
--- a/openerp/addons/base/i18n/ko.po
+++ b/openerp/addons/base/i18n/ko.po
@@ -5457,7 +5457,7 @@ msgstr "번역"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/lt.po b/openerp/addons/base/i18n/lt.po
index 2a31023df0f..f497c904fbd 100644
--- a/openerp/addons/base/i18n/lt.po
+++ b/openerp/addons/base/i18n/lt.po
@@ -5464,7 +5464,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/lt_LT.po b/openerp/addons/base/i18n/lt_LT.po
index 7aee4518a19..5c98c806928 100644
--- a/openerp/addons/base/i18n/lt_LT.po
+++ b/openerp/addons/base/i18n/lt_LT.po
@@ -4618,7 +4618,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/lv.po b/openerp/addons/base/i18n/lv.po
index cd1ef4c77fe..8b654b76800 100644
--- a/openerp/addons/base/i18n/lv.po
+++ b/openerp/addons/base/i18n/lv.po
@@ -5514,7 +5514,7 @@ msgstr "Tulkojumi"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Ciparu vietas"
#. module: base
diff --git a/openerp/addons/base/i18n/mk.po b/openerp/addons/base/i18n/mk.po
index bb8f47fcf7c..d9b5395a888 100644
--- a/openerp/addons/base/i18n/mk.po
+++ b/openerp/addons/base/i18n/mk.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/mn.po b/openerp/addons/base/i18n/mn.po
index 12c8460790f..fa355ed7b11 100644
--- a/openerp/addons/base/i18n/mn.po
+++ b/openerp/addons/base/i18n/mn.po
@@ -5533,7 +5533,7 @@ msgstr "Орчуулгууд"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Тоон дугаарын урт"
#. module: base
diff --git a/openerp/addons/base/i18n/nb.po b/openerp/addons/base/i18n/nb.po
index c62673f2b19..17bc1c0e472 100644
--- a/openerp/addons/base/i18n/nb.po
+++ b/openerp/addons/base/i18n/nb.po
@@ -5530,7 +5530,7 @@ msgstr "Oversettelser"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Bunnfyll"
#. module: base
diff --git a/openerp/addons/base/i18n/nl.po b/openerp/addons/base/i18n/nl.po
index 2bb60f29b38..831941c72a6 100644
--- a/openerp/addons/base/i18n/nl.po
+++ b/openerp/addons/base/i18n/nl.po
@@ -5702,7 +5702,7 @@ msgstr "Vertalingen"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Nummer verspringing"
#. module: base
diff --git a/openerp/addons/base/i18n/nl_BE.po b/openerp/addons/base/i18n/nl_BE.po
index 09b17071edd..aba44535fa2 100644
--- a/openerp/addons/base/i18n/nl_BE.po
+++ b/openerp/addons/base/i18n/nl_BE.po
@@ -5447,7 +5447,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/nl_NL.po b/openerp/addons/base/i18n/nl_NL.po
index 704c25a9d46..eeef0f9010e 100644
--- a/openerp/addons/base/i18n/nl_NL.po
+++ b/openerp/addons/base/i18n/nl_NL.po
@@ -4796,7 +4796,7 @@ msgstr "Vertalingen"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Nummer verspringing"
#. module: base
diff --git a/openerp/addons/base/i18n/pl.po b/openerp/addons/base/i18n/pl.po
index 9b8f0c8769c..417976cebd6 100644
--- a/openerp/addons/base/i18n/pl.po
+++ b/openerp/addons/base/i18n/pl.po
@@ -5612,7 +5612,7 @@ msgstr "Tłumaczenia"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Liczba cyfr"
#. module: base
diff --git a/openerp/addons/base/i18n/pt.po b/openerp/addons/base/i18n/pt.po
index 88b097ffe71..03f8b93ede1 100644
--- a/openerp/addons/base/i18n/pt.po
+++ b/openerp/addons/base/i18n/pt.po
@@ -5591,7 +5591,7 @@ msgstr "Traduções"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Dígitos do número"
#. module: base
diff --git a/openerp/addons/base/i18n/pt_BR.po b/openerp/addons/base/i18n/pt_BR.po
index 254c642a060..e8c5a66dada 100644
--- a/openerp/addons/base/i18n/pt_BR.po
+++ b/openerp/addons/base/i18n/pt_BR.po
@@ -5687,7 +5687,7 @@ msgstr "Traduções"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Preencher número"
#. module: base
diff --git a/openerp/addons/base/i18n/ro.po b/openerp/addons/base/i18n/ro.po
index 7f6e34b2edc..5d1f4e6012d 100644
--- a/openerp/addons/base/i18n/ro.po
+++ b/openerp/addons/base/i18n/ro.po
@@ -5555,7 +5555,7 @@ msgstr "Traduceri"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/ru.po b/openerp/addons/base/i18n/ru.po
index 48133981214..33388d00882 100644
--- a/openerp/addons/base/i18n/ru.po
+++ b/openerp/addons/base/i18n/ru.po
@@ -5689,7 +5689,7 @@ msgstr "Переводы"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Выравнивание чисел"
#. module: base
diff --git a/openerp/addons/base/i18n/sk.po b/openerp/addons/base/i18n/sk.po
index df5f44b9ef4..267dc5a9223 100644
--- a/openerp/addons/base/i18n/sk.po
+++ b/openerp/addons/base/i18n/sk.po
@@ -5598,7 +5598,7 @@ msgstr "Preklady"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Zarovanie čísla"
#. module: base
diff --git a/openerp/addons/base/i18n/sl.po b/openerp/addons/base/i18n/sl.po
index 22d06500f88..5e6d5eb5119 100644
--- a/openerp/addons/base/i18n/sl.po
+++ b/openerp/addons/base/i18n/sl.po
@@ -5650,7 +5650,7 @@ msgstr "Prevodi"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Zapolnitev številke"
#. module: base
diff --git a/openerp/addons/base/i18n/sq.po b/openerp/addons/base/i18n/sq.po
index 4d38cd56221..bb97ede3852 100644
--- a/openerp/addons/base/i18n/sq.po
+++ b/openerp/addons/base/i18n/sq.po
@@ -5430,7 +5430,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/sr.po b/openerp/addons/base/i18n/sr.po
index 04a1487c320..b174a0b5a2b 100644
--- a/openerp/addons/base/i18n/sr.po
+++ b/openerp/addons/base/i18n/sr.po
@@ -5575,7 +5575,7 @@ msgstr "Prevodi"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Dopunjavanje brojeva"
#. module: base
diff --git a/openerp/addons/base/i18n/sr@latin.po b/openerp/addons/base/i18n/sr@latin.po
index a545d3854a8..2aeaeb0279b 100644
--- a/openerp/addons/base/i18n/sr@latin.po
+++ b/openerp/addons/base/i18n/sr@latin.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/sv.po b/openerp/addons/base/i18n/sv.po
index 5dd00cab0ba..9422185f5da 100644
--- a/openerp/addons/base/i18n/sv.po
+++ b/openerp/addons/base/i18n/sv.po
@@ -5624,7 +5624,7 @@ msgstr "Översättningar"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Numerisk utfyllnad"
#. module: base
diff --git a/openerp/addons/base/i18n/th.po b/openerp/addons/base/i18n/th.po
index d785c5d635b..312b25c8e63 100644
--- a/openerp/addons/base/i18n/th.po
+++ b/openerp/addons/base/i18n/th.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/tlh.po b/openerp/addons/base/i18n/tlh.po
index dede310a722..226f568ed46 100644
--- a/openerp/addons/base/i18n/tlh.po
+++ b/openerp/addons/base/i18n/tlh.po
@@ -5430,7 +5430,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/tr.po b/openerp/addons/base/i18n/tr.po
index a1661ed041e..4311bcb01a8 100644
--- a/openerp/addons/base/i18n/tr.po
+++ b/openerp/addons/base/i18n/tr.po
@@ -5637,7 +5637,7 @@ msgstr "Çeviriler"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Numara dolgusu"
#. module: base
diff --git a/openerp/addons/base/i18n/uk.po b/openerp/addons/base/i18n/uk.po
index a024978394c..6c1f6ffeb02 100644
--- a/openerp/addons/base/i18n/uk.po
+++ b/openerp/addons/base/i18n/uk.po
@@ -5495,7 +5495,7 @@ msgstr "Переклади"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Вирівнювання номерів"
#. module: base
diff --git a/openerp/addons/base/i18n/uk_UA.po b/openerp/addons/base/i18n/uk_UA.po
index c1923fd44a9..c984308a4de 100644
--- a/openerp/addons/base/i18n/uk_UA.po
+++ b/openerp/addons/base/i18n/uk_UA.po
@@ -4636,7 +4636,7 @@ msgstr "Переклади"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "Вирівнювання номерів"
#. module: base
diff --git a/openerp/addons/base/i18n/ur.po b/openerp/addons/base/i18n/ur.po
index 2457121dad1..4deaed2489c 100644
--- a/openerp/addons/base/i18n/ur.po
+++ b/openerp/addons/base/i18n/ur.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/vi.po b/openerp/addons/base/i18n/vi.po
index 417c64daba6..ba03de09502 100644
--- a/openerp/addons/base/i18n/vi.po
+++ b/openerp/addons/base/i18n/vi.po
@@ -5468,7 +5468,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/zh_CN.po b/openerp/addons/base/i18n/zh_CN.po
index ccc8619e189..a633854008f 100644
--- a/openerp/addons/base/i18n/zh_CN.po
+++ b/openerp/addons/base/i18n/zh_CN.po
@@ -5471,7 +5471,7 @@ msgstr "翻译"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr "数字位数"
#. module: base
diff --git a/openerp/addons/base/i18n/zh_HK.po b/openerp/addons/base/i18n/zh_HK.po
index a1f9b2babf3..0c61107986b 100644
--- a/openerp/addons/base/i18n/zh_HK.po
+++ b/openerp/addons/base/i18n/zh_HK.po
@@ -5431,7 +5431,7 @@ msgstr ""
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/i18n/zh_TW.po b/openerp/addons/base/i18n/zh_TW.po
index 04b75725807..fab8a5bcba9 100644
--- a/openerp/addons/base/i18n/zh_TW.po
+++ b/openerp/addons/base/i18n/zh_TW.po
@@ -5447,7 +5447,7 @@ msgstr "翻譯"
#. module: base
#: field:ir.sequence,padding:0
-msgid "Number padding"
+msgid "Number Padding"
msgstr ""
#. module: base
diff --git a/openerp/addons/base/ir/ir.xml b/openerp/addons/base/ir/ir.xml
index 2792259773d..79490542b1c 100644
--- a/openerp/addons/base/ir/ir.xml
+++ b/openerp/addons/base/ir/ir.xml
@@ -176,6 +176,7 @@
+
@@ -215,6 +216,7 @@
+
diff --git a/openerp/addons/base/ir/ir_sequence.py b/openerp/addons/base/ir/ir_sequence.py
index 4267e92d54d..51b57a2ffbe 100644
--- a/openerp/addons/base/ir/ir_sequence.py
+++ b/openerp/addons/base/ir/ir_sequence.py
@@ -19,83 +19,252 @@
#
##############################################################################
+import logging
import time
-from osv import fields,osv
-import pooler
-class ir_sequence_type(osv.osv):
+import openerp
+
+_logger = logging.getLogger('ir_sequence')
+
+class ir_sequence_type(openerp.osv.osv.osv):
_name = 'ir.sequence.type'
_order = 'name'
_columns = {
- 'name': fields.char('Name',size=64, required=True),
- 'code': fields.char('Code',size=32, required=True),
+ 'name': openerp.osv.fields.char('Name', size=64, required=True),
+ 'code': openerp.osv.fields.char('Code', size=32, required=True),
}
-ir_sequence_type()
+
+ _sql_constraints = [
+ ('code_unique', 'unique(code)', '`code` must be unique.'),
+ ]
def _code_get(self, cr, uid, context={}):
cr.execute('select code, name from ir_sequence_type')
return cr.fetchall()
-class ir_sequence(osv.osv):
+class ir_sequence(openerp.osv.osv.osv):
+ """ Sequence model.
+
+ The sequence model allows to define and use so-called sequence objects.
+ Such objects are used to generate unique identifiers in a transaction-safe
+ way.
+
+ """
_name = 'ir.sequence'
_order = 'name'
_columns = {
- 'name': fields.char('Name',size=64, required=True),
- 'code': fields.selection(_code_get, 'Code',size=64, required=True),
- 'active': fields.boolean('Active'),
- 'prefix': fields.char('Prefix',size=64, help="Prefix value of the record for the sequence"),
- 'suffix': fields.char('Suffix',size=64, help="Suffix value of the record for the sequence"),
- 'number_next': fields.integer('Next Number', required=True, help="Next number of this sequence"),
- 'number_increment': fields.integer('Increment Number', required=True, help="The next number of the sequence will be incremented by this number"),
- 'padding' : fields.integer('Number padding', required=True, help="OpenERP will automatically adds some '0' on the left of the 'Next Number' to get the required padding size."),
- 'company_id': fields.many2one('res.company', 'Company'),
+ 'name': openerp.osv.fields.char('Name', size=64, required=True),
+ 'code': openerp.osv.fields.selection(_code_get, 'Code', size=64, required=True),
+ 'implementation': openerp.osv.fields.selection( # TODO update the view
+ [('standard', 'Standard'), ('no_gap', 'No gap')],
+ 'Implementation', required=True,
+ help="Two sequence object implementations are offered: Standard "
+ "and 'No gap'. The later is slower than the former but forbids any"
+ " gap in the sequence (while they are possible in the former)."),
+ 'active': openerp.osv.fields.boolean('Active'),
+ 'prefix': openerp.osv.fields.char('Prefix', size=64, help="Prefix value of the record for the sequence"),
+ 'suffix': openerp.osv.fields.char('Suffix', size=64, help="Suffix value of the record for the sequence"),
+ 'number_next': openerp.osv.fields.integer('Next Number', required=True, help="Next number of this sequence"),
+ 'number_increment': openerp.osv.fields.integer('Increment Number', required=True, help="The next number of the sequence will be incremented by this number"),
+ 'padding' : openerp.osv.fields.integer('Number Padding', required=True, help="OpenERP will automatically adds some '0' on the left of the 'Next Number' to get the required padding size."),
+ 'company_id': openerp.osv.fields.many2one('res.company', 'Company'),
}
_defaults = {
- 'active': lambda *a: True,
+ 'implementation': 'standard',
+ 'active': True,
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'ir.sequence', context=c),
- 'number_increment': lambda *a: 1,
- 'number_next': lambda *a: 1,
- 'padding' : lambda *a : 0,
+ 'number_increment': 1,
+ 'number_next': 1,
+ 'padding' : 0,
}
- def _process(self, s):
- return (s or '') % {
- 'year':time.strftime('%Y'),
- 'month': time.strftime('%m'),
- 'day':time.strftime('%d'),
- 'y': time.strftime('%y'),
- 'doy': time.strftime('%j'),
- 'woy': time.strftime('%W'),
- 'weekday': time.strftime('%w'),
- 'h24': time.strftime('%H'),
- 'h12': time.strftime('%I'),
- 'min': time.strftime('%M'),
- 'sec': time.strftime('%S'),
+ def init(self, cr):
+ return # Don't do the following index yet.
+ # CONSTRAINT/UNIQUE INDEX on (code, company_id)
+ # /!\ The unique constraint 'unique_name_company_id' is not sufficient, because SQL92
+ # only support field names in constraint definitions, and we need a function here:
+ # we need to special-case company_id to treat all NULL company_id as equal, otherwise
+ # we would allow duplicate (code, NULL) ir_sequences.
+ cr.execute("""
+ SELECT indexname FROM pg_indexes WHERE indexname =
+ 'ir_sequence_unique_code_company_id_idx'""")
+ if not cr.fetchone():
+ cr.execute("""
+ CREATE UNIQUE INDEX ir_sequence_unique_code_company_id_idx
+ ON ir_sequence (code, (COALESCE(company_id,-1)))""")
+
+ def _create_sequence(self, cr, id, number_increment, number_next):
+ """ Create a PostreSQL sequence.
+
+ There is no access rights check.
+ """
+ assert isinstance(id, (int, long))
+ sql = "CREATE SEQUENCE ir_sequence_%03d INCREMENT BY %%s START WITH %%s" % id
+ cr.execute(sql, (number_increment, number_next))
+
+ def _drop_sequence(self, cr, ids):
+ """ Drop the PostreSQL sequence if it exists.
+
+ There is no access rights check.
+ """
+
+ ids = ids if isinstance(ids, (list, tuple)) else [ids]
+ assert all(isinstance(i, (int, long)) for i in ids), \
+ "Only ids in (int, long) allowed."
+ names = ','.join('ir_sequence_%03d' % i for i in ids)
+
+ # RESTRICT is the default; it prevents dropping the sequence if an
+ # object depends on it.
+ cr.execute("DROP SEQUENCE IF EXISTS %s RESTRICT " % names)
+
+ def _alter_sequence(self, cr, id, number_increment, number_next):
+ """ Alter a PostreSQL sequence.
+
+ There is no access rights check.
+ """
+ assert isinstance(id, (int, long))
+ cr.execute("""
+ ALTER SEQUENCE ir_sequence_%03d INCREMENT BY %%s RESTART WITH %%s
+ """ % id, (number_increment, number_next))
+
+ def create(self, cr, uid, values, context=None):
+ """ Create a sequence, in implementation == standard a fast gaps-allowed PostgreSQL sequence is used.
+ """
+ values = self._add_missing_default_values(cr, uid, values, context)
+ values['id'] = super(ir_sequence, self).create(cr, uid, values, context)
+ if values['implementation'] == 'standard':
+ f = self._create_sequence(cr, values['id'], values['number_increment'], values['number_next'])
+ return values['id']
+
+ def unlink(self, cr, uid, ids, context=None):
+ super(ir_sequence, self).unlink(cr, uid, ids, context)
+ self._drop_sequence(cr, ids)
+ return True
+
+ def write(self, cr, uid, ids, values, context=None):
+ if not isinstance(ids, (list, tuple)):
+ ids = [ids]
+ new_implementation = values.get('implementation')
+ rows = self.read(cr, uid, ids, ['implementation', 'number_increment', 'number_next'], context)
+ super(ir_sequence, self).write(cr, uid, ids, values, context)
+
+ for row in rows:
+ # 4 cases: we test the previous impl. against the new one.
+ if row['implementation'] == 'standard':
+ i = values.get('number_increment', row['number_increment'])
+ n = values.get('number_next', row['number_next'])
+ if new_implementation in ('standard', None):
+ self._alter_sequence(cr, row['id'], i, n)
+ else:
+ self._drop_sequence(cr, row['id'])
+ else:
+ if new_implementation in ('no_gap', None):
+ pass
+ else:
+ self._create_sequence(cr, row['id'], i, n)
+
+ return True
+
+ def _interpolate(self, s, d):
+ if s:
+ return s % d
+ return ''
+
+ def _interpolation_dict(self):
+ t = time.localtime() # Actually, the server is always in UTC.
+ return {
+ 'year': time.strftime('%Y', t),
+ 'month': time.strftime('%m', t),
+ 'day': time.strftime('%d', t),
+ 'y': time.strftime('%y', t),
+ 'doy': time.strftime('%j', t),
+ 'woy': time.strftime('%W', t),
+ 'weekday': time.strftime('%w', t),
+ 'h24': time.strftime('%H', t),
+ 'h12': time.strftime('%I', t),
+ 'min': time.strftime('%M', t),
+ 'sec': time.strftime('%S', t),
}
- def get_id(self, cr, uid, sequence_id, test='id', context=None):
- assert test in ('code','id')
- company_ids = self.pool.get('res.company').search(cr, uid, [], context=context)
- cr.execute('''SELECT id, number_next, prefix, suffix, padding
- FROM ir_sequence
- WHERE %s=%%s
- AND active=true
- AND (company_id in %%s or company_id is NULL)
- ORDER BY company_id, id
- FOR UPDATE NOWAIT''' % test,
- (sequence_id, tuple(company_ids)))
- res = cr.dictfetchone()
- if res:
- cr.execute('UPDATE ir_sequence SET number_next=number_next+number_increment WHERE id=%s AND active=true', (res['id'],))
- if res['number_next']:
- return self._process(res['prefix']) + '%%0%sd' % res['padding'] % res['number_next'] + self._process(res['suffix'])
- else:
- return self._process(res['prefix']) + self._process(res['suffix'])
- return False
+ def _select_by_code_or_id(self, cr, uid, sequence_code_or_id, code_or_id, for_update_no_wait, context=None):
+ """ Read a sequence object.
- def get(self, cr, uid, code):
- return self.get_id(cr, uid, code, test='code')
-ir_sequence()
+ There is no access rights check on the sequence itself.
+ """
+ assert code_or_id in ('code', 'id')
+ res_company = self.pool.get('res.company')
+ company_ids = res_company.search(cr, uid, [], context=context)
+ sql = """
+ SELECT id, number_next, prefix, suffix, padding, implementation
+ FROM ir_sequence
+ WHERE %s=%%s
+ AND active=true
+ AND (company_id in %%s or company_id is NULL)
+ """ % code_or_id
+ if for_update_no_wait:
+ sql += 'FOR UPDATE NOWAIT'
+ cr.execute(sql, (sequence_code_or_id, tuple(company_ids)))
+ return cr.dictfetchone()
+
+ def _next(self, cr, uid, sequence, context=None):
+ if not sequence:
+ return False
+
+ if sequence['implementation'] == 'standard':
+ cr.execute("SELECT nextval('ir_sequence_%03d')" % sequence['id'])
+ sequence['number_next'] = cr.fetchone()
+ else:
+ # Read again with FOR UPDATE NO WAIT.
+ sequence = self._select_by_code_or_id(cr, uid, sequence['id'], 'id', True, context)
+ cr.execute("""
+ UPDATE ir_sequence
+ SET number_next=number_next+number_increment
+ WHERE id=%s
+ """, (sequence['id'],))
+
+ d = self._interpolation_dict()
+ interpolated_prefix = self._interpolate(sequence['prefix'], d)
+ interpolated_suffix = self._interpolate(sequence['suffix'], d)
+ if sequence['number_next']:
+ return interpolated_prefix + '%%0%sd' % sequence['padding'] % \
+ sequence['number_next'] + interpolated_suffix
+ else:
+ # TODO what is this case used for ?
+ return interpolated_prefix + interpolated_suffix
+
+ def next_by_id(self, cr, uid, sequence_id, context=None):
+ """ Draw an interpolated string using the specified sequence."""
+ self.check_read(cr, uid)
+ res = self._select_by_code_or_id(cr, uid, sequence_id, 'id', False, context)
+ return self._next(cr, uid, res, context)
+
+ def next_by_code(self, cr, uid, sequence_code, context=None):
+ """ Draw an interpolated string using the specified sequence."""
+ self.check_read(cr, uid)
+ res = self._select_by_code_or_id(cr, uid, sequence_code, 'code', False, context)
+ return self._next(cr, uid, res, context)
+
+ def get_id(self, cr, uid, sequence_code_or_id, code_or_id='id', context=None):
+ """ Draw an interpolated string using the specified sequence.
+
+ The sequence to use is specified by the ``sequence_code_or_id``
+ argument, which can be a code or an id (as controlled by the
+ ``code_or_id`` argument. This method is deprecated.
+ """
+ _logger.warning("ir_sequence.get() and ir_sequence.get_id() are deprecated. "
+ "Please use ir_sequence.next_by_code() or ir_sequence.next_by_id().")
+ if code_or_id == 'id':
+ return self.next_by_id(cr, uid, sequence_code_or_id, context)
+ else:
+ return self.next_by_code(cr, uid, sequence_code_or_id, context)
+
+ def get(self, cr, uid, code, context=None):
+ """ Draw an interpolated string using the specified sequence.
+
+ The sequence to use is specified by its code. This method is
+ deprecated.
+ """
+ return self.get_id(cr, uid, code, 'code', context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/tests/common.py b/tests/common.py
new file mode 100644
index 00000000000..9f51f7b595e
--- /dev/null
+++ b/tests/common.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+import os
+import time
+import unittest2
+import xmlrpclib
+
+import openerp
+
+ADDONS_PATH = os.environ['OPENERP_ADDONS_PATH']
+PORT = int(os.environ['OPENERP_PORT'])
+DB = os.environ['OPENERP_DATABASE']
+
+HOST = '127.0.0.1'
+
+ADMIN_USER = 'admin'
+ADMIN_USER_ID = 1
+ADMIN_PASSWORD = 'admin'
+
+common_proxy_60 = None
+db_proxy_60 = None
+object_proxy_60 = None
+
+common_proxy_61 = None
+db_proxy_61 = None
+model_proxy_61 = None
+
+def setUpModule():
+ """
+ Start the OpenERP server similary to the openerp-server script and
+ setup some xmlrpclib proxies.
+ """
+ openerp.tools.config['addons_path'] = ADDONS_PATH
+ openerp.tools.config['xmlrpc_port'] = PORT
+ openerp.service.start_services()
+
+ global common_proxy_60
+ global db_proxy_60
+ global object_proxy_60
+
+ # Use the old (pre 6.1) API.
+ url = 'http://%s:%d/xmlrpc/' % (HOST, PORT)
+ common_proxy_60 = xmlrpclib.ServerProxy(url + 'common')
+ db_proxy_60 = xmlrpclib.ServerProxy(url + 'db')
+ object_proxy_60 = xmlrpclib.ServerProxy(url + 'object')
+
+ global common_proxy_61
+ global db_proxy_61
+ global model_proxy_61
+
+ # Use the new (6.1) API.
+ url = 'http://%s:%d/openerp/6.1/xmlrpc/' % (HOST, PORT)
+ common_proxy_61 = xmlrpclib.ServerProxy(url + 'common')
+ db_proxy_61 = xmlrpclib.ServerProxy(url + 'db')
+ model_proxy_61 = xmlrpclib.ServerProxy(url + 'model/' + DB)
+
+
+ # Ugly way to ensure the server is listening.
+ time.sleep(2)
+
+def tearDownModule():
+ """ Shutdown the OpenERP server similarly to a single ctrl-c. """
+ openerp.service.stop_services()
diff --git a/tests/test_ir_sequence.py b/tests/test_ir_sequence.py
new file mode 100644
index 00000000000..8a4731d524f
--- /dev/null
+++ b/tests/test_ir_sequence.py
@@ -0,0 +1,198 @@
+# -*- coding: utf-8 -*-
+# Run with one of these commands:
+# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \
+# OPENERP_DATABASE=yy PYTHONPATH=. python tests/test_ir_sequence.py
+# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \
+# OPENERP_DATABASE=yy nosetests tests/test_ir_sequence.py
+# > OPENERP_ADDONS_PATH='../../../addons/trunk' OPENERP_PORT=8069 \
+# OPENERP_DATABASE=yy PYTHONPATH=../:. unit2 test_ir_sequence
+# This assume an existing database.
+import os
+import psycopg2
+import time
+import unittest2
+import xmlrpclib
+
+import openerp
+import common
+
+DB = common.DB
+ADMIN_USER_ID = common.ADMIN_USER_ID
+
+setUpModule = common.setUpModule
+tearDownModule = common.tearDownModule
+
+def registry(model):
+ return openerp.modules.registry.RegistryManager.get(DB)[model]
+
+def cursor():
+ return openerp.modules.registry.RegistryManager.get(DB).db.cursor()
+
+class test_ir_sequence_standard(unittest2.TestCase):
+ """ A few tests for a 'Standard' (i.e. PostgreSQL) sequence. """
+
+ def test_ir_sequence_create(self):
+ """ Try to create a sequence object. """
+ cr = cursor()
+ d = dict(code='test_sequence_type', name='Test sequence type')
+ c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ d = dict(code='test_sequence_type', name='Test sequence')
+ c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ cr.commit()
+ cr.close()
+
+ def test_ir_sequence_search(self):
+ """ Try a search. """
+ cr = cursor()
+ ids = registry('ir.sequence').search(cr, ADMIN_USER_ID, [], {})
+ assert ids
+ cr.commit()
+ cr.close()
+
+ def test_ir_sequence_draw(self):
+ """ Try to draw a number. """
+ cr = cursor()
+ n = registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type', {})
+ assert n
+ cr.commit()
+ cr.close()
+
+ def test_ir_sequence_draw_twice(self):
+ """ Try to draw a number from two transactions. """
+ cr0 = cursor()
+ cr1 = cursor()
+ n0 = registry('ir.sequence').get(cr0, ADMIN_USER_ID, 'test_sequence_type', {})
+ assert n0
+ n1 = registry('ir.sequence').get(cr1, ADMIN_USER_ID, 'test_sequence_type', {})
+ assert n1
+ cr0.commit()
+ cr1.commit()
+ cr0.close()
+ cr1.close()
+
+class test_ir_sequence_no_gap(unittest2.TestCase):
+ """ Copy of the previous tests for a 'No gap' sequence. """
+
+ def test_ir_sequence_create_no_gap(self):
+ """ Try to create a sequence object. """
+ cr = cursor()
+ d = dict(code='test_sequence_type_2', name='Test sequence type')
+ c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ d = dict(code='test_sequence_type_2', name='Test sequence',
+ implementation='no_gap')
+ c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ cr.commit()
+ cr.close()
+
+ def test_ir_sequence_draw_no_gap(self):
+ """ Try to draw a number. """
+ cr = cursor()
+ n = registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type_2', {})
+ assert n
+ cr.commit()
+ cr.close()
+
+ def test_ir_sequence_draw_twice_no_gap(self):
+ """ Try to draw a number from two transactions.
+ This is expected to not work.
+ """
+ cr0 = cursor()
+ cr1 = cursor()
+ msg_re = '^could not obtain lock on row in relation "ir_sequence"$'
+ with self.assertRaisesRegexp(psycopg2.OperationalError, msg_re):
+ n0 = registry('ir.sequence').get(cr0, ADMIN_USER_ID, 'test_sequence_type_2', {})
+ assert n0
+ n1 = registry('ir.sequence').get(cr1, ADMIN_USER_ID, 'test_sequence_type_2', {})
+ cr0.close()
+ cr1.close()
+
+class test_ir_sequence_change_implementation(unittest2.TestCase):
+ """ Create sequence objects and change their ``implementation`` field. """
+
+ def test_ir_sequence_1_create(self):
+ """ Try to create a sequence object. """
+ cr = cursor()
+ d = dict(code='test_sequence_type_3', name='Test sequence type')
+ c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ d = dict(code='test_sequence_type_3', name='Test sequence')
+ c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ d = dict(code='test_sequence_type_4', name='Test sequence type')
+ c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ d = dict(code='test_sequence_type_4', name='Test sequence',
+ implementation='no_gap')
+ c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ cr.commit()
+ cr.close()
+
+ def test_ir_sequence_2_write(self):
+ cr = cursor()
+ ids = registry('ir.sequence').search(cr, ADMIN_USER_ID,
+ [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])], {})
+ registry('ir.sequence').write(cr, ADMIN_USER_ID, ids,
+ {'implementation': 'standard'}, {})
+ registry('ir.sequence').write(cr, ADMIN_USER_ID, ids,
+ {'implementation': 'no_gap'}, {})
+ cr.commit()
+ cr.close()
+
+ def test_ir_sequence_3_unlink(self):
+ cr = cursor()
+ ids = registry('ir.sequence').search(cr, ADMIN_USER_ID,
+ [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])], {})
+ registry('ir.sequence').unlink(cr, ADMIN_USER_ID, ids, {})
+ cr.commit()
+ cr.close()
+
+class test_ir_sequence_generate(unittest2.TestCase):
+ """ Create sequence objects and generate some values. """
+
+ def test_ir_sequence_create(self):
+ """ Try to create a sequence object. """
+ cr = cursor()
+ d = dict(code='test_sequence_type_5', name='Test sequence type')
+ c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ d = dict(code='test_sequence_type_5', name='Test sequence')
+ c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ cr.commit()
+ cr.close()
+
+ cr = cursor()
+ f = lambda *a: registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type_5', {})
+ assert all(str(x) == f() for x in xrange(1,1000))
+ cr.commit()
+ cr.close()
+
+ def test_ir_sequence_create_no_gap(self):
+ """ Try to create a sequence object. """
+ cr = cursor()
+ d = dict(code='test_sequence_type_6', name='Test sequence type',
+ implementation='no_gap')
+ c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ d = dict(code='test_sequence_type_6', name='Test sequence')
+ c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
+ assert c
+ cr.commit()
+ cr.close()
+
+ cr = cursor()
+ f = lambda *a: registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type_6', {})
+ assert all(str(x) == f() for x in xrange(1,1000))
+ cr.commit()
+ cr.close()
+
+
+
+if __name__ == '__main__':
+ unittest2.main()
+
diff --git a/tests/test_xmlrpc.py b/tests/test_xmlrpc.py
index f31efd24803..5cace01c9a9 100644
--- a/tests/test_xmlrpc.py
+++ b/tests/test_xmlrpc.py
@@ -12,60 +12,15 @@ import unittest2
import xmlrpclib
import openerp
+import common
-ADDONS_PATH = os.environ['OPENERP_ADDONS_PATH']
-PORT = int(os.environ['OPENERP_PORT'])
-DB = os.environ['OPENERP_DATABASE']
+DB = common.DB
+ADMIN_USER = common.ADMIN_USER
+ADMIN_USER_ID = common.ADMIN_USER_ID
+ADMIN_PASSWORD = common.ADMIN_PASSWORD
-HOST = '127.0.0.1'
-
-ADMIN_USER = 'admin'
-ADMIN_USER_ID = 1
-ADMIN_PASSWORD = 'admin'
-
-common_proxy_60 = None
-db_proxy_60 = None
-object_proxy_60 = None
-
-common_proxy_61 = None
-db_proxy_61 = None
-model_proxy_61 = None
-
-def setUpModule():
- """
- Start the OpenERP server similary to the openerp-server script and
- setup some xmlrpclib proxies.
- """
- openerp.tools.config['addons_path'] = ADDONS_PATH
- openerp.tools.config['xmlrpc_port'] = PORT
- openerp.service.start_services()
-
- global common_proxy_60
- global db_proxy_60
- global object_proxy_60
-
- global common_proxy_61
- global db_proxy_61
- global model_proxy_61
-
- # Use the old (pre 6.1) API.
- url = 'http://%s:%d/xmlrpc/' % (HOST, PORT)
- common_proxy_60 = xmlrpclib.ServerProxy(url + 'common')
- db_proxy_60 = xmlrpclib.ServerProxy(url + 'db')
- object_proxy_60 = xmlrpclib.ServerProxy(url + 'object')
-
- # Use the new (6.1) API.
- url = 'http://%s:%d/openerp/6.1/xmlrpc/' % (HOST, PORT)
- common_proxy_61 = xmlrpclib.ServerProxy(url + 'common')
- db_proxy_61 = xmlrpclib.ServerProxy(url + 'db')
- model_proxy_61 = xmlrpclib.ServerProxy(url + 'model/' + DB)
-
- # Mmm need to make sure the server is listening for XML-RPC requests.
- time.sleep(10)
-
-def tearDownModule():
- """ Shutdown the OpenERP server similarly to a single ctrl-c. """
- openerp.service.stop_services()
+setUpModule = common.setUpModule
+tearDownModule = common.tearDownModule
class test_xmlrpc(unittest2.TestCase):
@@ -74,34 +29,34 @@ class test_xmlrpc(unittest2.TestCase):
Simulate a OpenERP client requesting the creation of a database and
polling the server until the creation is complete.
"""
- progress_id = db_proxy_60.create(ADMIN_PASSWORD, DB, True, False,
- ADMIN_PASSWORD)
+ progress_id = common.db_proxy_60.create(ADMIN_PASSWORD, DB, True,
+ False, ADMIN_PASSWORD)
while True:
time.sleep(1)
- progress, users = db_proxy_60.get_progress(ADMIN_PASSWORD,
+ progress, users = common.db_proxy_60.get_progress(ADMIN_PASSWORD,
progress_id)
if progress == 1.0:
break
def test_xmlrpc_login(self):
""" Try to login on the common service. """
- uid = common_proxy_60.login(DB, ADMIN_USER, ADMIN_PASSWORD)
+ uid = common.common_proxy_60.login(DB, ADMIN_USER, ADMIN_PASSWORD)
assert uid == ADMIN_USER_ID
def test_xmlrpc_ir_model_search(self):
""" Try a search on the object service. """
- ids = object_proxy_60.execute(DB, ADMIN_USER_ID, ADMIN_PASSWORD,
+ ids = common.object_proxy_60.execute(DB, ADMIN_USER_ID, ADMIN_PASSWORD,
'ir.model', 'search', [])
assert ids
- ids = object_proxy_60.execute(DB, ADMIN_USER_ID, ADMIN_PASSWORD,
+ ids = common.object_proxy_60.execute(DB, ADMIN_USER_ID, ADMIN_PASSWORD,
'ir.model', 'search', [], {})
assert ids
def test_xmlrpc_61_ir_model_search(self):
""" Try a search on the object service. """
- ids = model_proxy_61.execute(ADMIN_USER_ID, ADMIN_PASSWORD, 'ir.model', 'search', [])
+ ids = common.model_proxy_61.execute(ADMIN_USER_ID, ADMIN_PASSWORD, 'ir.model', 'search', [])
assert ids
- ids = model_proxy_61.execute(ADMIN_USER_ID, ADMIN_PASSWORD, 'ir.model', 'search', [], {})
+ ids = common.model_proxy_61.execute(ADMIN_USER_ID, ADMIN_PASSWORD, 'ir.model', 'search', [], {})
assert ids
if __name__ == '__main__':