diff --git a/debian/control b/debian/control index ce0d3df55e1..f5d425c5586 100644 --- a/debian/control +++ b/debian/control @@ -16,6 +16,7 @@ Depends: python, postgresql-client, python-dateutil, + python-docutils, python-feedparser, python-gdata, python-ldap, diff --git a/openerp-server b/openerp-server index 12b6962e4e6..5d717c834de 100755 --- a/openerp-server +++ b/openerp-server @@ -30,7 +30,6 @@ GNU Public Licence. (c) 2003-TODAY, Fabien Pinckaers - OpenERP SA """ -import imp import logging import os import signal @@ -105,7 +104,7 @@ def run_test_file(dbname, test_file): db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False) cr = db.cursor() _logger.info('loading test file %s', test_file) - openerp.tools.convert_yaml_import(cr, 'base', file(test_file), {}, 'test', True) + openerp.tools.convert_yaml_import(cr, 'base', file(test_file), 'test', {}, 'test', True) cr.rollback() cr.close() except Exception: @@ -203,7 +202,7 @@ def quit_on_signals(): try: while quit_signals_received == 0: time.sleep(60) - except KeyboardInterrupt, e: + except KeyboardInterrupt: pass if config['pidfile']: diff --git a/openerp/__init__.py b/openerp/__init__.py index 7e723c41f9d..5827b744cf8 100644 --- a/openerp/__init__.py +++ b/openerp/__init__.py @@ -32,7 +32,6 @@ import modules import netsvc import osv import pooler -import pychart import release import report import run_tests diff --git a/openerp/addons/base/__init__.py b/openerp/addons/base/__init__.py index 16a61521fb4..d666a6abbf7 100644 --- a/openerp/addons/base/__init__.py +++ b/openerp/addons/base/__init__.py @@ -22,7 +22,6 @@ import ir import module import res -import publisher_warranty import report import test diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index 5b65bff4bd7..937c9cbd20b 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -25,20 +25,23 @@ 'name': 'Base', 'version': '1.3', 'category': 'Hidden', - 'description': """The kernel of OpenERP, needed for all installation.""", + 'description': """ +The kernel of OpenERP, needed for all installation. +=================================================== +""", 'author': 'OpenERP SA', 'maintainer': 'OpenERP SA', 'website': 'http://www.openerp.com', 'depends': [], - 'init_xml': [ + 'data': [ 'base_data.xml', + 'currency_data.xml', + 'country_data.xml', 'security/base_security.xml', 'base_menu.xml', 'res/res_security.xml', 'res/res_config.xml', - 'data/res.country.state.csv' - ], - 'update_xml': [ + 'data/res.country.state.csv', 'ir/wizard/wizard_menu_view.xml', 'ir/ir.xml', 'ir/ir_filters.xml', @@ -70,14 +73,12 @@ 'res/res_partner_data.xml', 'res/ir_property_view.xml', 'security/base_security.xml', - 'publisher_warranty/publisher_warranty_view.xml', 'security/ir.model.access.csv', 'security/ir.model.access-1.csv', # res.partner.address is deprecated; it is still there for backward compability only and will be removed in next version 'res/res_widget_view.xml', 'res/res_widget_data.xml', - 'publisher_warranty/publisher_warranty_data.xml', ], - 'demo_xml': [ + 'demo': [ 'base_demo.xml', 'res/res_partner_demo.xml', 'res/res_partner_demo.yml', diff --git a/openerp/addons/base/base_data.xml b/openerp/addons/base/base_data.xml index 0bf4fc9cdb5..2fa9910758d 100644 --- a/openerp/addons/base/base_data.xml +++ b/openerp/addons/base/base_data.xml @@ -29,1042 +29,15 @@ - - - United Arab Emirates - ae - - - Afghanistan, Islamic State of - af - - - Antigua and Barbuda - ag - - - Anguilla - ai - - - Albania - al - - - Armenia - am - - - Netherlands Antilles - an - - - Angola - ao - - - Antarctica - aq - - - Argentina - ar - - - American Samoa - as - - - Austria - at - - - Australia - au - - - - Aruba - aw - - - Åland Islands - ax - - - Azerbaijan - az - - - Bosnia-Herzegovina - ba - - - Barbados - bb - - - Bangladesh - bd - - - Belgium - be - - - - Burkina Faso - bf - - - Bulgaria - bg - - - Bahrain - bh - - - Burundi - bi - - - Benin - bj - - - Saint Barthélémy - bl - - - Bermuda - bm - - - Brunei Darussalam - bn - - - Bolivia - bo - - - Bonaire, Sint Eustatius and Saba - bq - - - Brazil - br - - - - Bahamas - bs - - - Bhutan - bt - - - Bouvet Island - bv - - - Botswana - bw - - - Belarus - by - - - Belize - bz - - - Canada - ca - - - - Cocos (Keeling) Islands - cc - - - Central African Republic - cf - - - Congo, Democratic Republic of the - cd - - - Congo - cg - - - Switzerland - ch - - - Ivory Coast (Cote D'Ivoire) - ci - - - Cook Islands - ck - - - Chile - cl - - - Cameroon - cm - - - China - cn - - - Colombia - co - - - Costa Rica - cr - - - Cuba - cu - - - Cape Verde - cv - - - Curaçao - cw - - - Christmas Island - cx - - - Cyprus - cy - - - Czech Republic - cz - - - Germany - de - - - - Djibouti - dj - - - Denmark - dk - - - Dominica - dm - - - Dominican Republic - do - - - Algeria - dz - - - Ecuador - ec - - - Estonia - ee - - - Egypt - eg - - - Western Sahara - eh - - - Eritrea - er - - - Spain - es - - - - Ethiopia - et - - - Finland - fi - - - Fiji - fj - - - Falkland Islands - fk - - - Micronesia - fm - - - Faroe Islands - fo - - - France - fr - - - - Gabon - ga - - - Grenada - gd - - - Georgia - ge - - - French Guyana - gf - - - Ghana - gh - - - Gibraltar - gi - - - Guernsey - gg - - - Greenland - gl - - - Gambia - gm - - - Guinea - gn - - - Guadeloupe (French) - gp - - - Equatorial Guinea - gq - - - Greece - gr - - - South Georgia and the South Sandwich Islands - gs - - - Guatemala - gt - - - Guam (USA) - gu - - - Guinea Bissau - gw - - - Guyana - gy - - - Hong Kong - hk - - - Heard and McDonald Islands - hm - - - Honduras - hn - - - Croatia - hr - - - Haiti - ht - - - Hungary - hu - - - Indonesia - id - - - Ireland - ie - - - Israel - il - - - Isle of Man - im - - - India - in - - - - British Indian Ocean Territory - io - - - Iraq - iq - - - Iran - ir - - - Iceland - is - - - Italy - it - - - Jersey - je - - - Jamaica - jm - - - Jordan - jo - - - Japan - jp - - - Kenya - ke - - - Kyrgyz Republic (Kyrgyzstan) - kg - - - Cambodia, Kingdom of - kh - - - Kiribati - ki - - - Comoros - km - - - Saint Kitts & Nevis Anguilla - kn - - - North Korea - kp - - - South Korea - kr - - - Kuwait - kw - - - Cayman Islands - ky - - - Kazakhstan - kz - - - Laos - la - - - Lebanon - lb - - - Saint Lucia - lc - - - Liechtenstein - li - - - Sri Lanka - lk - - - Liberia - lr - - - Lesotho - ls - - - Lithuania - lt - - - Luxembourg - lu - - - Latvia - lv - - - Libya - ly - - - Morocco - ma - - - Monaco - mc - - - Moldavia - md - - - Montenegro - me - - - Saint Martin (French part) - mf - - - Madagascar - mg - - - Marshall Islands - mh - - - Macedonia, the former Yugoslav Republic of - mk - - - Mali - ml - - - Myanmar - mm - - - Mongolia - mn - - - Macau - mo - - - Northern Mariana Islands - mp - - - Martinique (French) - mq - - - Mauritania - mr - - - Montserrat - ms - - - Malta - mt - - - Mauritius - mu - - - Maldives - mv - - - Malawi - mw - - - Mexico - mx - - - Malaysia - my - - - Mozambique - mz - - - Namibia - na - - - New Caledonia (French) - nc - - - Niger - ne - - - Norfolk Island - nf - - - Nigeria - ng - - - Nicaragua - ni - - - Netherlands - nl - - - - Norway - no - - - Nepal - np - - - Nauru - nr - - - Neutral Zone - nt - - - Niue - nu - - - New Zealand - nz - - - Oman - om - - - Panama - pa - - - Peru - pe - - - Polynesia (French) - pf - - - Papua New Guinea - pg - - - Philippines - ph - - - Pakistan - pk - - - Poland - pl - - - Saint Pierre and Miquelon - pm - - - Pitcairn Island - pn - - - Puerto Rico - pr - - - Palestinian Territory, Occupied - ps - - - Portugal - pt - - - Palau - pw - - - Paraguay - py - - - Qatar - qa - - - Reunion (French) - re - - - Romania - ro - - - Serbia - rs - - - Russian Federation - ru - - - Rwanda - rw - - - Saudi Arabia - sa - - - Solomon Islands - sb - - - Seychelles - sc - - - Sudan - sd - - - Sweden - se - - - Singapore - sg - - - Saint Helena - sh - - - Slovenia - si - - - Svalbard and Jan Mayen Islands - sj - - - Slovakia - sk - - - Sierra Leone - sl - - - San Marino - sm - - - Senegal - sn - - - Somalia - so - - - Suriname - sr - - - South Sudan - ss - - - Saint Tome (Sao Tome) and Principe - st - - - El Salvador - sv - - - Sint Maarten (Dutch part) - sx - - - Syria - sy - - - Swaziland - sz - - - Turks and Caicos Islands - tc - - - Chad - td - - - French Southern Territories - tf - - - Togo - tg - - - Thailand - th - - - Tajikistan - tj - - - Tokelau - tk - - - Turkmenistan - tm - - - Tunisia - tn - - - Tonga - to - - - East Timor - tp - - - Turkey - tr - - - Trinidad and Tobago - tt - - - Tuvalu - tv - - - Taiwan - tw - - - Tanzania - tz - - - Ukraine - ua - - - Uganda - ug - - - United Kingdom - - gb - - - USA Minor Outlying Islands - um - - - United States - us - - - - Uruguay - uy - - - Uzbekistan - uz - - - Holy See (Vatican City State) - va - - - Saint Vincent & Grenadines - vc - - - Venezuela - ve - - - Virgin Islands (British) - vg - - - Virgin Islands (USA) - vi - - - Vietnam - vn - - - Vanuatu - vu - - - Wallis and Futuna Islands - wf - - - Samoa - ws - - - Yemen - ye - - - Mayotte - yt - - - Yugoslavia - yu - - - South Africa - za - - - Zambia - zm - - - - Zaire - zr - - - Zimbabwe - zw - - - + Your Company - - 45, Rue du Palais - Paris - 75016 - - +33 1 49 51 23 94 + + + + info@yourcompany.com www.yourcompany.com @@ -1112,644 +85,9 @@ - - - - USD - $ - 0.01 - 4 - - - - 1.2834 - - - - - - - VEF - Bs.F - 0.0001 - 4 - - - - 5.864 - - - - - - CAD - $ - 0.01 - 4 - - - - 1.3388 - - - - - - - CHF - CHF - 0.01 - 4 - - - - 1.3086 - - - - - - BRL - R$ - 0.01 - 4 - - - - 2.2344 - - - - - - CNY - ¥ - 0.01 - 4 - - - - 8.7556 - - - - - - - COP - $ - 0.01 - 4 - - - - 2933.8378 - - - - - - CZK - - 0.01 - 4 - - - - 26.5634 - - - - - - DKK - kr - 0.01 - 4 - - - - 7.4445 - - - - - - - HUF - Ft - 0.01 - 4 - - - - 271.5621 - - - - - - IDR - Rp - 0.01 - 4 - - - - 14352.00 - - - - - 11796.39 - - - - - - LVL - Ls - 0.01 - 4 - - - - 0.7086 - - - - - - - NOK - kr - 0.01 - 4 - - - - 7.8668 - - - - - - XPF - XPF - 1.00 - 4 - - - - 119.331742 - - - - - - PAB - B/. - 0.01 - 4 - - - - 1.2676 - - - - - - PLN - - 0.01 - 4 - - - - 4.1005 - - - - - - SEK - kr - 0.01 - 4 - - - - 10.3004 - - - - - - GBP - £ - 0.01 - 4 - - - - 0.8333 - - - - - - ARS - $ - 0.01 - 4 - - - - 5.0881 - - - - - - INR - - 0.01 - 4 - - - - 59.9739 - - - - - - AUD - $ - 0.01 - 4 - - - - 1.4070 - - - - - - UAH - - 0.01 - 4 - - - - 10.1969 - - - - - - VND - - 0.01 - 4 - - - - 26330.01 - - - - - - HKD - $ - 0.01 - 4 - - - - 11.1608 - - - - - - JPY - ¥ - 0.01 - 4 - - - - 133.62 - - - - - - BGN - лв - 0.01 - 4 - - - - 1.9558 - - - - - - LTL - Lt - 0.01 - 4 - - - - 3.4528 - - - - - - RON - lei - 0.01 - 4 - - - - 4.2253 - - - - - - HRK - kn - 0.01 - 4 - - - - 7.2936 - - - - - - RUB - руб - 0.01 - 4 - - - - 43.16 - - - - - - TRY - TL - 0.01 - 4 - - - - 2.1411 - - - - - - KRW - - 0.01 - 4 - - - - 1662.37 - - - - - - MXN - $ - 0.01 - 4 - - - - 18.6664 - - - - - - MYR - RM - 0.01 - 4 - - - - 4.8887 - - - - - - NZD - $ - 0.01 - 4 - - - - 1.9764 - - - - - - PHP - Php - 0.01 - 4 - - - - 66.1 - - - - - - SGD - $ - 0.01 - 4 - - - - 2.0126 - - - - - - THB - ฿ - 0.01 - 4 - - - - 47.779 - - - - - - ZAR - R - 0.01 - 4 - - - - 10.5618 - - - - - - International Bank - - - - CRC - 0.01 - 4 - ¢ - - - - 691.3153 - - - - - - localhost - localhost - - - - - - MUR - Rs - 0.01 - 4 - - - - 40.28 - - - - - - XOF - CFA - 1 - 4 - - - - 655.957 - - - - - - XAF - FCFA - 1 - 4 - - - - 655.957 - - - - - - UGX - USh - 1 - 4 - - - - 3401.91388 - - - - - - HNL - L - 0.01 - 4 - - - - 25 - - - - - - - CLP - $ - 0.01 - 4 - - - - 710 - - - - - - - UYU - $ - 0.01 - 4 - - - - - - 28.36 - - + diff --git a/openerp/addons/base/base_demo.xml b/openerp/addons/base/base_demo.xml index 34feb3af990..064b1f49e69 100644 --- a/openerp/addons/base/base_demo.xml +++ b/openerp/addons/base/base_demo.xml @@ -1,10 +1,15 @@ + + Demo User + + + + demo demo - Demo User Mr Demo diff --git a/openerp/addons/base/country_data.xml b/openerp/addons/base/country_data.xml new file mode 100644 index 00000000000..d4d880cb8ed --- /dev/null +++ b/openerp/addons/base/country_data.xml @@ -0,0 +1,1285 @@ + + + + + + + United Arab Emirates + ae + + + + Afghanistan, Islamic State of + af + + + + Antigua and Barbuda + ag + + + + Anguilla + ai + + + + Albania + al + + + + Armenia + am + + + + Netherlands Antilles + an + + + + Angola + ao + + + + Antarctica + aq + + + + Argentina + ar + + + + American Samoa + as + + + + Austria + at + + + + Australia + au + + + + + Aruba + aw + + + + Åland Islands + ax + + + + Azerbaijan + az + + + + Bosnia-Herzegovina + ba + + + + Barbados + bb + + + + Bangladesh + bd + + + + Belgium + be + + + + + Burkina Faso + bf + + + + Bulgaria + bg + + + + Bahrain + bh + + + + Burundi + bi + + + + Benin + bj + + + + Saint Barthélémy + bl + + + + Bermuda + bm + + + + Brunei Darussalam + bn + + + + Bolivia + bo + + + + Bonaire, Sint Eustatius and Saba + bq + + + + Brazil + br + + + + + Bahamas + bs + + + + Bhutan + bt + + + + Bouvet Island + bv + + + + Botswana + bw + + + + Belarus + by + + + + Belize + bz + + + + Canada + ca + + + + + Cocos (Keeling) Islands + cc + + + + Central African Republic + cf + + + + Congo, Democratic Republic of the + cd + + + + Congo + cg + + + + Switzerland + ch + + + + Ivory Coast (Cote D'Ivoire) + ci + + + + Cook Islands + ck + + + + Chile + cl + + + + Cameroon + cm + + + + China + cn + + + + Colombia + co + + + + Costa Rica + cr + + + + Cuba + cu + + + + Cape Verde + cv + + + + Curaçao + cw + + + + Christmas Island + cx + + + + Cyprus + cy + + + + Czech Republic + cz + + + + Germany + de + + + + + Djibouti + dj + + + + Denmark + dk + + + + Dominica + dm + + + + Dominican Republic + do + + + + Algeria + dz + + + + Ecuador + ec + + + + Estonia + ee + + + + Egypt + eg + + + + Western Sahara + eh + + + + Eritrea + er + + + + Spain + es + + + + + Ethiopia + et + + + + Finland + fi + + + + Fiji + fj + + + + Falkland Islands + fk + + + + Micronesia + fm + + + + Faroe Islands + fo + + + + France + fr + + + + + Gabon + ga + + + + Grenada + gd + + + + Georgia + ge + + + + French Guyana + gf + + + + Ghana + gh + + + + Gibraltar + gi + + + + Guernsey + gg + + + + Greenland + gl + + + + Gambia + gm + + + + Guinea + gn + + + + Guadeloupe (French) + gp + + + + Equatorial Guinea + gq + + + + Greece + gr + + + + South Georgia and the South Sandwich Islands + gs + + + + Guatemala + gt + + + + Guam (USA) + gu + + + + Guinea Bissau + gw + + + + Guyana + gy + + + + Hong Kong + hk + + + + Heard and McDonald Islands + hm + + + + Honduras + hn + + + + Croatia + hr + + + + Haiti + ht + + + + Hungary + hu + + + + Indonesia + id + + + + Ireland + ie + + + + Israel + il + + + + Isle of Man + im + + + + India + in + + + + + British Indian Ocean Territory + io + + + + Iraq + iq + + + + Iran + ir + + + + Iceland + is + + + + Italy + it + + + + Jersey + je + + + + Jamaica + jm + + + + Jordan + jo + + + + Japan + jp + + + + Kenya + ke + + + + Kyrgyz Republic (Kyrgyzstan) + kg + + + + Cambodia, Kingdom of + kh + + + + Kiribati + ki + + + + Comoros + km + + + + Saint Kitts & Nevis Anguilla + kn + + + + North Korea + kp + + + + South Korea + kr + + + + Kuwait + kw + + + + Cayman Islands + ky + + + + Kazakhstan + kz + + + + Laos + la + + + + Lebanon + lb + + + + Saint Lucia + lc + + + + Liechtenstein + li + + + + Sri Lanka + lk + + + + Liberia + lr + + + + Lesotho + ls + + + + Lithuania + lt + + + + Luxembourg + lu + + + + Latvia + lv + + + + Libya + ly + + + + Morocco + ma + + + + Monaco + + mc + + + Moldavia + md + + + + Montenegro + me + + + + Saint Martin (French part) + mf + + + + Madagascar + mg + + + + Marshall Islands + mh + + + + Macedonia, the former Yugoslav Republic of + mk + + + + Mali + ml + + + + Myanmar + mm + + + + Mongolia + mn + + + + Macau + mo + + + + Northern Mariana Islands + mp + + + + Martinique (French) + mq + + + + Mauritania + mr + + + + Montserrat + ms + + + + Malta + mt + + + + Mauritius + mu + + + + Maldives + mv + + + + Malawi + mw + + + + Mexico + mx + + + + Malaysia + my + + + + Mozambique + mz + + + + Namibia + na + + + + New Caledonia (French) + nc + + + + Niger + ne + + + + Norfolk Island + nf + + + + Nigeria + ng + + + + Nicaragua + ni + + + + Netherlands + nl + + + + + Norway + no + + + + Nepal + np + + + + Nauru + nr + + + + Neutral Zone + nt + + + + Niue + nu + + + + New Zealand + nz + + + + Oman + om + + + + Panama + pa + + + + Peru + pe + + + + Polynesia (French) + pf + + + + Papua New Guinea + pg + + + + Philippines + ph + + + + Pakistan + pk + + + + Poland + pl + + + + Saint Pierre and Miquelon + pm + + + + Pitcairn Island + pn + + + + Puerto Rico + pr + + + + Palestinian Territory, Occupied + ps + + + + Portugal + pt + + + + Palau + pw + + + + Paraguay + py + + + + Qatar + qa + + + + Reunion (French) + re + + + + Romania + ro + + + + Serbia + rs + + + + Russian Federation + ru + + + + Rwanda + rw + + + + Saudi Arabia + sa + + + + Solomon Islands + sb + + + + Seychelles + sc + + + + Sudan + sd + + + + Sweden + se + + + + Singapore + sg + + + + Saint Helena + sh + + + + Slovenia + si + + + + Svalbard and Jan Mayen Islands + sj + + + + Slovakia + sk + + + + Sierra Leone + sl + + + + San Marino + sm + + + + Senegal + sn + + + + Somalia + so + + + + Suriname + sr + + + + South Sudan + ss + + + + Saint Tome (Sao Tome) and Principe + st + + + + El Salvador + sv + + + + Sint Maarten (Dutch part) + sx + + + + Syria + sy + + + + Swaziland + sz + + + + Turks and Caicos Islands + tc + + + + Chad + td + + + + French Southern Territories + tf + + + + Togo + tg + + + + Thailand + th + + + + Tajikistan + tj + + + + Tokelau + tk + + + + Turkmenistan + tm + + + + Tunisia + tn + + + + Tonga + to + + + + East Timor + tp + + + + Turkey + tr + + + + Trinidad and Tobago + tt + + + + Tuvalu + tv + + + + Taiwan + tw + + + + Tanzania + tz + + + + Ukraine + ua + + + + + Uganda + ug + + + + United Kingdom + + gb + + + + USA Minor Outlying Islands + um + + + + United States + us + + + + + Uruguay + uy + + + + Uzbekistan + uz + + + + Holy See (Vatican City State) + va + + + + Saint Vincent & Grenadines + vc + + + + Venezuela + ve + + + + Virgin Islands (British) + vg + + + + Virgin Islands (USA) + vi + + + + Vietnam + vn + + + + Vanuatu + vu + + + + Wallis and Futuna Islands + wf + + + + Samoa + ws + + + + Yemen + ye + + + + Mayotte + yt + + + + Yugoslavia + yu + + + + South Africa + za + + + + Zambia + zm + + + + + + Zaire + zr + + + + Zimbabwe + zw + + + + diff --git a/openerp/addons/base/currency_data.xml b/openerp/addons/base/currency_data.xml new file mode 100644 index 00000000000..11a83404b02 --- /dev/null +++ b/openerp/addons/base/currency_data.xml @@ -0,0 +1,2299 @@ + + + + + + + USD + $ + 0.01 + 4 + + + + 1.2834 + + + + + + + VEF + Bs.F + 0.0001 + 4 + + + + 5.864 + + + + + + CAD + $ + 0.01 + 4 + + + + 1.3388 + + + + + + + CHF + CHF + 0.01 + 4 + + + + 1.3086 + + + + + + BRL + R$ + 0.01 + 4 + + + + 2.2344 + + + + + + CNY + ¥ + 0.01 + 4 + + + + 8.7556 + + + + + + + COP + $ + 0.01 + 4 + + + + 2933.8378 + + + + + + CZK + + 0.01 + 4 + + + + 26.5634 + + + + + + DKK + kr + 0.01 + 4 + + + + 7.4445 + + + + + + + HUF + Ft + 0.01 + 4 + + + + 271.5621 + + + + + + IDR + Rp + 0.01 + 4 + + + + 14352.00 + + + + + 11796.39 + + + + + + LVL + Ls + 0.01 + 4 + + + + 0.7086 + + + + + + NOK + kr + 0.01 + 4 + + + + 7.8668 + + + + + + XPF + XPF + 1.00 + 4 + + + + 119.331742 + + + + + + PAB + B/. + 0.01 + 4 + + + + 1.2676 + + + + + + PLN + + 0.01 + 4 + + + + 4.1005 + + + + + + SEK + kr + 0.01 + 4 + + + + 10.3004 + + + + + + ARS + $ + 0.01 + 4 + + + + 5.0881 + + + + + + INR + + 0.01 + 4 + + + + 59.9739 + + + + + + AUD + $ + 0.01 + 4 + + + + 1.4070 + + + + + + UAH + + 0.01 + 4 + + + + 10.1969 + + + + + + VND + + 0.01 + 4 + + + + 26330.01 + + + + + + HKD + $ + 0.01 + 4 + + + + 11.1608 + + + + + + JPY + ¥ + 0.01 + 4 + + + + 133.62 + + + + + + BGN + лв + 0.01 + 4 + + + + 1.9558 + + + + + + LTL + Lt + 0.01 + 4 + + + + 3.4528 + + + + + + RON + lei + 0.01 + 4 + + + + 4.2253 + + + + + + HRK + kn + 0.01 + 4 + + + + 7.2936 + + + + + + RUB + руб + 0.01 + 4 + + + + 43.16 + + + + + + TRY + TL + 0.01 + 4 + + + + 2.1411 + + + + + + KRW + + 0.01 + 4 + + + + 1662.37 + + + + + + MXN + $ + 0.01 + 4 + + + + 18.6664 + + + + + + MYR + RM + 0.01 + 4 + + + + 4.8887 + + + + + + NZD + $ + 0.01 + 4 + + + + 1.9764 + + + + + + PHP + Php + 0.01 + 4 + + + + 66.1 + + + + + + SGD + $ + 0.01 + 4 + + + + 2.0126 + + + + + + ZAR + R + 0.01 + 4 + + + + 10.5618 + + + + + + Reserve + + + + CRC + 0.01 + 4 + ¢ + + + + 691.3153 + + + + + + localhost + localhost + + + + + + MUR + Rs + 0.01 + 4 + + + + 40.28 + + + + + + XOF + CFA + 1 + 4 + + + + 655.957 + + + + + + XAF + FCFA + 1 + 4 + + + + 655.957 + + + + + + UGX + USh + 1 + 4 + + + + 3401.91388 + + + + + + HNL + L + 0.01 + 4 + + + + 25 + + + + + + CLP + $ + 0.01 + 4 + + + + 710 + + + + + + UYU + $ + 0.01 + 4 + + + + + + 28.36 + + + + AFN + Afs + 0.01 + 4 + + + + + + 59.33 + + + + AOA + Kz + 0.01 + 4 + + + + + + 117.080 + + + + XCD + $ + 0.01 + 4 + + + + + + 3.32 + + + + AMD + դր. + 0.01 + 4 + + + + + + 506.02 + + + + AWG + Afl. + 0.01 + 4 + + + + + + 0.45 + + + + AZN + m + 0.01 + 4 + + + + + + 0.96 + + + + BSD + B$ + 0.01 + 4 + + + + + + 1.23 + + + + BHD + BD + 0.01 + 4 + + + + + + 0.46 + + + + BDT + + 0.01 + 4 + + + + + + 100.59 + + + + BBD + Bds$ + 0.01 + 4 + + + + + + 2.46 + + + + BYR + BR + 0.01 + 4 + + + + + + 10228.19 + + + + BZD + BZ$ + 0.01 + 4 + + + + + + 2.33 + + + + BMD + BD$ + 0.01 + 4 + + + + + + 1.23 + + + + BTN + Nu. + 0.01 + 4 + + + + + + 67.81 + + + + BOB + Bs. + 0.01 + 4 + + + + + + 8.50 + + + + BAM + KM + 0.01 + 4 + + + + + + 1.96 + + + + BWP + P + 0.01 + 4 + + + + + + 9.45 + + + + BIF + FBu + 0.01 + 4 + + + + + + 1736.73 + + + + KHR + + 0.01 + 4 + + + + + + 5054.53 + + + + KYD + $ + 0.01 + 4 + + + + + + 1.007 + + + + KMF + CF + 0.01 + 4 + + + + + + 492.23 + + + + CDF + Fr + 0.01 + 4 + + + + + + 1112.80 + + + + CUP + $ + 0.01 + 4 + + + + + + 1.226 + + + + ANG + ƒ + 0.01 + 4 + + + + + + 2.11 + + + + CYP + £ + 0.01 + 4 + + + + + + 0.475 + + + + DJF + Fdj + 0.01 + 4 + + + + + + 222.22 + + + + DOP + RD$ + 0.01 + 4 + + + + + + 48.09 + + + + + TPE + 0.01 + 4 + + + + + + 1.2535 + + + + ECS + S/. + 0.01 + 4 + + + + + + 30707.5 + + + + EGP + + 0.01 + 4 + + + + + + 7.46 + + + + SVC + ¢ + 0.01 + 4 + + + + + + 10.74 + + + + ERN + Nfk + 0.01 + 4 + + + + + + 18.89 + + + + EEK + kr + 0.01 + 4 + + + + + + 14.41 + + + + ETB + Br + 0.01 + 4 + + + + + + 21.94 + + + + FKP + £ + 0.01 + 4 + + + + + + 0.78 + + + + FJD + FJ$ + 0.01 + 4 + + + + + + 2.22 + + + + GEL + + 0.01 + 4 + + + + + + 2.018 + + + + GIP + £ + 0.01 + 4 + + + + + + 0.786 + + + + QTQ + Q + 0.01 + 4 + + + + + + 9.8827 + + + + GNF + FG + 0.01 + 4 + + + + + + 8835.85 + + + + GWP + 0.01 + 4 + + + + + + 659.30 + + + + GYD + $ + 0.01 + 4 + + + + + + 247.31 + + + + HTG + G + 0.01 + 4 + + + + + + 51.69 + + + + ISK + kr + 0.01 + 4 + + + + + + 158.70 + + + + IRR + + 0.01 + 4 + + + + + + 15059.97 + + + + IQD + ع.د + 0.01 + 4 + + + + + + 1432.27 + + + + ILS + + 0.01 + 4 + + + + + + 4.89 + + + + JMD + $ + 0.01 + 4 + + + + + + 108.94 + + + + JOD + د.ا + 0.01 + 4 + + + + + + 0.87 + + + + KZT + лв + 0.01 + 4 + + + + + + 184.09 + + + + KES + KSh + 0.01 + 4 + + + + + + 103.43 + + + + KWD + د.ك + 0.01 + 4 + + + + + + 0.35 + + + + KGS + лв + 0.01 + 4 + + + + + + 57.93 + + + + LAK + + 0.01 + 4 + + + + + + 9847.72 + + + + LBP + ل.ل + 0.01 + 4 + + + + + + 1853.94 + + + + LSL + L + 0.01 + 4 + + + + + + 10.06 + + + + LRD + L$ + 0.01 + 4 + + + + + + 90.28 + + + + LYD + ل.د + 0.01 + 4 + + + + + + 1.54 + + + + MOP + MOP$ + 0.01 + 4 + + + + + + 9.81 + + + + MKD + ден + 0.01 + 4 + + + + + + 60.29 + + + + MGA + Ar + 0.01 + 4 + + + + + + 2775.86 + + + + MWK + MK + 0.01 + 4 + + + + + + 329.79 + + + + MVR + + 0.01 + 4 + + + + + + 18.89 + + + + MRO + UM + 0.01 + 4 + + + + + + 362.23 + + + + MDL + L + 0.01 + 4 + + + + + + 15.27 + + + + MNT + + 0.01 + 4 + + + + + + 1643.57 + + + + MAD + د.م. + 0.01 + 4 + + + + + + 10.9962499 + + + + BND + $ + 0.01 + 4 + + + + + + 1.54 + + + + DZD + DZ + 0.01 + 4 + + + + + + 99.65 + + + + GHS + GH¢ + 0.01 + 4 + + + + + + 2.39 + + + + GMD + D + 0.01 + 4 + + + + + + 38.89 + + + + ZRZ + Ƶ + 0.01 + 4 + + + + + + 1148948.76 + + + + MZN + MT + 0.01 + 4 + + + + + + 33.65 + + + + MMK + K + 0.01 + 4 + + + + + + 1080.82 + + + + NAD + $ + 0.01 + 4 + + + + + + 10.06 + + + + NPR + + 0.01 + 4 + + + + + + 108.33 + + + + ALL + L + 0.01 + 4 + + + + + + 138.00 + + + + NIO + C$ + 0.01 + 4 + + + + + + 28.97 + + + + NGN + + 0.01 + 4 + + + + + + 196.77 + + + + KPW + + 0.01 + 4 + + + + + + 1105.24376765 + + + + ZWD + Z$ + 0.01 + 4 + + + + + + 460.93 + + + + ZMK + ZK + 0.01 + 4 + + + + + + 6022.54902 + + + + YER + + 0.01 + 4 + + + + + + 264.784483 + + + + VUB + Bs + 0.01 + 4 + + + + + + 5.3821 + + + + EUR + + 0.01 + 4 + + + + + + 1.0 + + + + VUV + VT + 0.01 + 4 + + + + + + 114.024315363 + + + + UZS + лв + 0.01 + 4 + + + + + + 2331.3093 + + + + UYP + $U + 0.01 + 4 + + + + + + 26.91 + + + + AED + د.إ + 0.01 + 4 + + + + + + 4.51253195 + + + + UAG + + 0.01 + 4 + + + + + + 10.17 + + + + TMM + m + 0.01 + 4 + + + + + + 0.00313859649123 + + + + TRL + TL + 0.01 + 4 + + + + + + 2.255 + + + + TND + DT + 0.01 + 4 + + + + + + 34.0661408 + + + + TTD + $ + 0.01 + 4 + + + + + + 8.61926302 + + + + TOP + T$ + 0.01 + 4 + + + + + + 31.1217 + + + + THB + ฿ + 0.01 + 4 + + + + + + 38.4070124 + + + + TZS + x/y + 0.01 + 4 + + + + + + 1947.06815 + + + + TJR + 0.01 + 4 + + + + + + 5.95 + + + + TWD + NT$ + 0.01 + 4 + + + + + + 36.8329536 + + + + SYP + £ + 0.01 + 4 + + + + + + 78.8338 + + + + SZL + E + 0.01 + 4 + + + + + + 10.07 + + + + SRG + $ + 0.01 + 4 + + + + + + 3980.29 + + + + SDD + £Sd + 0.01 + 4 + + + + + + 544.44 + + + + LKR + Rs + 0.01 + 4 + + + + + + 163.552526 + + + + SSP + £ + 0.01 + 4 + + + + + + 5.528 + + + + GBP + £ + 0.01 + 4 + + + + + + 0.784221994 + + + + SOD + Sh. + 0.01 + 4 + + + + + + 1993.71 + + + + SBD + SI$ + 0.01 + 4 + + + + + + 8.6605 + + + + SLL + Le + 0.01 + 4 + + + + + + 5320.43478 + + + + SCR + SR + 0.01 + 4 + + + + + + 18.2587287 + + + + RSD + din. + 0.01 + 4 + + + + + + 117.381295 + + + + SAR + SR + 0.01 + 4 + + + + + + 4.58898972 + + + + STD + Db + 0.01 + 4 + + + + + + 24105.86 + + + + ITL + + 0.01 + 4 + + + + + + 1936.27 + + + + WST + WS$ + 0.01 + 4 + + + + + + 2.8628 + + + + SHP + £ + 0.01 + 4 + + + + + + 0.7856 + + + + RWF + RF + 0.01 + 4 + + + + + + 752.57 + + + + RUR + R + 0.01 + 4 + + + + + + 39.6622695 + + + + ROL + L + 0.01 + 4 + + + + + + 45638.59 + + + + QAR + QR + 0.01 + 4 + + + + + + 4.45500218 + + + + PLZ + + 0.01 + 4 + + + + + + 4.17281888 + + + + PEN + S/. + 0.01 + 4 + + + + + + 3.20731573 + + + + PYG + + 0.01 + 4 + + + + + + 5343.66812 + + + + PGK + K + 0.01 + 4 + + + + + + 2.5903895 + + + + PKR + Rs. + 0.01 + 4 + + + + + + 115.97432 + + + + OMR + ر.ع. + 0.01 + 4 + + + + + + 0.472921728 + + + + CVE + $ + 0.01 + 4 + + + + + + 0.61 + + + + SKK + Sk + 0.01 + 4 + + + + + + 30.1263029 + + + + SIT + 0.01 + 4 + + + + + + 239.64 + + + + YUM + дин. + 0.01 + 4 + + + + + + 1.96 + + + + diff --git a/openerp/addons/base/i18n/ab.po b/openerp/addons/base/i18n/ab.po index e7888a8a720..7edfde74afc 100644 --- a/openerp/addons/base/i18n/ab.po +++ b/openerp/addons/base/i18n/ab.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:36+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:37+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/af.po b/openerp/addons/base/i18n/af.po index 4f2dd5fb776..cb52e2f5de9 100644 --- a/openerp/addons/base/i18n/af.po +++ b/openerp/addons/base/i18n/af.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:36+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/am.po b/openerp/addons/base/i18n/am.po index 1ccb028cac0..3e1e29f7661 100644 --- a/openerp/addons/base/i18n/am.po +++ b/openerp/addons/base/i18n/am.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:37+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ar.po b/openerp/addons/base/i18n/ar.po index 1a2642d9e1f..e127ce1abbb 100644 --- a/openerp/addons/base/i18n/ar.po +++ b/openerp/addons/base/i18n/ar.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-03-19 10:06+0000\n" -"Last-Translator: Abdulwhhab A. Al-Shehri \n" +"PO-Revision-Date: 2012-08-20 15:46+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:37+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -34,7 +34,7 @@ msgstr "الوقت و التاريخ" #. module: base #: model:ir.module.module,shortdesc:base.module_project_mailgate msgid "Tasks-Mail Integration" -msgstr "" +msgstr "دمج المهام عن طريق الإيميل" #. module: base #: code:addons/fields.py:582 diff --git a/openerp/addons/base/i18n/base.pot b/openerp/addons/base/i18n/base.pot index b4d28052ba8..884dac7d821 100644 --- a/openerp/addons/base/i18n/base.pot +++ b/openerp/addons/base/i18n/base.pot @@ -3383,7 +3383,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9064,7 +9064,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/bg.po b/openerp/addons/base/i18n/bg.po index ab9556f269c..3d2625e4733 100644 --- a/openerp/addons/base/i18n/bg.po +++ b/openerp/addons/base/i18n/bg.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 16:44+0000\n" +"PO-Revision-Date: 2012-08-20 15:49+0000\n" "Last-Translator: Boris \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:37+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/bs.po b/openerp/addons/base/i18n/bs.po index 778679bb04d..9a3b2255563 100644 --- a/openerp/addons/base/i18n/bs.po +++ b/openerp/addons/base/i18n/bs.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:37+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ca.po b/openerp/addons/base/i18n/ca.po index fa5f95b14da..6fc2fb91702 100644 --- a/openerp/addons/base/i18n/ca.po +++ b/openerp/addons/base/i18n/ca.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 16:24+0000\n" +"PO-Revision-Date: 2012-08-20 15:44+0000\n" "Last-Translator: Antony Lesuisse (OpenERP) \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:37+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/cs.po b/openerp/addons/base/i18n/cs.po index 4819a321dda..6069a8e44ca 100644 --- a/openerp/addons/base/i18n/cs.po +++ b/openerp/addons/base/i18n/cs.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-04-05 13:24+0000\n" +"PO-Revision-Date: 2012-08-20 15:44+0000\n" "Last-Translator: Jiří Hajda \n" "Language-Team: openerp-i18n-czech \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:38+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n" +"X-Generator: Launchpad (build 15901)\n" "X-Poedit-Language: Czech\n" #. module: base diff --git a/openerp/addons/base/i18n/da.po b/openerp/addons/base/i18n/da.po index 2710b5c4629..62dc22344a7 100644 --- a/openerp/addons/base/i18n/da.po +++ b/openerp/addons/base/i18n/da.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2011-09-24 16:40+0000\n" -"Last-Translator: John Mertens Pallesen \n" +"PO-Revision-Date: 2012-08-20 15:44+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: Danish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:38+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/de.po b/openerp/addons/base/i18n/de.po index 9db01f56eb0..301be6a019e 100644 --- a/openerp/addons/base/i18n/de.po +++ b/openerp/addons/base/i18n/de.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-07-06 21:06+0000\n" +"PO-Revision-Date: 2012-08-20 15:29+0000\n" "Last-Translator: Rudolf Schnapka \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:39+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -3264,6 +3264,18 @@ msgid "" "że wszystkie towary są w obrocie hurtowym.\n" " " msgstr "" +"\n" +"Dieses Modul dient der Verwaltung des Kontenplans und der Steuern für Polen " +"in OpenERP.\n" +"=============================================================================" +"=====\n" +"\n" +"To jest moduł do tworzenia wzorcowego planu kont i podstawowych ustawień do " +"podatków\n" +"VAT 0%, 7% i 22%. Moduł ustawia też konta do kupna i sprzedaży towarów " +"zakładając,\n" +"że wszystkie towary są w obrocie hurtowym.\n" +" " #. module: base #: field:ir.actions.client,params_store:0 @@ -3809,6 +3821,14 @@ msgid "" "Canadian accounting charts and localizations.\n" " " msgstr "" +"\n" +"Dieses Modul dient der Verwaltung des englischen und französischen " +"Kontenplan Kanadas in OpenERP.\n" +"=============================================================================" +"==============\n" +"\n" +"Kanadischer Kontenplan und Lokalisierung.\n" +" " #. module: base #: view:base.module.import:0 @@ -3841,6 +3861,14 @@ msgid "" " * the Tax Code Chart for Luxembourg\n" " * the main taxes used in Luxembourg" msgstr "" +"\n" +"Dieses Modul dient der Verwaltung des Luxemburgischen Kontenplans in " +"OpenERP.\n" +"======================================================================\n" +"\n" +"* Der KLUWER Kontenplan,\n" +"* Die Steuerschlüssel für Luxembourg,\n" +"* Die wesentlichen Steuern, die in Luxembourg Verwendung finden." #. module: base #: field:ir.module.module,demo:0 @@ -4595,6 +4623,37 @@ msgid "" "\n" "\n" msgstr "" +"\n" +"Dies verbessert den Umgang mit Mehrfachwährungen bei Kostenstellenrechnung " +"generell bei Mehrfachunternehmungen.\n" +"\n" +"Dieses Modul basiert auf der durchgeführten Arbeit in allen Modulen c2c-" +"multicost* die ab der stabilen Version 5.0\n" +"verfügbar sind und ermöglicht die gemeinsame Nutzung von Kostenstellenkonten " +"durch die Unternehmen (selbst\n" +"wenn die Währungen sich unterscheiden).\n" +"\n" +"Was hier umgesetzt ist:\n" +"\n" +" * Zuweisung des Verursachers einer Kostenposition (=Unternehmen, dass die " +"Kostenstelle eingerichtet hat)\n" +" * Mehrfachwährung für Kosten (wie bei der Finanzbuchhaltung auch)\n" +" * Alle Kosten auf die in der Kostenstelle geführten Währung (Eigner-" +"Unternehmen) umrechnen.\n" +" * Per Standard ohne Einfluss bei Einrichtung für Einfachunternehmen\n" +"\n" +"Als Ergebnis können Kostenstellen, trotz unterschiedlicher Währungen, " +"gemeinsam genutzt werden. Diese\n" +"Einrichtung wird nun Realität, geniesse!\n" +"\n" +"- Unternehmen A: EUR\n" +"- Unternehmen B: CHF\n" +"\n" +"- Kostenstelle A: USD, eigner ist Unternehmen A\n" +"- Kostenstelle B; CHF, eigner ist Unternehmen A\n" +"- Kostenstelle C: EUR, eigner ist Unternehmen B\n" +"\n" +"\n" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_it @@ -4735,6 +4794,23 @@ msgid "" "anonymization process to recover your previous data.\n" " " msgstr "" +"\n" +"Dieses Modul ermöglicht die Anonymisierung einer Datenbank.\n" +"\n" +"Dieses Modul ermöglicht Daten einer gegebenen Datenbank vertraulich zu " +"halten.\n" +"Dies ist zweckmäßig, wenn Sie den Migrationsprozess nutzen und die " +"vertraulichen\n" +"Daten von Ihnen oder Ihrem Klienten schützen möchten. Im Prinzip lassen Sie " +"das \n" +"Anonymisierungs-Werkzeug die vertraulichen Daten verstecken (diese werden " +"durch \"XXX\"-\n" +"Zeichen ersetzt). Sie können dann die anonymisierte Datenbank an das " +"Migrationsteam \n" +"senden. Wenn Sie anschließend die migrierte Datenbank zurück erhalten, " +"stellen Sie,\n" +"im Umkehrprozess zur Anonymisierung, die Daten wieder her.\n" +" " #. module: base #: help:publisher_warranty.contract,name:0 @@ -4885,6 +4961,21 @@ msgid "" "You can also use the geolocalization without using the GPS coordinates.\n" " " msgstr "" +"\n" +"Dieses Modul wird durch die OpenERP S.A. verwendet, um Kunden per Geo-" +"Lokalisierung \n" +"an die zuständigen Partner weiter zu vermitteln.\n" +"=============================================================================" +"\n" +"\n" +"Sie können mit diesem Modul Ihre Geschäftsgelegenheiten geo-lokalisieren.\n" +"\n" +"Benutzen Sie Geo-Lokalisierung, um Geschäftgelegenheiten Partnern " +"zuzuweisen.\n" +"Ermitteln Sie die GPS-Koordinaten mittels der Addresse des Partners.\n" +"Der zutreffendste Partne kann somit zugewiesen werden.\n" +"Sie können die Geo-Lokalisierung auch ohne GPS-Koordinaten nutzen.\n" +" " #. module: base #: help:ir.actions.act_window,help:0 @@ -5400,6 +5491,20 @@ msgid "" "of the survey\n" " " msgstr "" +"\n" +"Dieses Modul dient der Erstellung von Fragebögen.\n" +"==============================================\n" +"\n" +"Es hängt von den Antworten ab, die auf Fragen verschiedener Benutzer " +"folgen.\n" +"Ein Fragebogen kann mehrere Seiten haben. Jede Seite kann mehrere Fragen mit " +"wiederum\n" +"mehreren Antwortmöglichkeiten haben.\n" +"Nutzer können verschiedene Antworten liefern und davon hängt die Beurteilung " +"ab.\n" +"Partnern wird eine Mail mit Name und Kennwort als Einladung zur Teilnahme " +"zugeschickt.\n" +" " #. module: base #: model:res.country,name:base.bm @@ -5568,6 +5673,15 @@ msgid "" "This new object will regroup and will allow you to easily keep track and " "order all your purchase orders.\n" msgstr "" +"\n" +"Dieses Modul ermöglicht Bestellanforderungen (BANF) zu verwalten.\n" +"===========================================================\n" +"\n" +"Wenn eine Bedarfsmeldung generiert wird, haben Sie nun die Möglichkeit die " +"zugehörigen Bestellanforderungen\n" +"zu speichern. Dieses neue Objekt gruppiert die Bedarfsmeldungen neu und " +"erlaubt die einfache Kontrolle und\n" +"Bestellung aller Bedarfe.\n" #. module: base #: model:res.country,name:base.hu @@ -5659,6 +5773,17 @@ msgid "" "It adds sales name and sales Reference on production order.\n" " " msgstr "" +"\n" +"Dieses Modul macht die gleichzeitige Installation der Module MRP und Verkauf " +"verfügbar.\n" +"===========================================================================\n" +"\n" +"Es wird im Wesentlichen dann genutzt, wenn aus Verkäufen entstandene " +"Fertigungsaufträge \n" +"nachverfolgt werden sollen. Es fügt dem Fertigungsauftrag den Verkäufernamen " +"und die\n" +"Bezugsnummer (Referenz) hinzu.\n" +" " #. module: base #: selection:res.request,state:0 @@ -5698,6 +5823,13 @@ msgid "" "revenue\n" "reports, etc." msgstr "" +"Erzeugen Sie Rechnungen aus Spesen, Stundennachweisen, ...\n" +"Modul zum generieren von Rechnungen aus Kosten (Personalkosten, Auslagen, " +"...).\n" +"=====================================================================\n" +"\n" +"Sie können Preislisten auf Kostenstellen beziehen, theoretische " +"Umsatzberichte erstellen, usw." #. module: base #: field:ir.ui.menu,parent_id:0 @@ -5794,6 +5926,12 @@ msgid "" " those assets. And it allows to create Move's of the depreciation lines.\n" " " msgstr "" +"Vermögens- und Anlagenverwaltung.\n" +" Dieses Modul verwaltet Anlagen eines Unternehmens oder eines Einzelnen. " +"Es wird die jeweiligen Abschreibungen\n" +" festhalten. Es ermöglicht darüber hinaus auch die Veränderungen dieser " +"Aktiva zu pflegen.\n" +" " #. module: base #: model:res.country,name:base.bv @@ -6021,6 +6159,28 @@ msgid "" " * Graph : Products to send in delay (date < = today)\n" " " msgstr "" +"\n" +"Die OpenERP Lagerverwaltung kann mit mehreren Lagerorten, mit mehreren \n" +"und strukturierten Lagerplätzen umgehen.\n" +"==========================================================================\n" +"\n" +"Dank der Doppelten Buchhaltung ist die Lagerverwaltung leistungsfähig und " +"flexibel:\n" +" * Lagerveränderung und -planung,\n" +" * Unterschiedliche Methoden (FIFO, LIFO, ...),\n" +" * Lagerbewertung (Festpreis, Mittelwert, ...),\n" +" * Solider Umgang mit Bestandsabweichungen,\n" +" * Automatische Regeln für Nachbestellungen (Bestand, JIT, ...),\n" +" * Unterstützung für Barcodes,\n" +" * Schnelle Fehlerfeststellung durch Gegenbuchungs-System,\n" +" * Nachverfolgung (Zugang/Abgang, Fertigungslose, Seriennummern, ...),\n" +" * Pinnwand für Lagerverwaltung mit:\n" +" - Kommissionierungsprobleme,\n" +" - Liste der Lagerzugänge,\n" +" - Liste der Lagerabgänge,\n" +" - Diagramm: Erwartete Produkte im Verzug (Datum <= heute),\n" +" - Diagramm: zu versendende Produkte im Verzug (Datum <= heute),\n" +" " #. module: base #: model:ir.model,name:base.model_ir_module_module @@ -6095,6 +6255,35 @@ msgid "" "Budgets per Budgets.\n" "\n" msgstr "" +"\n" +"Dieses Modul ermöglicht Buchhaltern die Verwaltung von Kostenstellen und " +"übergreifenden Budgets.\n" +"=============================================================================" +"=========\n" +"\n" +"Sind die Haupt- und Nebenkostenstellen festgelegt (in Finanzen/Budgets/) " +"können Projektmanager die\n" +"Verfügungsbeträge den jeweiligen Kostenstellen zuschreiben.\n" +"\n" +"Der Buchhalter hat die Möglichkeit die Gesamtsummen aller Haupt- und " +"Nebenkostenstellen überblicken,\n" +"um eine Über-/Unterschreitung der Plansummen zu vermeiden. Jede Kontenliste " +"kann auch zu einer\n" +"grafischen Ansicht umgeschaltet werden.\n" +"\n" +"Drei Berichte sind verfügbar:\n" +" 1. Der erste ist aus einer Liste von Budgets erreichbar: Er zeigt die " +"Verteilung der Kostenarten, der \n" +" Neben- und der Haupt-Kostenstellen.\n" +"\n" +" 2. Der zweite stellt eine Zusammenfassung des vorigen dar und zeigt nur " +"die Verteilung ausgewählter \n" +" Busgets innerhalb der Kostenstellen.\n" +"\n" +" 3. Der letzte Bericht ist vom Kostenstellenplan aus erhältlich. Es weist " +"die Verteilung der \n" +" Nebenkostenstellen innerhalb der Hauptkostenstellen aus.\n" +"\n" #. module: base #: help:res.lang,iso_code:0 @@ -6448,7 +6637,7 @@ msgstr "Wertebereich" #. module: base #: model:ir.module.module,shortdesc:base.module_base_module_quality msgid "Analyse Module Quality" -msgstr "" +msgstr "Modulqualität analysieren" #. module: base #: selection:base.language.install,lang:0 @@ -6574,6 +6763,19 @@ msgid "" " * Integrated with Holiday Management\n" " " msgstr "" +"\n" +"Allgemeines System für Lohn und Gehalt.\n" +"====================================\n" +"\n" +" * Mitarbeiterstammdaten\n" +" * Mitarbeiterverträge\n" +" * Kennwortgeschützter Vertrag\n" +" * Bezüge und Abzüge\n" +" * Ermöglicht Grundlohn / Zulagen / Nettolohn\n" +" * Lohn-/Gehaltsnachweis\n" +" * Monatliche Lohn-/Gehalts -Saldenliste\n" +" * Urlaubsplanung ist integriert\n" +" " #. module: base #: selection:ir.cron,interval_type:0 @@ -6607,7 +6809,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_web_diagram msgid "OpenERP Web Diagram" -msgstr "" +msgstr "OpenERP Web Diagramm" #. module: base #: view:res.partner.bank:0 @@ -6744,6 +6946,43 @@ msgid "" "\n" " " msgstr "" +"\n" +"Ein generisches eMail Teilsystem mit Nachrichtenspeicherung und " +"Warteschlange.\n" +"====================================================================\n" +"\n" +"Dieses eMail-Teilsystem ist nicht zur alleinigen Nutzung gedacht, es soll " +"eine \n" +"vereinheitlichte Abstraktionsebene zur Verfügung stellen auf die alle " +"anderen\n" +"Anwendungen/Module zurückgreifen können.\n" +"\n" +"Hauptmerkmale sind:\n" +"\n" +" * Verkässt sich auf global eingerichtete Ausgangs-Mailserver im " +"Einrichtungs-\n" +" menü für erfolgreiche Mail-Zustellung.\n" +" * Bietet eine API zum Senden und Speichern von Nachrichten nach Thema " +"gruppiert.\n" +" * Jedes OpenERP-Dokument kann als Unterhaltungsthema dienen, " +"vorausgesetzt \n" +" dieses bietet die notwendige Unterstützung zum Umgang mit " +"eingehenden \n" +" Nachrichten (s. a. \"mail.thread\"-Klasse für Details.\n" +" * Bietet ein Warteschlangen-System mit automatischer Abarbeitung durch\n" +" konfigurierbarem Ausführungsplaner.\n" +" * Bietet einen allgemeinen eMail-Erstellungs-Assistenten der auch zum \n" +" MassenMail-Assistenten werden kann und in der Lage ist einfache \n" +" Platzhalter-Ausdrücke zu interpretieren. Diese werden mit " +"dynamischen\n" +" Daten ersetzt wenn die Nachricht tatsächlich versandt wird. Dieser \n" +" einfache, allgemeine Assistent kann auf einfache Weise erweitert " +"werden\n" +" auch höhere Ansprüche zu erfüllen (siehe \"email_template\" für ein " +"Beispiel,\n" +" welches eMail-Vorlagen-Merkmale diesem Assistenten hinzufügt).\n" +"\n" +" " #. module: base #: view:res.lang:0 @@ -6779,6 +7018,27 @@ msgid "" "an other object.\n" " " msgstr "" +"\n" +"Dieses Modul ermöglicht Ihnen die Verwaltung Ihrer Kontakte.\n" +"=====================================================\n" +"\n" +"Es läßt folgendes festlegen:\n" +" * Kontakte ohne Bezug zu einem Partner,\n" +" * Kontakte mit Bezug zu mehreren Addressen (evtl. bei verschiedenen " +"Partnern),\n" +" * Kontakte mit möglicherweise verschiedenen Funktionen \n" +" bei den verschiedenen Adressen,\n" +"\n" +"Ebenso werden neue Menüs hinzugefügt in:\n" +" Beschaffung / Addressbuch / Kontakte\n" +" Verkauf / Addressbuch / Kontakte\n" +"\n" +"Beachten Sie bitte, dass dieses Modul bestehende Addressen zu \"Addressen + " +"Kontake\" umwandelt. Dies\n" +"bedeutet, dass bedeutet, dass manche Felder bei den Addressen fehlen (wie " +"der Ansprechpartnername), da diese in einem anderen Objekt definiert sein " +"sollen.\n" +" " #. module: base #: model:ir.actions.act_window,name:base.act_res_partner_event @@ -6850,7 +7110,7 @@ msgstr "Deinstallieren" #. module: base #: model:ir.module.module,shortdesc:base.module_account_budget msgid "Budgets Management" -msgstr "" +msgstr "Budgetverwaltung" #. module: base #: field:workflow.triggers,workitem_id:0 @@ -6943,6 +7203,14 @@ msgid "" "using the\n" "FTP client.\n" msgstr "" +"\n" +"Dies ist die FTP-Unterstützung für das Dokumentenverwaltungssystem (DMS)\n" +"=================================================================\n" +"\n" +"Mit diesem Modul können Sie nicht nur über OpenERP auf Dokumente zugreifen, " +"sondern\n" +"können auch mit einen FTP-Programm auf das Dateisystem der Dokumente " +"zugreifen.\n" #. module: base #: field:ir.model.fields,size:0 @@ -6968,6 +7236,23 @@ msgid "" "\n" " " msgstr "" +"\n" +"Dieses Modul ermöglicht Ihnen die Festlegung von Vorgabe-Funktionen eines " +"Benutzers für bestimmte Konten.\n" +"=============================================================================" +"================\n" +"\n" +"Dies wird zumeist genutzt, wenn ein Nutzer seinen Stundennachweis ausfüllt. " +"Die Zahlenwerte werden abgefragt\n" +"und die Felder anschließend die Felder automatisch geschrieben. Die " +"Feldinhalte können danach immer noch\n" +"verändert werden.\n" +"\n" +"Offensichtlicherweise werden Felder ohne Eingaben mit den Vorgabewerten des " +"Mitarbeiters gefüllt, so dass\n" +"die Kompatibilität zu älteren Konfigurationen gegeben ist.\n" +"\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_audittrail @@ -7276,7 +7561,7 @@ msgstr "" #. module: base #: selection:res.currency,position:0 msgid "After Amount" -msgstr "" +msgstr "Betrag danach" #. module: base #: selection:base.language.install,lang:0 @@ -7326,7 +7611,7 @@ msgstr "Ursprungsbezeichnung" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_timesheet_sheet msgid "Timesheets Validation" -msgstr "" +msgstr "Bewilligung von Stundennachweisen" #. module: base #: model:ir.ui.menu,name:base.menu_main_pm @@ -7473,7 +7758,7 @@ msgstr "wird gelöscht" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_multilang msgid "Multi Language Chart of Accounts" -msgstr "" +msgstr "Mehrsprachige Kontenpläne" #. module: base #: selection:res.lang,direction:0 @@ -7500,6 +7785,18 @@ msgid "" "that have no counterpart in the general financial accounts.\n" " " msgstr "" +"\n" +"Modul zum Erstellen von Kostenstellenobjekten.\n" +"==========================================\n" +"\n" +"In OpenERP sind Kostenstellen-Konten an Konten der Finanzbuchhaltung " +"gebunden,\n" +"werden jedoch vollkommen losgelöst behandelt. So können Sie verschiedene " +"analytische\n" +"Operationen daran verüben, ohne daß sich dies in den Konten der " +"Finanzbuchhaltung \n" +"auswirken würde.\n" +" " #. module: base #: field:res.users,signature:0 @@ -7509,7 +7806,7 @@ msgstr "Signatur" #. module: base #: model:ir.module.module,shortdesc:base.module_crm_caldav msgid "Meetings Synchronization" -msgstr "" +msgstr "Abgleich von Besprechungsterminen" #. module: base #: field:ir.actions.act_window,context:0 @@ -7722,7 +8019,7 @@ msgstr "Honduras Buchführung" #. module: base #: model:ir.module.module,shortdesc:base.module_report_intrastat msgid "Intrastat Reporting" -msgstr "" +msgstr "Innergemeinschaftliche Handelsstatistik" #. module: base #: code:addons/base/res/res_users.py:222 @@ -7799,7 +8096,7 @@ msgstr "Erzeugtes Menü" #. module: base #: model:ir.module.module,shortdesc:base.module_account_analytic_default msgid "Account Analytic Defaults" -msgstr "" +msgstr "Kostenstellen Vorgabewerte" #. module: base #: model:ir.module.module,description:base.module_hr_contract @@ -7815,6 +8112,17 @@ msgid "" "You can assign several contracts per employee.\n" " " msgstr "" +"\n" +"Information aus der Mitarbeiter-Vertragsverwaltung auf Sicht verfügbar " +"machen.\n" +"=================================================================\n" +"\n" +" * Familienstand,\n" +" * Sozialversicherungsnummer,\n" +" * Geburtsort, Geburtsdatum, ---\n" +"\n" +"Sie können einem Mitarbeiter mehrere Verträge zuordnen.\n" +" " #. module: base #: selection:ir.ui.view,type:0 @@ -7937,7 +8245,7 @@ msgstr "Gelesen" #. module: base #: model:ir.module.module,shortdesc:base.module_association msgid "Associations Management" -msgstr "" +msgstr "Beziehungsmanagement" #. module: base #: help:ir.model,modules:0 @@ -8027,7 +8335,7 @@ msgstr "" #. module: base #: field:res.partner,title:0 msgid "Partner Firm" -msgstr "" +msgstr "Partner-Unternehmen" #. module: base #: model:ir.actions.act_window,name:base.action_model_fields @@ -8069,6 +8377,12 @@ msgid "" "Invite OpenERP user feedback, powered by uservoice.\n" " " msgstr "" +"\n" +"Rückmeldungs-Schaltfläche im Kopfbereich hinzufügen.\n" +"================================================\n" +"\n" +"OpenERP-Nutzer um Rückmeldung bitten; durch \"uservoice\" ermöglicht.\n" +" " #. module: base #: field:res.company,rml_header2:0 @@ -8136,6 +8450,13 @@ msgid "" "that exceeds minimum amount set by configuration wizard.\n" " " msgstr "" +"\n" +"Zweistufige Bewilligung bei Beschaffung mit Betragsüberschreitung.\n" +"===========================================================\n" +"\n" +"Dieses Modul verändert den Beschaffungs-Prozess so, dass eine Beschaffung,\n" +"ab einem einstellbaren Mindest-Betrag, zusätzlich bewilligt werden muss.\n" +" " #. module: base #: field:res.currency,rounding:0 @@ -8223,6 +8544,14 @@ msgid "" "all the tasks will change accordingly.\n" " " msgstr "" +"\n" +"Paßt Daten so an, dass Sie mit veränderten Projekt Abschlußdaten " +"korellieren.\n" +"=================================================================\n" +"\n" +"Wenn Projekt-Enddaten verändert werden, so werden Frist und Startdatum aller " +"Aufgaben entsprechend angepaßt.\n" +" " #. module: base #: help:res.users,view:0 @@ -8371,6 +8700,12 @@ msgid "" "Contains the installer for marketing-related modules.\n" " " msgstr "" +"\n" +"Menü für Marketing.\n" +"====================\n" +"\n" +"Enthält einen Installations-Assistenten für auf Marketing bezogene Module.\n" +" " #. module: base #: model:ir.module.category,name:base.module_category_knowledge_management @@ -8418,6 +8753,37 @@ msgid "" "task is completed.\n" "\n" msgstr "" +"\n" +"Erstellt automatisch Projektaufgaben aus Beschaffungsauftragspositionen.\n" +"===============================================================\n" +"\n" +"Dieses Modul generiert automatisch neue Aufgaben für jede Bedarfsposition " +"(z. B. \n" +"aus einer Verkaufsauftragsposition), wenn der korrespondierende Artikel mit " +"den \n" +"folgenden Charakteristika übereinstimmt:\n" +"\n" +" * Typ = Dienstleistung\n" +" * Dispositionsmethode = Beschaffe von Auftrag,\n" +" * Beschaffungsmethode = Fertigung,\n" +"\n" +"Wenn darüber hinaus auch noch ein Projekt in der Produkt-Sicht (Beschaffung " +"& Lagerorte)\n" +"festgelgt ist, dann wird die Aufgabe in diesem Projekt angelegt.\n" +"Andenfalls wird die Aufgabe keinem Projekt zugewiesen und kann später einem " +"manuell\n" +"einem Projekt zugewiesen werden.\n" +"\n" +"Wenn die Projekt-Aufgabe abgeschlossen oder storniert/abgebrochen wird, so " +"wird der \n" +"Prozess der zugehörigen Beschaffungsauftragzeile entsprechend aktualisiert. " +"Zum \n" +"Beispiel die Position des Beschaffungsauftrags zu einer " +"Verkaufsauftragsposition \n" +"korrespondiert, so wird diese Zeile als zugestellt angesehen, wenn die " +"Aufgabe\n" +"abgeschlossen ist.\n" +"\n" #. module: base #: code:addons/base/res/res_config.py:348 @@ -8476,6 +8842,25 @@ msgid "" "\n" " " msgstr "" +"\n" +"Dieses Modul generiert automatisch Projektaufgaben bei eingehenden eMails.\n" +"==================================================================\n" +"\n" +"Ermöglicht die erstellung von Aufgaben basierend auf neuen eMails in " +"bestimmten Postfächern,\n" +"ähnlich dem in Kundenverwaltungsbereich vorhandenen Mechanismus.\n" +"Es gibt zwei übliche Alternativen die Postfach-Integration festzulegen:\n" +"\n" +" * Das \"fetchmail\"-Modul installieren, ein neues Postfach anlegen und " +"dann\n" +" \"Projekt-Aufgaben\" als Ziel für die eingehenden Nachrichten auswählen.\n" +" * Selbst händisch in Ihrem Posteingangsserver auf Grundlage des \"Mail " +"Gateway\"\n" +" -Skripts des \"Post\"-Moduls - dieses darin an das \"project.task\"-Modell " +"binden.\n" +"\n" +"\n" +" " #. module: base #: model:ir.module.module,description:base.module_membership @@ -8589,6 +8974,9 @@ msgid "" "serialization field, instead of having its own database column. This cannot " "be changed after creation." msgstr "" +"Wenn gesetzt, wird dieses Feld in einer zusätzlichen Struktur des " +"Serialisierungsfeldes gespeichert anstelle einer eigenen Spalte in der " +"Datenbank. Dies kann nach Erstellung nicht mehr geändert werden." #. module: base #: view:res.partner.bank:0 @@ -8779,6 +9167,12 @@ msgid "" "\n" " * Share meeting with other calendar clients like sunbird\n" msgstr "" +"\n" +"CalDAV Merkmale in Besprechungen.\n" +"=================================\n" +"\n" +" * Besprechungen-Kalender mit anderen Kalender-Anwendungen wie Sunbird " +"gemeinsam nutzen.\n" #. module: base #: model:ir.module.module,shortdesc:base.module_base_iban @@ -9028,6 +9422,14 @@ msgid "" "for Wiki Quality Manual.\n" " " msgstr "" +"\n" +"Vorlage für Qualitätshandbuch.\n" +"===========================\n" +"\n" +"Liefert Beispieldaten unter gleichzeitiger Erstellung einer Wiki-Gruppe und " +"\n" +"einer Wiki-Seite für ein Wiki-Qualitätshandbuch.\n" +" " #. module: base #: model:ir.actions.act_window,name:base.act_values_form_action @@ -9491,6 +9893,17 @@ msgid "" "* Date\n" " " msgstr "" +"Setzt Vorgabewerte für Ihre Kostenstellen\n" +"Ermöglicht die automatische Auswahl von Kostenstellen gemäß den folgenden " +"Kriterien:\n" +"==========================================================================\n" +"\n" +"* Produkt\n" +"* Partner\n" +"* Benutzer\n" +"* Unternehmen\n" +"* Datum\n" +" " #. module: base #: model:res.country,name:base.ae @@ -9551,6 +9964,12 @@ msgid "" "Keep track of Wiki groups, pages, and history.\n" " " msgstr "" +"\n" +"Das Basis-Modul für die Dokumenten-Verwaltung:\n" +"=============================================\n" +"\n" +"Wiki-Gruppen, -Seiten und Historie verfolgen\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_mrp_repair diff --git a/openerp/addons/base/i18n/el.po b/openerp/addons/base/i18n/el.po index 7a9c9db6811..610613af10c 100644 --- a/openerp/addons/base/i18n/el.po +++ b/openerp/addons/base/i18n/el.po @@ -6,14 +6,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 16:03+0000\n" +"PO-Revision-Date: 2012-08-20 15:34+0000\n" "Last-Translator: Dimitris Andavoglou \n" "Language-Team: nls@hellug.gr \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:39+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n" +"X-Generator: Launchpad (build 15901)\n" "X-Poedit-Country: GREECE\n" "X-Poedit-Language: Greek\n" "X-Poedit-SourceCharset: utf-8\n" diff --git a/openerp/addons/base/i18n/en_GB.po b/openerp/addons/base/i18n/en_GB.po index d7bc4f79bbf..ee7bd182672 100644 --- a/openerp/addons/base/i18n/en_GB.po +++ b/openerp/addons/base/i18n/en_GB.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-02-24 16:14+0000\n" -"Last-Translator: John Bradshaw \n" +"PO-Revision-Date: 2012-08-20 15:47+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: English (United Kingdom) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:44+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -35,7 +35,7 @@ msgstr "DateTime" #. module: base #: model:ir.module.module,shortdesc:base.module_project_mailgate msgid "Tasks-Mail Integration" -msgstr "" +msgstr "Tasks-Mail Integration" #. module: base #: code:addons/fields.py:582 @@ -72,6 +72,21 @@ msgid "" " * Graph of My Remaining Hours by Project\n" " " msgstr "" +"\n" +"The Project management module tracks multi-level projects, tasks, work done " +"on tasks, etc.\n" +"=============================================================================" +"=========\n" +"\n" +"It is able to render plans, order tasks, etc.\n" +"\n" +"Dashboard for project members that includes:\n" +"--------------------------------------------\n" +" * List of my open tasks\n" +" * List of my delegated tasks\n" +" * Graph of My Projects: Planned vs Total Hours\n" +" * Graph of My Remaining Hours by Project\n" +" " #. module: base #: field:base.language.import,code:0 @@ -1817,6 +1832,22 @@ msgid "" "\n" " " msgstr "" +"\n" +"This module adds generic sharing tools to your current OpenERP database.\n" +"========================================================================\n" +"\n" +"It specifically adds a 'share' button that is available in the Web client " +"to\n" +"share any kind of OpenERP data with colleagues, customers, friends, etc.\n" +"\n" +"The system will work by creating new users and groups on the fly, and by\n" +"combining the appropriate access rights and ir.rules to ensure that the\n" +"shared users only have access to the data that has been shared with them.\n" +"\n" +"This is extremely useful for collaborative work, knowledge sharing,\n" +"synchronisation with other companies, etc.\n" +"\n" +" " #. module: base #: field:res.currency,accuracy:0 @@ -1946,6 +1977,8 @@ msgid "" "simplified payment mode encoding, automatic picking lists generation and " "more." msgstr "" +"Get the most out of your points of sales with fast sale encoding, simplified " +"payment mode encoding, automatic picking lists generation and more." #. module: base #: model:res.country,name:base.mv @@ -1992,7 +2025,7 @@ msgstr "Days" #. module: base #: model:ir.module.module,shortdesc:base.module_web_rpc msgid "OpenERP Web web" -msgstr "" +msgstr "OpenERP Web web" #. module: base #: model:ir.module.module,shortdesc:base.module_html_view @@ -3277,12 +3310,26 @@ msgid "" "since it's the same which has been renamed.\n" " " msgstr "" +"\n" +"This module lets users perform segmentation within partners.\n" +"=================================================================\n" +"\n" +"It improves the profiles criteria from the earlier segmentation module. " +"Thanks to the new concept of questionnaire. You can now regroup questions " +"into a questionnaire and directly use it on a partner.\n" +"\n" +"It also has been merged with the earlier CRM & SRM segmentation tool because " +"they were overlapping.\n" +"\n" +" * Note: this module is not compatible with the module segmentation, " +"since it's the same which has been renamed.\n" +" " #. module: base #: code:addons/report_sxw.py:434 #, python-format msgid "Unknown report type: %s" -msgstr "" +msgstr "Unknown report type: %s" #. module: base #: code:addons/base/ir/ir_model.py:282 @@ -3397,11 +3444,34 @@ msgid "" "\n" " " msgstr "" +"\n" +" \n" +"Belgian localisation for in- and outgoing invoices (prereq to " +"account_coda):\n" +" - Rename 'reference' field labels to 'Communication'\n" +" - Add support for Belgian Structured Communication\n" +"\n" +"A Structured Communication can be generated automatically on outgoing " +"invoices according to the following algorithms:\n" +" 1) Random : +++RRR/RRRR/RRRDD+++\n" +" R..R = Random Digits, DD = Check Digits\n" +" 2) Date : +++DOY/YEAR/SSSDD+++\n" +" DOY = Day of the Year, SSS = Sequence Number, DD = Check Digits)\n" +" 3) Customer Reference +++RRR/RRRR/SSSDDD+++\n" +" R..R = Customer Reference without non-numeric characters, SSS = " +"Sequence Number, DD = Check Digits) \n" +" \n" +"The preferred type of Structured Communication and associated Algorithm can " +"be specified on the Partner records. \n" +"A 'random' Structured Communication will generated if no algorithm is " +"specified on the Partner record. \n" +"\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_wiki_quality_manual msgid "Wiki: Quality Manual" -msgstr "" +msgstr "Wiki: Quality Manual" #. module: base #: selection:ir.actions.act_window.view,view_mode:0 @@ -3429,7 +3499,7 @@ msgstr "HR sector" #. module: base #: model:ir.ui.menu,name:base.menu_dashboard_admin msgid "Administration Dashboard" -msgstr "" +msgstr "Administration Dashboard" #. module: base #: code:addons/orm.py:4408 @@ -3489,7 +3559,7 @@ msgstr "" #. module: base #: model:res.groups,name:base.group_survey_user msgid "Survey / User" -msgstr "" +msgstr "Survey / User" #. module: base #: view:ir.module.module:0 @@ -3510,17 +3580,17 @@ msgstr "Web Icon File (hover)" #. module: base #: model:ir.module.module,description:base.module_web_diagram msgid "Openerp web Diagram view" -msgstr "" +msgstr "Openerp web Diagram view" #. module: base #: model:res.groups,name:base.group_hr_user msgid "HR Officer" -msgstr "" +msgstr "HR Officer" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_contract msgid "Employee Contracts" -msgstr "" +msgstr "Employee Contracts" #. module: base #: model:ir.module.module,description:base.module_wiki_faq @@ -3533,6 +3603,13 @@ msgid "" "for Wiki FAQ.\n" " " msgstr "" +"\n" +"This module provides a Wiki FAQ Template.\n" +"=========================================\n" +"\n" +"It provides demo data, thereby creating a Wiki Group and a Wiki Page\n" +"for Wiki FAQ.\n" +" " #. module: base #: view:ir.actions.server:0 @@ -3573,18 +3650,18 @@ msgstr "Contact Titles" #. module: base #: model:ir.module.module,shortdesc:base.module_product_manufacturer msgid "Products Manufacturers" -msgstr "" +msgstr "Products Manufacturers" #. module: base #: code:addons/base/ir/ir_mail_server.py:217 #, python-format msgid "SMTP-over-SSL mode unavailable" -msgstr "" +msgstr "SMTP-over-SSL mode unavailable" #. module: base #: model:ir.module.module,shortdesc:base.module_survey msgid "Survey" -msgstr "" +msgstr "Survey" #. module: base #: view:base.language.import:0 @@ -3632,7 +3709,7 @@ msgstr "Uruguay" #. module: base #: model:ir.module.module,shortdesc:base.module_fetchmail_crm msgid "eMail Gateway for Leads" -msgstr "" +msgstr "email Gateway for Leads" #. module: base #: selection:base.language.install,lang:0 @@ -3662,7 +3739,7 @@ msgstr "Fields Mapping" #. module: base #: model:ir.module.module,shortdesc:base.module_web_dashboard msgid "web Dashboard" -msgstr "" +msgstr "web Dashboard" #. module: base #: model:ir.module.module,description:base.module_sale @@ -3706,6 +3783,44 @@ msgid "" " * Graph of Sales by Product's Category in last 90 days\n" " " msgstr "" +"\n" +"The base module to manage quotations and sales orders.\n" +"======================================================\n" +"\n" +"Workflow with validation steps:\n" +"-------------------------------\n" +" * Quotation -> Sales order -> Invoice\n" +"\n" +"Invoicing methods:\n" +"------------------\n" +" * Invoice on order (before or after shipping)\n" +" * Invoice on delivery\n" +" * Invoice on timesheets\n" +" * Advance invoice\n" +"\n" +"Partners preferences:\n" +"---------------------\n" +" * shipping\n" +" * invoicing\n" +" * incoterm\n" +"\n" +"Products stocks and prices\n" +"--------------------------\n" +"\n" +"Delivery methods:\n" +"-----------------\n" +" * all at once\n" +" * multi-parcel\n" +" * delivery costs\n" +"\n" +"Dashboard for Sales Manager that includes:\n" +"------------------------------------------\n" +" * Quotations\n" +" * Sales by Month\n" +" * Graph of Sales by Salesperson in last 90 days\n" +" * Graph of Sales per Customer in last 90 days\n" +" * Graph of Sales by Product's Category in last 90 days\n" +" " #. module: base #: selection:base.language.install,lang:0 @@ -3729,6 +3844,14 @@ msgid "" "Canadian accounting charts and localizations.\n" " " msgstr "" +"\n" +"This is the module to manage the English and French - Canadian accounting " +"chart in OpenERP.\n" +"=============================================================================" +"==============\n" +"\n" +"Canadian accounting charts and localisations.\n" +" " #. module: base #: view:base.module.import:0 @@ -3761,6 +3884,13 @@ msgid "" " * the Tax Code Chart for Luxembourg\n" " * the main taxes used in Luxembourg" msgstr "" +"\n" +"This is the base module to manage the accounting chart for Luxembourg.\n" +"======================================================================\n" +"\n" +" * the KLUWER Chart of Accounts,\n" +" * the Tax Code Chart for Luxembourg\n" +" * the main taxes used in Luxembourg" #. module: base #: field:ir.module.module,demo:0 @@ -3785,6 +3915,19 @@ msgid "" "module 'share'.\n" " " msgstr "" +"\n" +"This module defines 'portals' to customise access to your OpenERP database\n" +"for external users.\n" +"\n" +"A portal defines customised user menu and access rights for a group of " +"users\n" +"(the ones associated to that portal). It also associates user groups to " +"the\n" +"portal users (adding a group in the portal automatically adds it to the " +"portal\n" +"users, etc). That feature is very handy when used in combination with the\n" +"module 'share'.\n" +" " #. module: base #: selection:res.request,priority:0 @@ -3812,7 +3955,7 @@ msgstr "Instances" #. module: base #: help:ir.mail_server,smtp_host:0 msgid "Hostname or IP of SMTP server" -msgstr "" +msgstr "Hostname or IP of SMTP server" #. module: base #: selection:base.language.install,lang:0 @@ -3842,12 +3985,12 @@ msgstr "Separator Format" #. module: base #: constraint:res.partner.bank:0 msgid "The RIB and/or IBAN is not valid" -msgstr "" +msgstr "The RIB and/or IBAN is not valid" #. module: base #: model:ir.module.module,shortdesc:base.module_report_webkit msgid "Webkit Report Engine" -msgstr "" +msgstr "Webkit Report Engine" #. module: base #: selection:publisher_warranty.contract,state:0 @@ -3874,13 +4017,13 @@ msgstr "Mayotte" #. module: base #: model:ir.module.module,shortdesc:base.module_crm_todo msgid "Tasks on CRM" -msgstr "" +msgstr "Tasks on CRM" #. module: base #: model:ir.module.category,name:base.module_category_generic_modules_accounting #: view:res.company:0 msgid "Accounting" -msgstr "" +msgstr "Accounting" #. module: base #: model:ir.module.module,description:base.module_account_payment @@ -3895,11 +4038,20 @@ msgid "" "* a basic mechanism to easily plug various automated payment.\n" " " msgstr "" +"\n" +"Module to manage invoice payment.\n" +"=================================\n" +"\n" +"This module provides :\n" +"----------------------\n" +"* A more efficient way to manage invoice payment.\n" +"* A basic mechanism to easily plug various automated payment.\n" +" " #. module: base #: view:ir.rule:0 msgid "Interaction between rules" -msgstr "" +msgstr "Interaction between rules" #. module: base #: model:ir.module.module,description:base.module_account_invoice_layout @@ -3921,11 +4073,27 @@ msgid "" "\n" " " msgstr "" +"\n" +"This module provides some features to improve the layout of the invoices.\n" +"=========================================================================\n" +"\n" +"It gives you the possibility to:\n" +"--------------------------------\n" +" * Order all the lines of an invoice\n" +" * Add titles, comment lines, sub total lines\n" +" * Draw horizontal lines and put page breaks\n" +"\n" +"Moreover, there is one option which allows you to print all the selected " +"invoices with a given special message at the bottom. This feature can be " +"very useful for printing your invoices with end-of-year wishes, special " +"punctual conditions.\n" +"\n" +" " #. module: base #: constraint:res.partner:0 msgid "Error ! You cannot create recursive associated members." -msgstr "" +msgstr "Error ! You cannot create recursive associated members." #. module: base #: view:res.payterm:0 @@ -3958,6 +4126,9 @@ msgid "" "or data in your OpenERP instance. To install some modules, click on the " "button \"Install\" from the form view and then click on \"Start Upgrade\"." msgstr "" +"You can install new modules to activate new features, menu, reports or data " +"in your OpenERP instance. To install modules, click on the button " +"\"Install\" from the form view and then click on \"Start Upgrade\"." #. module: base #: model:ir.actions.act_window,name:base.ir_cron_act @@ -3973,6 +4144,9 @@ msgid "" " OpenERP Web chat module.\n" " " msgstr "" +"\n" +" OpenERP Web chat module.\n" +" " #. module: base #: field:res.partner.address,title:0 @@ -3995,12 +4169,12 @@ msgstr "Recursivity detected." #. module: base #: model:ir.module.module,shortdesc:base.module_report_webkit_sample msgid "Webkit Report Samples" -msgstr "" +msgstr "Webkit Report Samples" #. module: base #: model:ir.module.module,shortdesc:base.module_point_of_sale msgid "Point Of Sale" -msgstr "" +msgstr "Point Of Sale" #. module: base #: code:addons/base/module/module.py:302 @@ -4036,7 +4210,7 @@ msgstr "" #. module: base #: selection:ir.sequence,implementation:0 msgid "Standard" -msgstr "" +msgstr "Standard" #. module: base #: model:ir.model,name:base.model_maintenance_contract @@ -4065,11 +4239,13 @@ msgid "" "Invalid value for reference field \"%s.%s\" (last part must be a non-zero " "integer): \"%s\"" msgstr "" +"Invalid value for reference field \"%s.%s\" (last part must be a non-zero " +"integer): \"%s\"" #. module: base #: model:ir.module.category,name:base.module_category_human_resources msgid "Human Resources" -msgstr "" +msgstr "Human Resources" #. module: base #: model:ir.actions.act_window,name:base.action_country @@ -4085,7 +4261,7 @@ msgstr "RML (deprecated - use Report)" #. module: base #: sql_constraint:ir.translation:0 msgid "Language code of translation item must be among known languages" -msgstr "" +msgstr "Language code of translation item must be among known languages" #. module: base #: view:ir.rule:0 @@ -4109,6 +4285,14 @@ msgid "" "templates to target objects.\n" " " msgstr "" +"\n" +" * Multi language support for Chart of Accounts, Taxes, Tax Codes , " +"Journals, Accounting Templates,\n" +" Analytic Chart of Accounts and Analytic Journals.\n" +" * Setup wizard changes\n" +" - Copy translations for COA, Tax, Tax Code and Fiscal Position from " +"templates to target objects.\n" +" " #. module: base #: view:ir.actions.todo:0 @@ -4129,7 +4313,7 @@ msgstr "VAT" #. module: base #: field:res.users,new_password:0 msgid "Set password" -msgstr "" +msgstr "Set password" #. module: base #: view:res.lang:0 @@ -4223,6 +4407,8 @@ msgid "" "la moneda Lempira. -- Adds accounting chart for Honduras. It also includes " "taxes and the Lempira currency" msgstr "" +"Adds accounting chart for Honduras. It also includes taxes and the Lempira " +"currency" #. module: base #: selection:ir.actions.act_window,view_type:0 @@ -4243,6 +4429,10 @@ msgid "" "Italian accounting chart and localization.\n" " " msgstr "" +"\n" +"Italian accounting chart and localization.\n" +"================================================\n" +" " #. module: base #: model:res.country,name:base.me @@ -4252,12 +4442,12 @@ msgstr "Montenegro" #. module: base #: model:ir.module.module,shortdesc:base.module_document_ics msgid "iCal Support" -msgstr "" +msgstr "iCal Support" #. module: base #: model:ir.module.module,shortdesc:base.module_fetchmail msgid "Email Gateway" -msgstr "" +msgstr "Email Gateway" #. module: base #: code:addons/base/ir/ir_mail_server.py:439 @@ -4266,6 +4456,8 @@ msgid "" "Mail delivery failed via SMTP server '%s'.\n" "%s: %s" msgstr "" +"Mail delivery failed via SMTP server '%s'.\n" +"%s: %s" #. module: base #: view:ir.cron:0 @@ -4308,6 +4500,16 @@ msgid "" "user rights to Demo user.\n" " " msgstr "" +"\n" +"Accounting Access Rights.\n" +"=========================\n" +"\n" +"This module gives the admin user access to all the accounting features\n" +"such as journal items and the chart of accounts.\n" +"\n" +"It assigns manager and user access rights to the Administrator, and only\n" +"user rights to Demo user.\n" +" " #. module: base #: selection:ir.module.module,state:0 @@ -4333,12 +4535,12 @@ msgstr "Liechtenstein" #. module: base #: model:ir.module.module,description:base.module_web_rpc msgid "Openerp web web" -msgstr "" +msgstr "Openerp web web" #. module: base #: model:ir.module.module,shortdesc:base.module_project_issue_sheet msgid "Timesheet on Issues" -msgstr "" +msgstr "Timesheet on Issues" #. module: base #: model:res.partner.title,name:base.res_partner_title_ltd @@ -4359,6 +4561,16 @@ msgid "" " * Cheque Register\n" " " msgstr "" +"\n" +"Account Voucher module includes all the basic requirements of Voucher " +"Entries for Bank, Cash, Sales, Purchase, Expanse, Contra, etc.\n" +"=============================================================================" +"=======================================================\n" +"\n" +" * Voucher Entry\n" +" * Voucher Receipt\n" +" * Cheque Register\n" +" " #. module: base #: field:res.partner,ean13:0 @@ -4379,7 +4591,7 @@ msgstr "Portugal" #. module: base #: model:ir.module.module,shortdesc:base.module_share msgid "Share any Document" -msgstr "" +msgstr "Share any Document" #. module: base #: field:ir.module.module,certificate:0 @@ -4425,11 +4637,41 @@ msgid "" "\n" "\n" msgstr "" +"\n" +"This improves OpenERP multi-currency handling in analytic accountiong, " +"overall for multi-company.\n" +"\n" +"This module is based on the work made in all c2c_multicost* available on the " +"v5.0 stable version and\n" +"allow you to share analytic account between company (even if currency " +"differs in each one).\n" +"\n" +"What has been done here:\n" +"\n" +" * Adapt the owner of analytic line (= to company that own the general " +"account associated with en analytic line)\n" +" * Add multi-currency on analytic lines (similar to financial accounting)\n" +" * Correct all \"costs\" indicators into analytic account to base them on " +"the right currency (owner's company)\n" +" * By default, nothing change for single company implementation.\n" +"\n" +"As a result, we can now really share the same analytic account between " +"companies that don't have the same \n" +"currency. This setup becomes True, Enjoy !\n" +"\n" +"- Company A : EUR\n" +"- Company B : CHF\n" +"\n" +"- Analytic Account A : USD, owned by Company A\n" +" - Analytic Account B : CHF, owned by Company A\n" +" - Analytic Account C : EUR, owned by Company B\n" +"\n" +"\n" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_it msgid "Italy - Accounting" -msgstr "" +msgstr "Italy - Accounting" #. module: base #: field:ir.actions.act_window,help:0 @@ -4448,6 +4690,9 @@ msgid "" "its dependencies are satisfied. If the module has no dependency, it is " "always installed." msgstr "" +"An auto-installable module is automatically installed by the system when all " +"its dependencies are satisfied. If the module has no dependency, it is " +"always installed." #. module: base #: model:ir.actions.act_window,name:base.res_lang_act_window @@ -4470,6 +4715,16 @@ msgid "" "automatically new claims based on incoming emails.\n" " " msgstr "" +"\n" +"This modules allows you to track your customers/suppliers claims and " +"grievances.\n" +"=============================================================================" +"===\n" +"\n" +"It is fully integrated with the email gateway so you can automatically " +"create\n" +"new claims based on incoming emails.\n" +" " #. module: base #: selection:workflow.activity,join_mode:0 @@ -4480,7 +4735,7 @@ msgstr "Xor" #. module: base #: model:ir.module.category,name:base.module_category_localization_account_charts msgid "Account Charts" -msgstr "" +msgstr "Account Charts" #. module: base #: view:res.request:0 @@ -4551,6 +4806,22 @@ msgid "" "anonymization process to recover your previous data.\n" " " msgstr "" +"\n" +"This module allows you to anonymise a database.\n" +"===============================================\n" +"\n" +"This module lets you keep your data confidential for a given database.\n" +"This process is useful if you want to use the migration process and protect\n" +"your own or your customer’s confidential data. The principle is that you " +"run\n" +"an anonymisation tool which will hide your confidential data (they are " +"replaced\n" +"by ‘XXX’ characters). Then you can send the anonymized database to the " +"migration\n" +"team. Once you get back your migrated database, you restore it and reverse " +"the\n" +"anonymisation process to recover your previous data.\n" +" " #. module: base #: help:publisher_warranty.contract,name:0 @@ -4559,6 +4830,8 @@ msgid "" "Your OpenERP Publisher's Warranty Contract unique key, also called serial " "number." msgstr "" +"Your OpenERP Publisher's Warranty Contract unique key, also called serial " +"number." #. module: base #: model:ir.module.module,description:base.module_base_setup @@ -4573,6 +4846,15 @@ msgid "" "\n" " " msgstr "" +"\n" +"This module helps configure the system at the installation of a new " +"database.\n" +"=============================================================================" +"===\n" +"\n" +"Shows you a list of applications features to install from.\n" +"\n" +" " #. module: base #: field:ir.actions.report.xml,report_sxw_content:0 @@ -4583,7 +4865,7 @@ msgstr "SXW content" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_pl msgid "Poland - Accounting" -msgstr "" +msgstr "Poland - Accounting" #. module: base #: view:ir.cron:0 @@ -4613,6 +4895,20 @@ msgid "" "\n" " " msgstr "" +"\n" +"Purchase module is for generating a purchase order for purchase of goods " +"from a supplier.\n" +"=============================================================================" +"============\n" +"\n" +"A supplier invoice is created for the particular purchase order.\n" +"\n" +"Dashboard for purchase management that includes:\n" +" * Current Purchase Orders\n" +" * Draft Purchase Orders\n" +" * Graph for quantity and amount per month\n" +"\n" +" " #. module: base #: view:ir.model.fields:0 @@ -4634,7 +4930,7 @@ msgstr "Summary" #. module: base #: model:ir.module.category,name:base.module_category_hidden_dependency msgid "Dependency" -msgstr "" +msgstr "Dependency" #. module: base #: field:multi_company.default,expression:0 @@ -4657,6 +4953,8 @@ msgid "" "When no specific mail server is requested for a mail, the highest priority " "one is used. Default priority is 10 (smaller number = higher priority)" msgstr "" +"When no specific mail server is requested for a mail, the highest priority " +"one is used. Default priority is 10 (smaller number = higher priority)" #. module: base #: model:ir.module.module,description:base.module_crm_partner_assign @@ -4675,6 +4973,19 @@ msgid "" "You can also use the geolocalization without using the GPS coordinates.\n" " " msgstr "" +"\n" +"This is the module used by OpenERP SA to redirect customers to its partners, " +"based on geolocalisation.\n" +"=============================================================================" +"=========================\n" +"\n" +"You can geolocalise your opportunities using this module.\n" +"\n" +"Use geolocalisation when assigning opportunities to partners.\n" +"Determine the GPS coordinates according to the address of the partner.\n" +"The most appropriate partner can be assigned.\n" +"You can also use the geolocalisation without GPS coordinates.\n" +" " #. module: base #: help:ir.actions.act_window,help:0 @@ -4708,7 +5019,7 @@ msgstr "Trigger Object" #. module: base #: sql_constraint:ir.sequence.type:0 msgid "`code` must be unique." -msgstr "" +msgstr "`code` must be unique." #. module: base #: model:ir.module.module,shortdesc:base.module_hr_expense diff --git a/openerp/addons/base/i18n/es.po b/openerp/addons/base/i18n/es.po index ef47237de9f..3f0a4646113 100644 --- a/openerp/addons/base/i18n/es.po +++ b/openerp/addons/base/i18n/es.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-03-12 08:10+0000\n" -"Last-Translator: German Figueredo \n" +"PO-Revision-Date: 2012-08-20 15:29+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:43+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -29,7 +29,7 @@ msgstr "Otra configuración" #. module: base #: selection:ir.property,type:0 msgid "DateTime" -msgstr "FechaHora" +msgstr "Fecha y hora" #. module: base #: model:ir.module.module,shortdesc:base.module_project_mailgate @@ -2098,7 +2098,7 @@ msgstr "Modelo archivo adjunto" #. module: base #: field:res.partner.bank,footer:0 msgid "Display on Reports" -msgstr "" +msgstr "Mostrar en Informes" #. module: base #: model:ir.module.module,description:base.module_l10n_cn @@ -2260,7 +2260,7 @@ msgstr "Finlandia" #: code:addons/base/res/res_company.py:156 #, python-format msgid "Website: " -msgstr "" +msgstr "Sitio web: " #. module: base #: model:ir.ui.menu,name:base.menu_administration @@ -2279,7 +2279,7 @@ msgstr "Árbol" #. module: base #: model:ir.module.module,shortdesc:base.module_analytic_multicurrency msgid "Multi-Currency in Analytic" -msgstr "" +msgstr "Multi-Moneda en Analitica" #. module: base #: view:base.language.export:0 @@ -2297,6 +2297,8 @@ msgid "" "Display this bank account on the footer of printed documents like invoices " "and sales orders." msgstr "" +"Mostrar esta cuenta bancaria en el pie de página de los documentos impresos " +"como facturas y órdenes de venta." #. module: base #: view:base.language.import:0 @@ -2400,12 +2402,12 @@ msgstr "" #. module: base #: field:ir.values,action_id:0 msgid "Action (change only)" -msgstr "" +msgstr "Acción (solo cambio)" #. module: base #: model:ir.module.module,shortdesc:base.module_subscription msgid "Recurring Documents" -msgstr "" +msgstr "Documentos Recurrentes" #. module: base #: model:res.country,name:base.bs @@ -2444,7 +2446,7 @@ msgstr "Número de módulos actualizados" #. module: base #: field:ir.cron,function:0 msgid "Method" -msgstr "" +msgstr "Método" #. module: base #: view:res.partner.event:0 @@ -2469,7 +2471,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_base_setup msgid "Initial Setup Tools" -msgstr "" +msgstr "Herramientas de Configuración Inicial" #. module: base #: field:ir.actions.act_window,groups_id:0 @@ -2531,7 +2533,7 @@ msgstr "Gestión de widgets de la página inicial" #. module: base #: field:res.company,rml_header1:0 msgid "Report Header / Company Slogan" -msgstr "" +msgstr "Encabezado del Informe / Lema de la Empresa" #. module: base #: model:res.country,name:base.pl @@ -2585,7 +2587,7 @@ msgstr "" #. module: base #: field:ir.mail_server,smtp_debug:0 msgid "Debugging" -msgstr "" +msgstr "Depurando" #. module: base #: model:ir.module.module,description:base.module_crm_helpdesk @@ -2696,12 +2698,12 @@ msgstr "Tasa" #. module: base #: model:ir.module.module,shortdesc:base.module_idea msgid "Ideas" -msgstr "" +msgstr "Ideas" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_crm msgid "Opportunity to Quotation" -msgstr "" +msgstr "Oportunidad a Presupuesto" #. module: base #: model:ir.module.module,description:base.module_sale_analytic_plans @@ -2728,17 +2730,17 @@ msgstr "" #. module: base #: model:ir.actions.report.xml,name:base.report_ir_model_overview msgid "Model Overview" -msgstr "" +msgstr "Información general del modelo" #. module: base #: model:ir.module.module,shortdesc:base.module_product_margin msgid "Margins by Products" -msgstr "" +msgstr "Márgenes por Productos" #. module: base #: model:ir.ui.menu,name:base.menu_invoiced msgid "Invoicing" -msgstr "" +msgstr "Facturar" #. module: base #: field:ir.ui.view_sc,name:0 @@ -2773,13 +2775,13 @@ msgstr "Importar / Exportar" #. module: base #: model:ir.actions.todo.category,name:base.category_tools_customization_config msgid "Tools / Customization" -msgstr "" +msgstr "Herramientas / Personalización" #. module: base #: field:ir.model.data,res_id:0 #: field:ir.values,res_id:0 msgid "Record ID" -msgstr "" +msgstr "ID de registro" #. module: base #: field:ir.actions.server,email:0 @@ -2865,7 +2867,7 @@ msgstr "" #: model:res.groups,name:base.group_sale_manager #: model:res.groups,name:base.group_tool_manager msgid "Manager" -msgstr "" +msgstr "Responsable" #. module: base #: model:ir.ui.menu,name:base.menu_custom @@ -2902,7 +2904,7 @@ msgstr "Eliminar ID's" #. module: base #: view:res.groups:0 msgid "Inherited" -msgstr "" +msgstr "Hededado" #. module: base #: field:ir.model.fields,serialization_field_id:0 @@ -2915,6 +2917,8 @@ msgid "" "Lets you install various tools to simplify and enhance OpenERP's report " "creation." msgstr "" +"Permite instalar varias herramientas para simplificar y mejorar la creación " +"de informes OpenERP." #. module: base #: view:res.lang:0 @@ -2925,7 +2929,7 @@ msgstr "%y - Año sin el siglo [00,99]." #: code:addons/base/res/res_company.py:155 #, python-format msgid "Fax: " -msgstr "" +msgstr "Fax: " #. module: base #: model:res.country,name:base.si @@ -2935,7 +2939,7 @@ msgstr "Eslovenia" #. module: base #: help:res.currency,name:0 msgid "Currency Code (ISO 4217)" -msgstr "" +msgstr "Código de moneda (ISO 4217)" #. module: base #: model:ir.actions.act_window,name:base.res_log_act_window @@ -3135,7 +3139,7 @@ msgstr "" #: code:addons/report_sxw.py:434 #, python-format msgid "Unknown report type: %s" -msgstr "" +msgstr "Tipo de informe desconocido: %s" #. module: base #: code:addons/base/ir/ir_model.py:282 diff --git a/openerp/addons/base/i18n/es_AR.po b/openerp/addons/base/i18n/es_AR.po index fdc9c0340dd..cd7ff89c0ef 100644 --- a/openerp/addons/base/i18n/es_AR.po +++ b/openerp/addons/base/i18n/es_AR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:44+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/es_CL.po b/openerp/addons/base/i18n/es_CL.po index 9c200b406c5..f215912bd37 100644 --- a/openerp/addons/base/i18n/es_CL.po +++ b/openerp/addons/base/i18n/es_CL.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:44+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/es_CR.po b/openerp/addons/base/i18n/es_CR.po index a5124cc2596..87c2b8aa483 100644 --- a/openerp/addons/base/i18n/es_CR.po +++ b/openerp/addons/base/i18n/es_CR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:45+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n" +"X-Generator: Launchpad (build 15901)\n" "Language: \n" #. module: base diff --git a/openerp/addons/base/i18n/es_EC.po b/openerp/addons/base/i18n/es_EC.po index 9a8ee789f45..0ba92adb8ff 100644 --- a/openerp/addons/base/i18n/es_EC.po +++ b/openerp/addons/base/i18n/es_EC.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:45+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/es_MX.po b/openerp/addons/base/i18n/es_MX.po new file mode 100644 index 00000000000..cc9d519e705 --- /dev/null +++ b/openerp/addons/base/i18n/es_MX.po @@ -0,0 +1,15177 @@ +# Spanish (Mexico) translation for openobject-server +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the openobject-server package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-server\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-02-08 00:44+0000\n" +"PO-Revision-Date: 2012-09-07 01:11+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Spanish (Mexico) \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-09-08 04:54+0000\n" +"X-Generator: Launchpad (build 15914)\n" + +#. module: base +#: model:res.country,name:base.sh +msgid "Saint Helena" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Other Configuration" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "DateTime" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_project_mailgate +msgid "Tasks-Mail Integration" +msgstr "" + +#. module: base +#: code:addons/fields.py:582 +#, python-format +msgid "" +"The second argument of the many2many field %s must be a SQL table !You used " +"%s, which is not a valid SQL table name." +msgstr "" + +#. module: base +#: field:ir.ui.view,arch:0 +#: field:ir.ui.view.custom,arch:0 +msgid "View Architecture" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project +msgid "" +"\n" +"Project management module tracks multi-level projects, tasks, work done on " +"tasks, eso.\n" +"=============================================================================" +"=========\n" +"\n" +"It is able to render planning, order tasks, eso.\n" +"\n" +"Dashboard for project members that includes:\n" +"--------------------------------------------\n" +" * List of my open tasks\n" +" * List of my delegated tasks\n" +" * Graph of My Projects: Planned vs Total Hours\n" +" * Graph of My Remaining Hours by Project\n" +" " +msgstr "" + +#. module: base +#: field:base.language.import,code:0 +msgid "Code (eg:en__US)" +msgstr "" + +#. module: base +#: view:workflow:0 +#: view:workflow.activity:0 +#: field:workflow.activity,wkf_id:0 +#: field:workflow.instance,wkf_id:0 +#: field:workflow.transition,wkf_id:0 +#: field:workflow.workitem,wkf_id:0 +msgid "Workflow" +msgstr "" + +#. module: base +#: selection:ir.sequence,implementation:0 +msgid "No gap" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Hungarian / Magyar" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PY) / Español (PY)" +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_project_management +msgid "" +"Helps you manage your projects and tasks by tracking them, generating " +"plannings, etc..." +msgstr "" + +#. module: base +#: field:ir.actions.act_window,display_menu_tip:0 +msgid "Display Menu Tips" +msgstr "" + +#. module: base +#: help:ir.cron,model:0 +msgid "" +"Model name on which the method to be called is located, e.g. 'res.partner'." +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Created Views" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:532 +#, python-format +msgid "" +"You can not write in this document (%s) ! Be sure your user belongs to one " +"of these groups: %s." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_event_project +msgid "" +"\n" +"Organization and management of events.\n" +"======================================\n" +"\n" +"This module allows you to create retro planning for managing your events.\n" +msgstr "" + +#. module: base +#: help:ir.model.fields,domain:0 +msgid "" +"The optional domain to restrict possible values for relationship fields, " +"specified as a Python expression defining a list of triplets. For example: " +"[('color','=','red')]" +msgstr "" + +#. module: base +#: field:res.partner,ref:0 +msgid "Reference" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_be_invoice_bba +msgid "Belgium - Structured Communication" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,target:0 +msgid "Target Window" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_sale_analytic_plans +msgid "Sales Analytic Distribution" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_process +msgid "Process" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_analytic_journal_billing_rate +msgid "Billing Rates on Contracts" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:558 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:344 +#, python-format +msgid "" +"Properties of base fields cannot be altered in this manner! Please modify " +"them through Python code, preferably through a custom addon!" +msgstr "" + +#. module: base +#: code:addons/osv.py:129 +#, python-format +msgid "Constraint Error" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_view_custom +msgid "ir.ui.view.custom" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:313 +#, python-format +msgid "Renaming sparse field \"%s\" is not allowed" +msgstr "" + +#. module: base +#: model:res.country,name:base.sz +msgid "Swaziland" +msgstr "" + +#. module: base +#: code:addons/orm.py:4206 +#, python-format +msgid "created." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_tr +msgid "Turkey - Accounting" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_mrp_subproduct +msgid "MRP Subproducts" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:390 +#, python-format +msgid "" +"Some installed modules depend on the module you plan to Uninstall :\n" +" %s" +msgstr "" + +#. module: base +#: field:ir.sequence,number_increment:0 +msgid "Increment Number" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_company_tree +#: model:ir.ui.menu,name:base.menu_action_res_company_tree +msgid "Company's Structure" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Inuktitut / ᐃᓄᒃᑎᑐᑦ" +msgstr "" + +#. module: base +#: model:ir.actions.todo.category,name:base.category_sales_management_config +#: model:ir.module.category,name:base.module_category_sales_management +#: model:ir.module.module,shortdesc:base.module_sale +msgid "Sales Management" +msgstr "" + +#. module: base +#: view:res.partner:0 +msgid "Search Partner" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:60 +#, python-format +msgid "new" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,multi:0 +msgid "On multiple doc." +msgstr "" + +#. module: base +#: field:ir.module.category,module_nr:0 +msgid "Number of Modules" +msgstr "" + +#. module: base +#: help:multi_company.default,company_dest_id:0 +msgid "Company to store the current record" +msgstr "" + +#. module: base +#: field:res.partner.bank.type.field,size:0 +msgid "Max. Size" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_reporting +#: model:ir.ui.menu,name:base.menu_lunch_reporting +#: model:ir.ui.menu,name:base.menu_project_report +#: model:ir.ui.menu,name:base.menu_report_association +#: model:ir.ui.menu,name:base.menu_report_marketing +#: model:ir.ui.menu,name:base.menu_reporting +#: model:ir.ui.menu,name:base.next_id_64 +#: model:ir.ui.menu,name:base.next_id_73 +#: model:ir.ui.menu,name:base.reporting_menu +msgid "Reporting" +msgstr "" + +#. module: base +#: view:res.partner:0 +#: field:res.partner,subname:0 +#: field:res.partner.address,name:0 +msgid "Contact Name" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:56 +#, python-format +msgid "" +"Save this document to a %s file and edit it with a specific software or a " +"text editor. The file encoding is UTF-8." +msgstr "" + +#. module: base +#: help:ir.values,key2:0 +msgid "" +"For actions, one of the possible action slots: \n" +" - client_action_multi\n" +" - client_print_multi\n" +" - client_action_relate\n" +" - tree_but_open\n" +"For defaults, an optional condition" +msgstr "" + +#. module: base +#: sql_constraint:res.lang:0 +msgid "The name of the language must be unique !" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_import_base +msgid "" +"\n" +" This module provide a class import_framework to help importing \n" +" complex data from other software\n" +" " +msgstr "" + +#. module: base +#: field:ir.actions.wizard,wiz_name:0 +msgid "Wizard Name" +msgstr "" + +#. module: base +#: model:res.groups,name:base.group_partner_manager +msgid "Partner Manager" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_customer_relationship_management +msgid "Customer Relationship Management" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Extra" +msgstr "" + +#. module: base +#: code:addons/orm.py:2526 +#, python-format +msgid "Invalid group_by" +msgstr "" + +#. module: base +#: field:ir.module.category,child_ids:0 +msgid "Child Applications" +msgstr "" + +#. module: base +#: field:res.partner,credit_limit:0 +msgid "Credit Limit" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_graph +msgid "Openerp web graph view" +msgstr "" + +#. module: base +#: field:ir.model.data,date_update:0 +msgid "Update Date" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_action_rule +msgid "Automated Action Rules" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Owner" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,src_model:0 +msgid "Source Object" +msgstr "" + +#. module: base +#: model:res.partner.bank.type,format_layout:base.bank_normal +msgid "%(bank_name)s: %(acc_number)s" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Config Wizard Steps" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_view_sc +msgid "ir.ui.view_sc" +msgstr "" + +#. module: base +#: field:res.widget.user,widget_id:0 +#: field:res.widget.wizard,widgets_list:0 +msgid "Widget" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: field:ir.model.access,group_id:0 +msgid "Group" +msgstr "" + +#. module: base +#: constraint:res.lang:0 +msgid "" +"Invalid date/time format directive specified. Please refer to the list of " +"allowed directives, displayed when you edit a language." +msgstr "" + +#. module: base +#: code:addons/orm.py:3895 +#, python-format +msgid "" +"One of the records you are trying to modify has already been deleted " +"(Document type: %s)." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_pad_project +msgid "Specifications on PADs" +msgstr "" + +#. module: base +#: help:ir.filters,user_id:0 +msgid "" +"The user this filter is available to. When left empty the filter is usable " +"by the system only." +msgstr "" + +#. module: base +#: help:res.partner,website:0 +msgid "Website of Partner." +msgstr "" + +#. module: base +#: help:ir.actions.act_window,views:0 +msgid "" +"This function field computes the ordered list of views that should be " +"enabled when displaying the result of an action, federating view mode, views " +"and reference view. The result is returned as an ordered list of pairs " +"(view_id,view_mode)." +msgstr "" + +#. module: base +#: model:res.country,name:base.tv +msgid "Tuvalu" +msgstr "" + +#. module: base +#: selection:ir.model,state:0 +msgid "Custom Object" +msgstr "" + +#. module: base +#: field:res.lang,date_format:0 +msgid "Date Format" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_report_designer +msgid "OpenOffice Report Designer" +msgstr "" + +#. module: base +#: field:res.bank,email:0 +#: field:res.partner.address,email:0 +msgid "E-Mail" +msgstr "" + +#. module: base +#: model:res.country,name:base.an +msgid "Netherlands Antilles" +msgstr "" + +#. module: base +#: model:res.country,name:base.ro +msgid "Romania" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:396 +#, python-format +msgid "" +"You can not remove the admin user as it is used internally for resources " +"created by OpenERP (updates, module installation, ...)" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Action Binding" +msgstr "" + +#. module: base +#: model:res.country,name:base.gf +msgid "French Guyana" +msgstr "" + +#. module: base +#: field:ir.ui.view.custom,ref_id:0 +msgid "Original View" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Bosnian / bosanski jezik" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,attachment_use:0 +msgid "" +"If you check this, then the second time the user prints with same attachment " +"name, it returns the previous report." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_sale_layout +msgid "Sales Orders Print Layout" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (VE) / Español (VE)" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr_timesheet_invoice +msgid "Invoice on Timesheets" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "Your system will be updated." +msgstr "" + +#. module: base +#: field:ir.actions.todo,note:0 +#: selection:ir.property,type:0 +msgid "Text" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_followup +msgid "" +"\n" +"Module to automate letters for unpaid invoices, with multi-level recalls.\n" +"==========================================================================\n" +"\n" +"You can define your multiple levels of recall through the menu:\n" +" Accounting/Configuration/Miscellaneous/Follow-Ups\n" +"\n" +"Once it is defined, you can automatically print recalls every day through " +"simply clicking on the menu:\n" +" Accounting/Periodical Processing/Billing/Send followups\n" +"\n" +"It will generate a PDF with all the letters according to the the\n" +"different levels of recall defined. You can define different policies\n" +"for different companies. You can also send mail to the customer.\n" +"\n" +"Note that if you want to check the followup level for a given " +"partner/account entry, you can do from in the menu:\n" +" Accounting/Reporting/Generic Reporting/Partners/Follow-ups Sent\n" +"\n" +msgstr "" + +#. module: base +#: field:res.country,name:0 +msgid "Country Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.co +msgid "Colombia" +msgstr "" + +#. module: base +#: code:addons/orm.py:1390 +#, python-format +msgid "Key/value '%s' not found in selection field '%s'" +msgstr "" + +#. module: base +#: help:res.country,code:0 +msgid "" +"The ISO country code in two chars.\n" +"You can use this field for quick search." +msgstr "" + +#. module: base +#: model:res.country,name:base.pw +msgid "Palau" +msgstr "" + +#. module: base +#: view:res.partner:0 +msgid "Sales & Purchases" +msgstr "" + +#. module: base +#: view:ir.translation:0 +msgid "Untranslated" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,context:0 +msgid "" +"Context dictionary as Python expression, empty by default (Default: {})" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_action_wizard +#: view:ir.actions.wizard:0 +#: model:ir.ui.menu,name:base.menu_ir_action_wizard +msgid "Wizards" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_miscellaneoussuppliers0 +msgid "Miscellaneous Suppliers" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:287 +#, python-format +msgid "Custom fields must have a name that starts with 'x_' !" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_mx +msgid "Mexico - Accounting" +msgstr "" + +#. module: base +#: help:ir.actions.server,action_id:0 +msgid "Select the Action Window, Report, Wizard to be executed." +msgstr "" + +#. module: base +#: model:res.country,name:base.ai +msgid "Anguilla" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "Export done" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_plugin_outlook +msgid "Outlook Plug-In" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: field:ir.model,name:0 +msgid "Model Description" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,src_model:0 +msgid "" +"Optional model name of the objects on which this action should be visible" +msgstr "" + +#. module: base +#: field:workflow.transition,trigger_expr_id:0 +msgid "Trigger Expression" +msgstr "" + +#. module: base +#: model:res.country,name:base.jo +msgid "Jordan" +msgstr "" + +#. module: base +#: help:ir.cron,nextcall:0 +msgid "Next planned execution date for this job." +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:139 +#, python-format +msgid "You can not remove the model '%s' !" +msgstr "" + +#. module: base +#: model:res.country,name:base.er +msgid "Eritrea" +msgstr "" + +#. module: base +#: sql_constraint:res.company:0 +msgid "The company name must be unique !" +msgstr "" + +#. module: base +#: view:res.config:0 +#: view:res.config.installer:0 +msgid "description" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_action_rule +#: model:ir.ui.menu,name:base.menu_base_action_rule_admin +msgid "Automated Actions" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_ro +msgid "Romania - Accounting" +msgstr "" + +#. module: base +#: view:partner.wizard.ean.check:0 +msgid "Want to check Ean ? " +msgstr "" + +#. module: base +#: help:ir.actions.server,mobile:0 +msgid "" +"Provides fields that be used to fetch the mobile number, e.g. you select the " +"invoice, then `object.invoice_address_id.mobile` is the field which gives " +"the correct mobile number" +msgstr "" + +#. module: base +#: view:ir.mail_server:0 +msgid "Security and Authentication" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "" +"OpenERP translations (core, modules, clients) are managed through " +"Launchpad.net, our open source project management facility. We use their " +"online interface to synchronize all translations efforts." +msgstr "" + +#. module: base +#: help:ir.actions.todo,type:0 +msgid "" +"Manual: Launched manually.\n" +"Automatic: Runs whenever the system is reconfigured.\n" +"Launch Manually Once: after hacing been launched manually, it sets " +"automatically to Done." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Swedish / svenska" +msgstr "" + +#. module: base +#: model:res.country,name:base.rs +msgid "Serbia" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Wizard View" +msgstr "" + +#. module: base +#: model:res.country,name:base.kh +msgid "Cambodia, Kingdom of" +msgstr "" + +#. module: base +#: field:base.language.import,overwrite:0 +#: field:base.language.install,overwrite:0 +msgid "Overwrite Existing Terms" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_language_import +msgid "Language Import" +msgstr "" + +#. module: base +#: help:ir.cron,interval_number:0 +msgid "Repeat every x." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Albanian / Shqip" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_crm_config_opportunity +msgid "Opportunities" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_language_export +msgid "base.language.export" +msgstr "" + +#. module: base +#: help:ir.actions.server,write_id:0 +msgid "" +"Provide the field name that the record id refers to for the write operation. " +"If it is empty it will refer to the active id of the object." +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,report_type:0 +msgid "Report Type, e.g. pdf, html, raw, sxw, odt, html2html, mako2html, ..." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_document_webdav +msgid "Shared Repositories (WebDAV)" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_import_google +msgid "" +"The module adds google contact in partner address and add google calendar " +"events details in Meeting" +msgstr "" + +#. module: base +#: view:res.users:0 +msgid "Email Preferences" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_audittrail +msgid "" +"\n" +"This module lets administrator track every user operation on all the objects " +"of the system.\n" +"=============================================================================" +"==============\n" +"\n" +"The administrator can subscribe to rules for read, write and\n" +"delete on objects and can check logs.\n" +" " +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_4 +msgid "Basic Partner" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "," +msgstr "" + +#. module: base +#: view:res.partner:0 +msgid "My Partners" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "XML Report" +msgstr "" + +#. module: base +#: model:res.country,name:base.es +msgid "Spain" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "Please be patient, as this operation may take a few seconds..." +msgstr "" + +#. module: base +#: help:ir.actions.act_window,domain:0 +msgid "" +"Optional domain filtering of the destination data, as a Python expression" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade +#: model:ir.model,name:base.model_base_module_upgrade +msgid "Module Upgrade" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (UY) / Español (UY)" +msgstr "" + +#. module: base +#: field:res.partner,mobile:0 +#: field:res.partner.address,mobile:0 +msgid "Mobile" +msgstr "" + +#. module: base +#: model:res.country,name:base.om +msgid "Oman" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_mrp +msgid "MRP" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "1cm 28cm 20cm 28cm" +msgstr "" + +#. module: base +#: model:res.country,name:base.nu +msgid "Niue" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_membership +msgid "Membership Management" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "Other OSI Approved Licence" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_menu_create +#: view:wizard.ir.model.menu.create:0 +msgid "Create Menu" +msgstr "" + +#. module: base +#: model:res.country,name:base.in +msgid "India" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_request_link-act +#: model:ir.ui.menu,name:base.menu_res_request_link_act +msgid "Request Reference Types" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_google_base_account +msgid "Google Users" +msgstr "" + +#. module: base +#: help:ir.server.object.lines,value:0 +msgid "" +"Expression containing a value specification. \n" +"When Formula type is selected, this field may be a Python expression that " +"can use the same values as for the condition field on the server action.\n" +"If Value type is selected, the value will be used directly without " +"evaluation." +msgstr "" + +#. module: base +#: model:res.country,name:base.ad +msgid "Andorra, Principality of" +msgstr "" + +#. module: base +#: field:res.partner.category,child_ids:0 +msgid "Child Categories" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_config_parameter +msgid "ir.config_parameter" +msgstr "" + +#. module: base +#: selection:base.language.export,format:0 +msgid "TGZ Archive" +msgstr "" + +#. module: base +#: view:res.groups:0 +msgid "" +"Users added to this group are automatically added in the following groups." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%B - Full month name." +msgstr "" + +#. module: base +#: field:ir.actions.todo,type:0 +#: view:ir.attachment:0 +#: field:ir.attachment,type:0 +#: field:ir.model,state:0 +#: field:ir.model.fields,state:0 +#: field:ir.property,type:0 +#: field:ir.server.object.lines,type:0 +#: field:ir.translation,type:0 +#: view:ir.ui.view:0 +#: view:ir.values:0 +#: field:ir.values,key:0 +#: view:res.partner:0 +#: view:res.partner.address:0 +msgid "Type" +msgstr "" + +#. module: base +#: field:ir.mail_server,smtp_user:0 +msgid "Username" +msgstr "" + +#. module: base +#: code:addons/orm.py:398 +#, python-format +msgid "" +"Language with code \"%s\" is not defined in your system !\n" +"Define it through the Administration menu." +msgstr "" + +#. module: base +#: model:res.country,name:base.gu +msgid "Guam (USA)" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:558 +#, python-format +msgid "Setting empty passwords is not allowed for security reasons!" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:192 +#, python-format +msgid "Connection test failed!" +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +#: selection:workflow.activity,kind:0 +msgid "Dummy" +msgstr "" + +#. module: base +#: constraint:ir.ui.view:0 +msgid "Invalid XML for View Architecture!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ky +msgid "Cayman Islands" +msgstr "" + +#. module: base +#: model:res.country,name:base.kr +msgid "South Korea" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_transition_form +#: model:ir.ui.menu,name:base.menu_workflow_transition +#: view:workflow.activity:0 +msgid "Transitions" +msgstr "" + +#. module: base +#: code:addons/orm.py:4615 +#, python-format +msgid "Record #%d of %s not found, cannot copy!" +msgstr "" + +#. module: base +#: field:ir.module.module,contributors:0 +msgid "Contributors" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project_planning +msgid "" +"Keep track of your planning\n" +"This module helps you to manage your plannings.\n" +"===============================================\n" +"\n" +"This module is based on the analytic accounting and is totally integrated " +"with\n" +"* the timesheets encoding\n" +"* the holidays management\n" +"* the project management\n" +"\n" +"So that, each department manager can know if someone in his team has still " +"unallocated time for a given planning (taking in consideration the validated " +"leaves) or if he still needs to encode tasks.\n" +"\n" +"At the end of the month, the planning manager can also check if the encoded " +"timesheets are respecting the planned time on each analytic account.\n" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Char" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Slovak / Slovenský jazyk" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (AR) / Español (AR)" +msgstr "" + +#. module: base +#: model:res.country,name:base.ug +msgid "Uganda" +msgstr "" + +#. module: base +#: field:ir.model.access,perm_unlink:0 +msgid "Delete Access" +msgstr "" + +#. module: base +#: model:res.country,name:base.ne +msgid "Niger" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Chinese (HK)" +msgstr "" + +#. module: base +#: model:res.country,name:base.ba +msgid "Bosnia-Herzegovina" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "" +"To improve or expand the official translations, you should use directly " +"Lauchpad's web interface (Rosetta). If you need to perform mass translation, " +"Launchpad also allows uploading full .po files at once" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (GT) / Español (GT)" +msgstr "" + +#. module: base +#: field:ir.mail_server,smtp_port:0 +msgid "SMTP Port" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_import_sugarcrm +msgid "SugarCRM Import" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "" +"%W - Week number of the year (Monday as the first day of the week) as a " +"decimal number [00,53]. All days in a new year preceding the first Monday " +"are considered to be in week 0." +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_language_install.py:55 +#, python-format +msgid "Language Pack" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_tests +msgid "Tests" +msgstr "" + +#. module: base +#: field:ir.ui.view_sc,res_id:0 +msgid "Resource Ref." +msgstr "" + +#. module: base +#: model:res.country,name:base.gs +msgid "S. Georgia & S. Sandwich Isls." +msgstr "" + +#. module: base +#: field:ir.actions.url,url:0 +msgid "Action URL" +msgstr "" + +#. module: base +#: field:base.module.import,module_name:0 +msgid "Module Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.mh +msgid "Marshall Islands" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:368 +#, python-format +msgid "Changing the model of a field is forbidden!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ht +msgid "Haiti" +msgstr "" + +#. module: base +#: view:ir.ui.view:0 +#: selection:ir.ui.view,type:0 +msgid "Search" +msgstr "" + +#. module: base +#: code:addons/osv.py:132 +#, python-format +msgid "" +"The operation cannot be completed, probably due to the following:\n" +"- deletion: you may be trying to delete a record while other records still " +"reference it\n" +"- creation/update: a mandatory field is not correctly set" +msgstr "" + +#. module: base +#: field:ir.module.category,parent_id:0 +msgid "Parent Application" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:222 +#, python-format +msgid "Operation Canceled" +msgstr "" + +#. module: base +#: help:base.language.export,lang:0 +msgid "To export a new language, do not select a language." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_document +#: model:ir.module.module,shortdesc:base.module_knowledge +msgid "Document Management System" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_crm_claim +msgid "Claims Management" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_purchase_root +msgid "Purchases" +msgstr "" + +#. module: base +#: model:res.country,name:base.md +msgid "Moldavia" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Features" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.bank_account_update +msgid "" +"Configure your company's bank accounts and select those that must appear on " +"the report footer. You can reorder bank accounts from the list view. If you " +"use the accounting application of OpenERP, journals and accounts will be " +"created automatically based on these data." +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: report:ir.module.reference.graph:0 +msgid "Version" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_sale_order_dates +msgid "" +"\n" +"Add additional date information to the sales order.\n" +"===================================================\n" +"\n" +"You can add the following additional dates to a sale order:\n" +" * Requested Date\n" +" * Commitment Date\n" +" * Effective Date\n" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_sequence +msgid "Entries Sequence Numbering" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_exports +msgid "ir.exports" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_update_translations.py:38 +#, python-format +msgid "No language with code \"%s\" exists" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_document +msgid "" +"\n" +"This is a complete document management system.\n" +"==============================================\n" +"\n" +" * User Authentication\n" +" * Document Indexation :- .pptx and .docx files are not supported in " +"Windows platform.\n" +" * Dashboard for Document that includes:\n" +" * New Files (list)\n" +" * Files by Resource Type (graph)\n" +" * Files by Partner (graph)\n" +" * Files Size by Month (graph)\n" +"\n" +"ATTENTION:\n" +" - When you install this module in a running company that have already " +"PDF files stored into the database,\n" +" you will lose them all.\n" +" - After installing this module PDF's are no longer stored into the " +"database,\n" +" but in the servers rootpad like /server/bin/filestore.\n" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%Y - Year with century." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_gantt +msgid "" +"\n" +" OpenERP Web gantt chart view.\n" +" " +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "-" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "" +"This wizard helps you register a publisher warranty contract in your OpenERP " +"system. After the contract has been registered, you will be able to send " +"issues directly to OpenERP." +msgstr "" + +#. module: base +#: view:wizard.ir.model.menu.create:0 +msgid "Create _Menu" +msgstr "" + +#. module: base +#: field:res.payterm,name:0 +msgid "Payment Term (short name)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_bank +#: view:res.bank:0 +#: field:res.partner.bank,bank:0 +msgid "Bank" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_exports_line +msgid "ir.exports.line" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_html_view +msgid "" +"\n" +"This is the test module which shows HTML tag support in normal XML form " +"view.\n" +"=============================================================================" +"\n" +"\n" +"Creates a sample form-view using HTML tags. It is visible only in OpenERP " +"Web.\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_purchase_management +msgid "" +"Helps you manage your purchase-related processes such as requests for " +"quotations, supplier invoices, etc..." +msgstr "" + +#. module: base +#: help:base.language.install,overwrite:0 +msgid "" +"If you check this box, your customized translations will be overwritten and " +"replaced by the official ones." +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_rml:0 +msgid "Main report file path" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_action_report_xml +#: field:ir.module.module,reports_by_module:0 +#: model:ir.ui.menu,name:base.menu_ir_action_report_xml +msgid "Reports" +msgstr "" + +#. module: base +#: help:ir.actions.act_window.view,multi:0 +#: help:ir.actions.report.xml,multi:0 +msgid "" +"If set to true, the action will not be displayed on the right toolbar of a " +"form view." +msgstr "" + +#. module: base +#: field:workflow,on_create:0 +msgid "On Create" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:681 +#, python-format +msgid "" +"'%s' contains too many dots. XML ids should not contain dots ! These are " +"used to refer to other modules data, as in module.reference_id" +msgstr "" + +#. module: base +#: field:partner.sms.send,user:0 +#: field:res.users,login:0 +msgid "Login" +msgstr "" + +#. module: base +#: view:base.update.translations:0 +#: model:ir.actions.act_window,name:base.action_wizard_update_translations +#: model:ir.ui.menu,name:base.menu_wizard_update_translations +msgid "Synchronize Terms" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "" +"Access all the fields related to the current object using expressions, i.e. " +"object.partner_id.name " +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_event +msgid "" +"\n" +"Organization and management of Events.\n" +"======================================\n" +"\n" +"This module allows you\n" +" * to manage your events and their registrations\n" +" * to use emails to automatically confirm and send acknowledgements for " +"any registration to an event\n" +" * ...\n" +"\n" +"Note that:\n" +" - You can define new types of events in\n" +" Association / Configuration / Types of Events\n" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_tools +msgid "Tools" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Float" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_warehouse_management +#: model:ir.module.module,shortdesc:base.module_stock +msgid "Warehouse Management" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_request_link +msgid "res.request.link" +msgstr "" + +#. module: base +#: field:ir.actions.wizard,name:0 +msgid "Wizard Info" +msgstr "" + +#. module: base +#: view:base.language.export:0 +#: model:ir.actions.act_window,name:base.action_wizard_lang_export +#: model:ir.ui.menu,name:base.menu_wizard_lang_export +msgid "Export Translation" +msgstr "" + +#. module: base +#: help:res.log,secondary:0 +msgid "" +"Do not display this log if it belongs to the same object the user is working " +"on" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_lu +msgid "Luxembourg - Accounting" +msgstr "" + +#. module: base +#: model:res.country,name:base.tp +msgid "East Timor" +msgstr "" + +#. module: base +#: model:res.company,follow_up_msg:base.main_company +msgid "" +"Date : %(date)s\n" +"\n" +"Dear %(partner_name)s,\n" +"\n" +"Please find in attachment a reminder of all your unpaid invoices, for a " +"total amount due of:\n" +"\n" +"%(followup_amount).2f %(company_currency)s\n" +"\n" +"Thanks,\n" +"--\n" +"%(user_signature)s\n" +"%(company_name)s" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_share +msgid "" +"\n" +"This module adds generic sharing tools to your current OpenERP database.\n" +"========================================================================\n" +"\n" +"It specifically adds a 'share' button that is available in the Web client " +"to\n" +"share any kind of OpenERP data with colleagues, customers, friends, etc.\n" +"\n" +"The system will work by creating new users and groups on the fly, and by\n" +"combining the appropriate access rights and ir.rules to ensure that the\n" +"shared users only have access to the data that has been shared with them.\n" +"\n" +"This is extremely useful for collaborative work, knowledge sharing,\n" +"synchronization with other companies, etc.\n" +"\n" +" " +msgstr "" + +#. module: base +#: field:res.currency,accuracy:0 +msgid "Computational Accuracy" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_lunch +msgid "" +"\n" +" The base module to manage lunch\n" +"\n" +" keep track for the Lunch Order ,Cash Moves ,CashBox ,Product.\n" +" Apply Different Category for the product.\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.kg +msgid "Kyrgyz Republic (Kyrgyzstan)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_wizard_ir_model_menu_create_line +msgid "wizard.ir.model.menu.create.line" +msgstr "" + +#. module: base +#: field:ir.attachment,res_id:0 +msgid "Attached ID" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_vat +msgid "" +"\n" +"VAT validation for Partners' VAT numbers\n" +"========================================\n" +"\n" +"After installing this module, values entered in the VAT field of Partners " +"will\n" +"be validated for all supported countries. The country is inferred from the\n" +"2-letter country code that prefixes the VAT number, e.g. ``BE0477472701``\n" +"will be validated using the Belgian rules.\n" +"\n" +"There are two different levels of VAT number validation:\n" +"\n" +" * By default, a simple off-line check is performed using the known " +"validation\n" +" rules for the country, usually a simple check digit. This is quick and \n" +" always available, but allows numbers that are perhaps not truly " +"allocated,\n" +" or not valid anymore.\n" +" * When the \"VAT VIES Check\" option is enabled (in the configuration of " +"the user's\n" +" Company), VAT numbers will be instead submitted to the online EU VIES\n" +" database, which will truly verify that the number is valid and currently\n" +" allocated to a EU company. This is a little bit slower than the simple\n" +" off-line check, requires an Internet connection, and may not be " +"available\n" +" all the time. If the service is not available or does not support the\n" +" requested country (e.g. for non-EU countries), a simple check will be " +"performed\n" +" instead.\n" +"\n" +"Supported countries currently include EU countries, and a few non-EU " +"countries\n" +"such as Chile, Colombia, Mexico, Norway or Russia. For unsupported " +"countries,\n" +"only the country code will be validated.\n" +"\n" +" " +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Day: %(day)s" +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_point_of_sale +msgid "" +"Helps you get the most out of your points of sales with fast sale encoding, " +"simplified payment mode encoding, automatic picking lists generation and " +"more." +msgstr "" + +#. module: base +#: model:res.country,name:base.mv +msgid "Maldives" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_idea +msgid "" +"\n" +"This module allows your user to easily and efficiently participate in " +"enterprise innovation.\n" +"=============================================================================" +"===============\n" +"\n" +"It allows everybody to express ideas about different subjects.\n" +"Then, other users can comment on these ideas and vote for particular ideas.\n" +"Each idea has a score based on the different votes.\n" +"The managers can obtain an easy view of best ideas from all the users.\n" +"Once installed, check the menu 'Ideas' in the 'Tools' main menu." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_rule +msgid "ir.rule" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Days" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_rpc +msgid "OpenERP Web web" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_html_view +msgid "Html View" +msgstr "" + +#. module: base +#: field:res.currency,position:0 +msgid "Symbol position" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_process +msgid "Enterprise Process" +msgstr "" + +#. module: base +#: help:ir.cron,function:0 +msgid "Name of the method to be called when this job is processed." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr_evaluation +msgid "Employee Appraisals" +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Write Object" +msgstr "" + +#. module: base +#: code:addons/base/res/res_company.py:66 +#: code:addons/base/res/res_partner.py:175 +#, python-format +msgid " (copy)" +msgstr "" + +#. module: base +#: field:res.company,rml_footer1:0 +msgid "General Information Footer" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "7. %H:%M:%S ==> 18:25:20" +msgstr "" + +#. module: base +#: view:res.partner:0 +#: view:res.partner.category:0 +#: field:res.partner.category,partner_ids:0 +msgid "Partners" +msgstr "" + +#. module: base +#: field:res.partner.category,parent_left:0 +msgid "Left parent" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_project_mrp +msgid "Create Tasks on SO" +msgstr "" + +#. module: base +#: field:ir.attachment,res_model:0 +msgid "Attached Model" +msgstr "" + +#. module: base +#: field:res.partner.bank,footer:0 +msgid "Display on Reports" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_cn +msgid "" +"\n" +" 添加中文省份数据\n" +" 科目类型\\会计科目表模板\\增值税\\辅助核算类别\\管理会计凭证簿\\财务会计凭证簿\n" +" ============================================================\n" +" " +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_model_access +msgid "ir.model.access" +msgstr "" + +#. module: base +#: field:ir.cron,priority:0 +#: field:ir.mail_server,sequence:0 +#: field:res.request,priority:0 +#: field:res.request.link,priority:0 +msgid "Priority" +msgstr "" + +#. module: base +#: field:workflow.transition,act_from:0 +msgid "Source Activity" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Legend (for prefix, suffix)" +msgstr "" + +#. module: base +#: selection:ir.server.object.lines,type:0 +msgid "Formula" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:396 +#, python-format +msgid "Can not remove root user!" +msgstr "" + +#. module: base +#: model:res.country,name:base.mw +msgid "Malawi" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_ec +msgid "" +"\n" +"This is the base module to manage the accounting chart for Ecuador in " +"OpenERP.\n" +"=============================================================================" +"=\n" +"\n" +"Accounting chart and localization for Ecuador.\n" +" " +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_filters.py:38 +#: code:addons/base/res/res_users.py:80 +#: code:addons/base/res/res_users.py:420 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_chart +msgid "Template of Charts of Accounts" +msgstr "" + +#. module: base +#: field:res.partner.address,type:0 +msgid "Address Type" +msgstr "" + +#. module: base +#: view:ir.ui.menu:0 +msgid "Full Path" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_br +msgid "" +"\n" +"Base module for the Brazilian localization\n" +"==========================================\n" +"\n" +"This module consists in:\n" +"\n" +" - Generic Brazilian chart of accounts\n" +" - Brazilian taxes such as:\n" +"\n" +" - IPI\n" +" - ICMS\n" +" - PIS\n" +" - COFINS\n" +" - ISS\n" +" - IR\n" +" - IRPJ\n" +" - CSLL\n" +"\n" +" - Tax Situation Code (CST) required for the electronic fiscal invoicing " +"(NFe)\n" +"\n" +"The field tax_discount has also been added in the account.tax.template and " +"account.tax objects to allow the proper computation of some Brazilian VATs " +"such as ICMS. The chart of account creation wizard has been extended to " +"propagate those new data properly.\n" +"\n" +"It's important to note however that this module lack many implementations to " +"use OpenERP properly in Brazil. Those implementations (such as the " +"electronic fiscal Invoicing which is already operational) are brought by " +"more than 15 additional modules of the Brazilian Launchpad localization " +"project https://launchpad.net/openerp.pt-br-localiz and their dependencies " +"in the extra addons branch. Those modules aim at not breaking with the " +"remarkable OpenERP modularity, this is why they are numerous but small. One " +"of the reasons for maintaining those modules apart is that Brazilian " +"Localization leaders need commit rights agility to complete the localization " +"as companies fund the remaining legal requirements (such as soon fiscal " +"ledgers, accounting SPED, fiscal SPED and PAF ECF that are still missing as " +"September 2011). Those modules are also strictly licensed under AGPL V3 and " +"today don't come with any additional paid permission for online use of " +"'private modules'." +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "References" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "" +"%U - Week number of the year (Sunday as the first day of the week) as a " +"decimal number [00,53]. All days in a new year preceding the first Sunday " +"are considered to be in week 0." +msgstr "" + +#. module: base +#: view:ir.ui.view:0 +msgid "Advanced" +msgstr "" + +#. module: base +#: model:res.country,name:base.fi +msgid "Finland" +msgstr "" + +#. module: base +#: code:addons/base/res/res_company.py:156 +#, python-format +msgid "Website: " +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_administration +msgid "Settings" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window,view_type:0 +#: selection:ir.actions.act_window.view,view_mode:0 +#: view:ir.ui.view:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Tree" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_analytic_multicurrency +msgid "Multi-Currency in Analytic" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "https://help.launchpad.net/Translations" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,view_mode:0 +msgid "View Mode" +msgstr "" + +#. module: base +#: help:res.partner.bank,footer:0 +msgid "" +"Display this bank account on the footer of printed documents like invoices " +"and sales orders." +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "" +"When using CSV format, please also check that the first line of your file is " +"one of the following:" +msgstr "" + +#. module: base +#: view:res.log:0 +msgid "Logs" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish / Español" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Korean (KP) / 한국어 (KP)" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "" +"This wizard will scan all module repositories on the server side to detect " +"newly added modules as well as any change to existing modules." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_sale_journal +msgid "" +"\n" +"The sales journal modules allows you to categorise your sales and deliveries " +"(picking lists) between different journals.\n" +"=============================================================================" +"===========================================\n" +"\n" +"This module is very helpful for bigger companies that\n" +"works by departments.\n" +"\n" +"You can use journal for different purposes, some examples:\n" +" * isolate sales of different departments\n" +" * journals for deliveries by truck or by UPS\n" +"\n" +"Journals have a responsible and evolves between different status:\n" +" * draft, open, cancel, done.\n" +"\n" +"Batch operations can be processed on the different journals to\n" +"confirm all sales at once, to validate or invoice packing, ...\n" +"\n" +"It also supports batch invoicing methods that can be configured by partners " +"and sales orders, examples:\n" +" * daily invoicing,\n" +" * monthly invoicing, ...\n" +"\n" +"Some statistics by journals are provided.\n" +" " +msgstr "" + +#. module: base +#: field:res.company,logo:0 +msgid "Logo" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_cr +msgid "Costa Rica - Accounting" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Uninstall (beta)" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr_expense +msgid "" +"\n" +"This module aims to manage employee's expenses.\n" +"===============================================\n" +"\n" +"The whole workflow is implemented:\n" +" * Draft expense\n" +" * Confirmation of the sheet by the employee\n" +" * Validation by his manager\n" +" * Validation by the accountant and invoice creation\n" +" * Payment of the invoice to the employee\n" +"\n" +"This module also uses the analytic accounting and is compatible with\n" +"the invoice on timesheet module so that you will be able to automatically\n" +"re-invoice your customer's expenses if your work by project.\n" +" " +msgstr "" + +#. module: base +#: field:ir.values,action_id:0 +msgid "Action (change only)" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_subscription +msgid "Recurring Documents" +msgstr "" + +#. module: base +#: model:res.country,name:base.bs +msgid "Bahamas" +msgstr "" + +#. module: base +#: selection:res.request,state:0 +msgid "active" +msgstr "" + +#. module: base +#: code:addons/base/res/res_partner.py:273 +#, python-format +msgid "" +"Couldn't generate the next id because some partners have an alphabetic id !" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Attachment" +msgstr "" + +#. module: base +#: model:res.country,name:base.ie +msgid "Ireland" +msgstr "" + +#. module: base +#: field:base.module.update,update:0 +msgid "Number of modules updated" +msgstr "" + +#. module: base +#: field:ir.cron,function:0 +msgid "Method" +msgstr "" + +#. module: base +#: view:res.partner.event:0 +msgid "General Description" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +msgid "Workflow Activity" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_ui_view +msgid "" +"Views allows you to personalize each view of OpenERP. You can add new " +"fields, move fields, rename them or delete the ones that you do not need." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_setup +msgid "Initial Setup Tools" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,groups_id:0 +#: model:ir.actions.act_window,name:base.action_res_groups +#: view:ir.actions.report.xml:0 +#: field:ir.actions.report.xml,groups_id:0 +#: view:ir.actions.todo:0 +#: field:ir.actions.todo,groups_id:0 +#: field:ir.actions.wizard,groups_id:0 +#: view:ir.model:0 +#: field:ir.model.fields,groups:0 +#: field:ir.rule,groups:0 +#: view:ir.ui.menu:0 +#: field:ir.ui.menu,groups_id:0 +#: model:ir.ui.menu,name:base.menu_action_res_groups +#: view:res.groups:0 +#: field:res.users,groups_id:0 +msgid "Groups" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (CL) / Español (CL)" +msgstr "" + +#. module: base +#: model:res.country,name:base.bz +msgid "Belize" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,header:0 +msgid "Add or not the corporate RML header" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr_recruitment +msgid "" +"\n" +"Manages job positions and the recruitment process.\n" +"==================================================\n" +"\n" +"It's integrated with the survey module to allow you to define interview for " +"different jobs.\n" +"\n" +"This module is integrated with the mail gateway to automatically tracks " +"email\n" +"sent to jobs@YOURCOMPANY.com. It's also integrated with the document " +"management\n" +"system to store and search in your CV base.\n" +" " +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_widget_wizard +msgid "Homepage Widgets Management" +msgstr "" + +#. module: base +#: field:res.company,rml_header1:0 +msgid "Report Header / Company Slogan" +msgstr "" + +#. module: base +#: model:res.country,name:base.pl +msgid "Poland" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,view_mode:0 +msgid "" +"Comma-separated list of allowed view modes, such as 'form', 'tree', " +"'calendar', etc. (Default: tree,form)" +msgstr "" + +#. module: base +#: code:addons/orm.py:3615 +#, python-format +msgid "A document was modified since you last viewed it (%s:%d)" +msgstr "" + +#. module: base +#: view:workflow:0 +msgid "Workflow Editor" +msgstr "" + +#. module: base +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "To be removed" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_sequence +msgid "ir.sequence" +msgstr "" + +#. module: base +#: help:ir.actions.server,expression:0 +msgid "" +"Enter the field/expression that will return the list. E.g. select the sale " +"order in Object, and you can have loop on the sales order line. Expression = " +"`object.order_line`." +msgstr "" + +#. module: base +#: field:ir.mail_server,smtp_debug:0 +msgid "Debugging" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_crm_helpdesk +msgid "" +"\n" +"Helpdesk Management.\n" +"====================\n" +"\n" +"Like records and processing of claims, Helpdesk and Support are good tools\n" +"to trace your interventions. This menu is more adapted to oral " +"communication,\n" +"which is not necessarily related to a claim. Select a customer, add notes\n" +"and categorize your interventions with a channel and a priority level.\n" +" " +msgstr "" + +#. module: base +#: sql_constraint:ir.ui.view_sc:0 +msgid "Shortcut for this menu already exists!" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_resource +msgid "" +"\n" +"Module for resource management.\n" +"===============================\n" +"\n" +"A resource represent something that can be scheduled\n" +"(a developer on a task or a work center on manufacturing orders).\n" +"This module manages a resource calendar associated to every resource.\n" +"It also manages the leaves of every resource.\n" +"\n" +" " +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "Groups (no group = global)" +msgstr "" + +#. module: base +#: selection:res.users,view:0 +msgid "Simplified" +msgstr "" + +#. module: base +#: model:res.country,name:base.st +msgid "Saint Tome (Sao Tome) and Principe" +msgstr "" + +#. module: base +#: selection:res.partner.address,type:0 +msgid "Invoice" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Portugese (BR) / Português (BR)" +msgstr "" + +#. module: base +#: model:res.country,name:base.bb +msgid "Barbados" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_synchro +msgid "" +"\n" +"Synchronization with all objects.\n" +"=================================\n" +"\n" +"Configure servers and trigger synchronization with its database objects.\n" +msgstr "" + +#. module: base +#: model:res.country,name:base.mg +msgid "Madagascar" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:116 +#, python-format +msgid "" +"The Object name must start with x_ and not contain any special character !" +msgstr "" + +#. module: base +#: field:ir.actions.configuration.wizard,note:0 +msgid "Next Wizard" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_menu_admin +#: view:ir.ui.menu:0 +#: field:ir.ui.menu,name:0 +msgid "Menu" +msgstr "" + +#. module: base +#: field:res.currency,rate:0 +msgid "Current Rate" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_idea +msgid "Ideas" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_sale_crm +msgid "Opportunity to Quotation" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_sale_analytic_plans +msgid "" +"\n" +"The base module to manage analytic distribution and sales orders.\n" +"=================================================================\n" +"\n" +"Using this module you will be able to link analytic accounts to sales " +"orders.\n" +" " +msgstr "" + +#. module: base +#: field:ir.actions.url,target:0 +msgid "Action Target" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_calendar +msgid "Calendar Layer" +msgstr "" + +#. module: base +#: model:ir.actions.report.xml,name:base.report_ir_model_overview +msgid "Model Overview" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_product_margin +msgid "Margins by Products" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_invoiced +msgid "Invoicing" +msgstr "" + +#. module: base +#: field:ir.ui.view_sc,name:0 +msgid "Shortcut Name" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,limit:0 +msgid "Default limit for the list view" +msgstr "" + +#. module: base +#: model:res.country,name:base.pg +msgid "Papua New Guinea" +msgstr "" + +#. module: base +#: model:res.country,name:base.zw +msgid "Zimbabwe" +msgstr "" + +#. module: base +#: model:res.country,name:base.io +msgid "British Indian Ocean Territory" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_translation_export +msgid "Import / Export" +msgstr "" + +#. module: base +#: model:ir.actions.todo.category,name:base.category_tools_customization_config +msgid "Tools / Customization" +msgstr "" + +#. module: base +#: field:ir.model.data,res_id:0 +#: field:ir.values,res_id:0 +msgid "Record ID" +msgstr "" + +#. module: base +#: field:ir.actions.server,email:0 +msgid "Email Address" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "French (BE) / Français (BE)" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +#: field:workflow.activity,action_id:0 +msgid "Server Action" +msgstr "" + +#. module: base +#: help:ir.actions.client,params:0 +msgid "Arguments sent to the client along withthe view tag" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project_gtd +msgid "" +"\n" +"This module implements all concepts defined by the Getting Things Done " +"methodology.\n" +"=============================================================================" +"======\n" +"\n" +"This module implements a simple personnal Todo list based on tasks. It adds " +"in\n" +"the project application an editable list of tasks simplified to the minimum\n" +"required fields.\n" +"\n" +"The todo list is based on the GTD methodology. This world-wide used " +"methodology\n" +"is used for personal time management improvement.\n" +"\n" +"Getting Things Done (commonly abbreviated as GTD) is an action management\n" +"method created by David Allen, and described in a book of the same name.\n" +"\n" +"GTD rests on the principle that a person needs to move tasks out of the mind " +"by\n" +"recording them externally. That way, the mind is freed from the job of\n" +"remembering everything that needs to be done, and can concentrate on " +"actually\n" +"performing those tasks.\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.tt +msgid "Trinidad and Tobago" +msgstr "" + +#. module: base +#: model:res.country,name:base.lv +msgid "Latvia" +msgstr "" + +#. module: base +#: view:partner.sms.send:0 +msgid "SMS - Gateway: clickatell" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Field Mappings" +msgstr "" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:125 +#: code:addons/base/publisher_warranty/publisher_warranty.py:163 +#, python-format +msgid "Error during communication with the publisher warranty server." +msgstr "" + +#. module: base +#: model:res.groups,name:base.group_sale_manager +#: model:res.groups,name:base.group_tool_manager +msgid "Manager" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_custom +msgid "Customization" +msgstr "" + +#. module: base +#: model:res.country,name:base.py +msgid "Paraguay" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_act_window_close +msgid "ir.actions.act_window_close" +msgstr "" + +#. module: base +#: field:ir.server.object.lines,col1:0 +msgid "Destination" +msgstr "" + +#. module: base +#: model:res.country,name:base.lt +msgid "Lithuania" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_partner_clear_ids +#: model:ir.model,name:base.model_partner_clear_ids +#: view:partner.clear.ids:0 +msgid "Clear IDs" +msgstr "" + +#. module: base +#: view:res.groups:0 +msgid "Inherited" +msgstr "" + +#. module: base +#: field:ir.model.fields,serialization_field_id:0 +msgid "Serialization Field" +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_report_designer +msgid "" +"Lets you install various tools to simplify and enhance OpenERP's report " +"creation." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%y - Year without century [00,99]." +msgstr "" + +#. module: base +#: code:addons/base/res/res_company.py:155 +#, python-format +msgid "Fax: " +msgstr "" + +#. module: base +#: model:res.country,name:base.si +msgid "Slovenia" +msgstr "" + +#. module: base +#: help:res.currency,name:0 +msgid "Currency Code (ISO 4217)" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_log_act_window +#: model:ir.ui.menu,name:base.menu_res_log_act_window +msgid "Client Logs" +msgstr "" + +#. module: base +#: code:addons/orm.py:1883 +#: code:addons/orm.py:1894 +#, python-format +msgid "Invalid Object Architecture!" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:311 +#: code:addons/base/ir/ir_model.py:313 +#: code:addons/base/ir/ir_model.py:343 +#: code:addons/base/ir/ir_model.py:357 +#: code:addons/base/ir/ir_model.py:359 +#: code:addons/base/ir/ir_model.py:361 +#: code:addons/base/ir/ir_model.py:368 +#: code:addons/base/ir/ir_model.py:371 +#: code:addons/base/module/wizard/base_update_translations.py:38 +#, python-format +msgid "Error!" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_fr_rib +msgid "French RIB Bank Details" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%p - Equivalent of either AM or PM." +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Iteration Actions" +msgstr "" + +#. module: base +#: help:multi_company.default,company_id:0 +msgid "Company where the user is connected" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,date_stop:0 +msgid "Ending Date" +msgstr "" + +#. module: base +#: model:res.country,name:base.nz +msgid "New Zealand" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_pad_project +msgid "" +"\n" +"This module adds a PAD in all project kanban views\n" +"==================================================\n" +" " +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_country +msgid "" +"Display and manage the list of all countries that can be assigned to your " +"partner records. You can create or delete countries to make sure the ones " +"you are working on will be maintained." +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_7 +msgid "Openstuff.net" +msgstr "" + +#. module: base +#: model:res.country,name:base.nf +msgid "Norfolk Island" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Korean (KR) / 한국어 (KR)" +msgstr "" + +#. module: base +#: help:ir.model.fields,model:0 +msgid "The technical name of the model this field belongs to" +msgstr "" + +#. module: base +#: field:ir.actions.server,action_id:0 +#: selection:ir.actions.server,state:0 +msgid "Client Action" +msgstr "" + +#. module: base +#: model:res.country,name:base.bd +msgid "Bangladesh" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_project_retro_planning +msgid "Project Retro-planning" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_stock_planning +msgid "Master Procurement Schedule" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_module_category +#: field:ir.module.module,application:0 +#: field:res.groups,category_id:0 +msgid "Application" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Valid" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_decimal_precision +msgid "" +"\n" +"Configure the price accuracy you need for different kinds of usage: " +"accounting, sales, purchases, etc.\n" +"=============================================================================" +"=========================\n" +"\n" +"The decimal precision is configured per company.\n" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_pl +msgid "" +"\n" +"This is the module to manage the accounting chart and taxes for Poland in " +"OpenERP.\n" +"=============================================================================" +"=====\n" +"\n" +"To jest moduł do tworzenia wzorcowego planu kont i podstawowych ustawień do " +"podatków\n" +"VAT 0%, 7% i 22%. Moduł ustawia też konta do kupna i sprzedaży towarów " +"zakładając,\n" +"że wszystkie towary są w obrocie hurtowym.\n" +" " +msgstr "" + +#. module: base +#: field:ir.actions.client,params_store:0 +msgid "Params storage" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:409 +#, python-format +msgid "Can not upgrade module '%s'. It is not installed." +msgstr "" + +#. module: base +#: model:res.country,name:base.cu +msgid "Cuba" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_crm_profiling +msgid "" +"\n" +"This module allows users to perform segmentation within partners.\n" +"=================================================================\n" +"\n" +"It uses the profiles criteria from the earlier segmentation module and " +"improve it. Thanks to the new concept of questionnaire. You can now regroup " +"questions into a questionnaire and directly use it on a partner.\n" +"\n" +"It also has been merged with the earlier CRM & SRM segmentation tool because " +"they were overlapping.\n" +"\n" +" * Note: this module is not compatible with the module segmentation, " +"since it's the same which has been renamed.\n" +" " +msgstr "" + +#. module: base +#: code:addons/report_sxw.py:434 +#, python-format +msgid "Unknown report type: %s" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:282 +#, python-format +msgid "For selection fields, the Selection Options must be given!" +msgstr "" + +#. module: base +#: model:res.widget,title:base.facebook_widget +msgid "Facebook" +msgstr "" + +#. module: base +#: model:res.country,name:base.am +msgid "Armenia" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_property_form +#: model:ir.ui.menu,name:base.menu_ir_property_form_all +msgid "Configuration Parameters" +msgstr "" + +#. module: base +#: constraint:ir.cron:0 +msgid "Invalid arguments" +msgstr "" + +#. module: base +#: model:res.country,name:base.se +msgid "Sweden" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window.view,view_mode:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Gantt" +msgstr "" + +#. module: base +#: view:ir.property:0 +msgid "Property" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_bank_type +#: field:res.partner.bank,state:0 +#: view:res.partner.bank.type:0 +msgid "Bank Account Type" +msgstr "" + +#. module: base +#: field:base.language.export,config_logo:0 +#: field:base.language.import,config_logo:0 +#: field:base.language.install,config_logo:0 +#: field:base.module.import,config_logo:0 +#: field:base.module.update,config_logo:0 +#: field:base.update.translations,config_logo:0 +#: field:ir.actions.configuration.wizard,config_logo:0 +#: field:ir.wizard.screen,config_logo:0 +#: field:publisher_warranty.contract.wizard,config_logo:0 +#: field:res.config,config_logo:0 +#: field:res.config.installer,config_logo:0 +msgid "Image" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Iteration Action Configuration" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Canceled" +msgstr "" + +#. module: base +#: model:res.country,name:base.at +msgid "Austria" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Cancel Install" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_be_invoice_bba +msgid "" +"\n" +" \n" +"Belgian localisation for in- and outgoing invoices (prereq to " +"account_coda):\n" +" - Rename 'reference' field labels to 'Communication'\n" +" - Add support for Belgian Structured Communication\n" +"\n" +"A Structured Communication can be generated automatically on outgoing " +"invoices according to the following algorithms:\n" +" 1) Random : +++RRR/RRRR/RRRDD+++\n" +" R..R = Random Digits, DD = Check Digits\n" +" 2) Date : +++DOY/YEAR/SSSDD+++\n" +" DOY = Day of the Year, SSS = Sequence Number, DD = Check Digits)\n" +" 3) Customer Reference +++RRR/RRRR/SSSDDD+++\n" +" R..R = Customer Reference without non-numeric characters, SSS = " +"Sequence Number, DD = Check Digits) \n" +" \n" +"The preferred type of Structured Communication and associated Algorithm can " +"be specified on the Partner records. \n" +"A 'random' Structured Communication will generated if no algorithm is " +"specified on the Partner record. \n" +"\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_wiki_quality_manual +msgid "Wiki: Quality Manual" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window.view,view_mode:0 +#: model:ir.ui.menu,name:base.menu_calendar_configuration +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Calendar" +msgstr "" + +#. module: base +#: field:res.partner.address,partner_id:0 +msgid "Partner Name" +msgstr "" + +#. module: base +#: field:workflow.activity,signal_send:0 +msgid "Signal (subflow.*)" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_17 +msgid "HR sector" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_dashboard_admin +msgid "Administration Dashboard" +msgstr "" + +#. module: base +#: code:addons/orm.py:4408 +#, python-format +msgid "" +"Invalid \"order\" specified. A valid \"order\" specification is a comma-" +"separated list of valid field names (optionally followed by asc/desc for the " +"direction)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_module_module_dependency +msgid "Module dependency" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract.wizard,state:0 +msgid "Draft" +msgstr "" + +#. module: base +#: selection:res.users,view:0 +msgid "Extended" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_title_contact +msgid "" +"Manage the contact titles you want to have available in your system and the " +"way you want to print them in letters and other documents. Some example: " +"Mr., Mrs. " +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: view:res.groups:0 +#: field:res.groups,model_access:0 +msgid "Access Controls" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:237 +#, python-format +msgid "" +"The Selection Options expression is not a valid Pythonic expression.Please " +"provide an expression in the [('key','Label'), ...] format." +msgstr "" + +#. module: base +#: model:res.groups,name:base.group_survey_user +msgid "Survey / User" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: field:ir.module.module,dependencies_id:0 +msgid "Dependencies" +msgstr "" + +#. module: base +#: field:multi_company.default,company_id:0 +msgid "Main Company" +msgstr "" + +#. module: base +#: field:ir.ui.menu,web_icon_hover:0 +msgid "Web Icon File (hover)" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_diagram +msgid "Openerp web Diagram view" +msgstr "" + +#. module: base +#: model:res.groups,name:base.group_hr_user +msgid "HR Officer" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr_contract +msgid "Employee Contracts" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_wiki_faq +msgid "" +"\n" +"This module provides a Wiki FAQ Template.\n" +"=========================================\n" +"\n" +"It provides demo data, thereby creating a Wiki Group and a Wiki Page\n" +"for Wiki FAQ.\n" +" " +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "" +"If you use a formula type, use a python expression using the variable " +"'object'." +msgstr "" + +#. module: base +#: constraint:res.company:0 +msgid "Error! You can not create recursive companies." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_users +#: field:ir.default,uid:0 +#: model:ir.ui.menu,name:base.menu_action_res_users +#: model:ir.ui.menu,name:base.menu_users +#: view:res.groups:0 +#: field:res.groups,users:0 +#: view:res.users:0 +msgid "Users" +msgstr "" + +#. module: base +#: field:res.partner.address,birthdate:0 +msgid "Birthdate" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_title_contact +#: model:ir.ui.menu,name:base.menu_partner_title_contact +msgid "Contact Titles" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_product_manufacturer +msgid "Products Manufacturers" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:217 +#, python-format +msgid "SMTP-over-SSL mode unavailable" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_survey +msgid "Survey" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "" +"Please double-check that the file encoding is set to UTF-8 (sometimes called " +"Unicode) when the translator exports it." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (DO) / Español (DO)" +msgstr "" + +#. module: base +#: model:res.country,name:base.na +msgid "Namibia" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_activity +msgid "workflow.activity" +msgstr "" + +#. module: base +#: help:ir.ui.view_sc,res_id:0 +msgid "" +"Reference of the target resource, whose model/table depends on the 'Resource " +"Name' field." +msgstr "" + +#. module: base +#: field:ir.model.fields,select_level:0 +msgid "Searchable" +msgstr "" + +#. module: base +#: model:res.country,name:base.uy +msgid "Uruguay" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_fetchmail_crm +msgid "eMail Gateway for Leads" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Finnish / Suomi" +msgstr "" + +#. module: base +#: field:ir.rule,perm_write:0 +msgid "Apply For Write" +msgstr "" + +#. module: base +#: field:ir.sequence,prefix:0 +msgid "Prefix" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "German / Deutsch" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Fields Mapping" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_dashboard +msgid "web Dashboard" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_sale +msgid "" +"\n" +"The base module to manage quotations and sales orders.\n" +"======================================================\n" +"\n" +"Workflow with validation steps:\n" +"-------------------------------\n" +" * Quotation -> Sales order -> Invoice\n" +"\n" +"Invoicing methods:\n" +"------------------\n" +" * Invoice on order (before or after shipping)\n" +" * Invoice on delivery\n" +" * Invoice on timesheets\n" +" * Advance invoice\n" +"\n" +"Partners preferences:\n" +"---------------------\n" +" * shipping\n" +" * invoicing\n" +" * incoterm\n" +"\n" +"Products stocks and prices\n" +"--------------------------\n" +"\n" +"Delivery methods:\n" +"-----------------\n" +" * all at once\n" +" * multi-parcel\n" +" * delivery costs\n" +"\n" +"Dashboard for Sales Manager that includes:\n" +"------------------------------------------\n" +" * Quotations\n" +" * Sales by Month\n" +" * Graph of Sales by Salesman in last 90 days\n" +" * Graph of Sales per Customer in last 90 days\n" +" * Graph of Sales by Product's Category in last 90 days\n" +" " +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Portugese / Português" +msgstr "" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_sir +msgid "Sir" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_ca +msgid "" +"\n" +"This is the module to manage the English and French - Canadian accounting " +"chart in OpenERP.\n" +"=============================================================================" +"==============\n" +"\n" +"Canadian accounting charts and localizations.\n" +" " +msgstr "" + +#. module: base +#: view:base.module.import:0 +msgid "Select module package to import (.zip file):" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "French / Français" +msgstr "" + +#. module: base +#: model:res.country,name:base.mt +msgid "Malta" +msgstr "" + +#. module: base +#: field:ir.actions.server,fields_lines:0 +msgid "Field Mappings." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_lu +msgid "" +"\n" +"This is the base module to manage the accounting chart for Luxembourg.\n" +"======================================================================\n" +"\n" +" * the KLUWER Chart of Accounts,\n" +" * the Tax Code Chart for Luxembourg\n" +" * the main taxes used in Luxembourg" +msgstr "" + +#. module: base +#: field:ir.module.module,demo:0 +msgid "Demo data" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_portal +msgid "" +"\n" +"This module defines 'portals' to customize the access to your OpenERP " +"database\n" +"for external users.\n" +"\n" +"A portal defines customized user menu and access rights for a group of " +"users\n" +"(the ones associated to that portal). It also associates user groups to " +"the\n" +"portal users (adding a group in the portal automatically adds it to the " +"portal\n" +"users, etc). That feature is very handy when used in combination with the\n" +"module 'share'.\n" +" " +msgstr "" + +#. module: base +#: selection:res.request,priority:0 +msgid "High" +msgstr "" + +#. module: base +#: field:ir.attachment,description:0 +#: field:ir.mail_server,name:0 +#: field:ir.module.category,description:0 +#: view:ir.module.module:0 +#: field:ir.module.module,description:0 +#: view:res.partner.event:0 +#: field:res.partner.event,description:0 +#: view:res.request:0 +msgid "Description" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_instance_form +#: model:ir.ui.menu,name:base.menu_workflow_instance +msgid "Instances" +msgstr "" + +#. module: base +#: help:ir.mail_server,smtp_host:0 +msgid "Hostname or IP of SMTP server" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Japanese / 日本語" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,auto:0 +msgid "Custom python parser" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "_Import" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "XSL" +msgstr "" + +#. module: base +#: field:res.lang,grouping:0 +msgid "Separator Format" +msgstr "" + +#. module: base +#: constraint:res.partner.bank:0 +msgid "The RIB and/or IBAN is not valid" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_report_webkit +msgid "Webkit Report Engine" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Unvalidated" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_9 +msgid "Database Structure" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_mass_mail +#: model:ir.model,name:base.model_partner_massmail_wizard +#: view:partner.massmail.wizard:0 +msgid "Mass Mailing" +msgstr "" + +#. module: base +#: model:res.country,name:base.yt +msgid "Mayotte" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_crm_todo +msgid "Tasks on CRM" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_generic_modules_accounting +#: view:res.company:0 +msgid "Accounting" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_payment +msgid "" +"\n" +"Module to manage invoice payment.\n" +"=================================\n" +"\n" +"This module provides :\n" +"----------------------\n" +"* a more efficient way to manage invoice payment.\n" +"* a basic mechanism to easily plug various automated payment.\n" +" " +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "Interaction between rules" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_invoice_layout +msgid "" +"\n" +"This module provides some features to improve the layout of the invoices.\n" +"=========================================================================\n" +"\n" +"It gives you the possibility to:\n" +"--------------------------------\n" +" * order all the lines of an invoice\n" +" * add titles, comment lines, sub total lines\n" +" * draw horizontal lines and put page breaks\n" +"\n" +"Moreover, there is one option which allows you to print all the selected " +"invoices with a given special message at the bottom of it. This feature can " +"be very useful for printing your invoices with end-of-year wishes, special " +"punctual conditions.\n" +"\n" +" " +msgstr "" + +#. module: base +#: constraint:res.partner:0 +msgid "Error ! You cannot create recursive associated members." +msgstr "" + +#. module: base +#: view:res.payterm:0 +msgid "Payment Term" +msgstr "" + +#. module: base +#: selection:res.lang,direction:0 +msgid "Right-to-Left" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_event +msgid "res.partner.event" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +#: model:ir.actions.act_window,name:base.actions_ir_filters_view +#: view:ir.filters:0 +#: model:ir.model,name:base.model_ir_filters +#: model:ir.ui.menu,name:base.menu_ir_filters +msgid "Filters" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.open_module_tree +msgid "" +"You can install new modules in order to activate new features, menu, reports " +"or data in your OpenERP instance. To install some modules, click on the " +"button \"Install\" from the form view and then click on \"Start Upgrade\"." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_cron_act +#: view:ir.cron:0 +#: model:ir.ui.menu,name:base.menu_ir_cron_act +msgid "Scheduled Actions" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_chat +msgid "" +"\n" +" OpenERP Web chat module.\n" +" " +msgstr "" + +#. module: base +#: field:res.partner.address,title:0 +#: field:res.partner.title,name:0 +#: field:res.widget,title:0 +msgid "Title" +msgstr "" + +#. module: base +#: help:ir.property,res_id:0 +msgid "If not set, acts as a default value for new resources" +msgstr "" + +#. module: base +#: code:addons/orm.py:3988 +#, python-format +msgid "Recursivity Detected." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_report_webkit_sample +msgid "Webkit Report Samples" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_point_of_sale +msgid "Point Of Sale" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:302 +#, python-format +msgid "Recursion error in modules dependencies !" +msgstr "" + +#. module: base +#: view:base.language.install:0 +msgid "" +"This wizard helps you add a new language to your OpenERP system. After " +"loading a new language it becomes available as default interface language " +"for users and partners." +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "Create a Menu" +msgstr "" + +#. module: base +#: help:res.partner,vat:0 +msgid "" +"Value Added Tax number. Check the box if the partner is subjected to the " +"VAT. Used by the VAT legal statement." +msgstr "" + +#. module: base +#: selection:ir.sequence,implementation:0 +msgid "Standard" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_maintenance_contract +msgid "maintenance.contract" +msgstr "" + +#. module: base +#: model:res.country,name:base.ru +msgid "Russian Federation" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Urdu / اردو" +msgstr "" + +#. module: base +#: field:res.company,name:0 +msgid "Company Name" +msgstr "" + +#. module: base +#: code:addons/orm.py:2683 +#, python-format +msgid "" +"Invalid value for reference field \"%s.%s\" (last part must be a non-zero " +"integer): \"%s\"" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_human_resources +msgid "Human Resources" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_country +#: model:ir.ui.menu,name:base.menu_country_partner +msgid "Countries" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "RML (deprecated - use Report)" +msgstr "" + +#. module: base +#: sql_constraint:ir.translation:0 +msgid "Language code of translation item must be among known languages" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "Record rules" +msgstr "" + +#. module: base +#: view:ir.property:0 +msgid "Field Information" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_multilang +msgid "" +"\n" +" * Multi language support for Chart of Accounts, Taxes, Tax Codes , " +"Journals, Accounting Templates,\n" +" Analytic Chart of Accounts and Analytic Journals.\n" +" * Setup wizard changes\n" +" - Copy translations for COA, Tax, Tax Code and Fiscal Position from " +"templates to target objects.\n" +" " +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Search Actions" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_partner_wizard_ean_check +#: view:partner.wizard.ean.check:0 +msgid "Ean check" +msgstr "" + +#. module: base +#: field:res.partner,vat:0 +msgid "VAT" +msgstr "RFC" + +#. module: base +#: field:res.users,new_password:0 +msgid "Set password" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "12. %w ==> 5 ( Friday is the 6th day)" +msgstr "" + +#. module: base +#: constraint:res.partner.category:0 +msgid "Error ! You can not create recursive categories." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%x - Appropriate date representation." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_mobile +msgid "" +"\n" +" OpenERP Web mobile.\n" +" " +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%d - Day of the month [01,31]." +msgstr "" + +#. module: base +#: model:res.country,name:base.tj +msgid "Tajikistan" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL-2 or later version" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_sir +msgid "M." +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:519 +#, python-format +msgid "" +"Can not create the module file:\n" +" %s" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_wizard +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.wizard" +msgstr "" + +#. module: base +#: code:addons/orm.py:3437 +#, python-format +msgid "" +"Operation prohibited by access rules, or performed on an already deleted " +"document (Operation: read, Document type: %s)." +msgstr "" + +#. module: base +#: model:res.country,name:base.nr +msgid "Nauru" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Introspection report on objects" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:240 +#, python-format +msgid "The certificate ID of the module must be unique !" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_hn +msgid "" +"Agrega una nomenclatura contable para Honduras. También incluye impuestos y " +"la moneda Lempira. -- Adds accounting chart for Honduras. It also includes " +"taxes and the Lempira currency" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window,view_type:0 +#: selection:ir.actions.act_window.view,view_mode:0 +#: view:ir.ui.view:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Form" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_it +msgid "" +"\n" +"Piano dei conti italiano di un'impresa generica.\n" +"================================================\n" +"\n" +"Italian accounting chart and localization.\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.me +msgid "Montenegro" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_document_ics +msgid "iCal Support" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_fetchmail +msgid "Email Gateway" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:439 +#, python-format +msgid "" +"Mail delivery failed via SMTP server '%s'.\n" +"%s: %s" +msgstr "" + +#. module: base +#: view:ir.cron:0 +msgid "Technical Data" +msgstr "" + +#. module: base +#: view:res.partner:0 +#: field:res.partner,category_id:0 +msgid "Categories" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_mobile +msgid "OpenERP Web mobile" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "" +"If you need another language than the official ones available, you can " +"import a language pack from here. Other OpenERP languages than the official " +"ones can be found on launchpad." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_accountant +msgid "" +"\n" +"Accounting Access Rights.\n" +"=========================\n" +"\n" +"This module gives the admin user the access to all the accounting features\n" +"like the journal items and the chart of accounts.\n" +"\n" +"It assigns manager and user access rights to the Administrator, and only\n" +"user rights to Demo user.\n" +" " +msgstr "" + +#. module: base +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "To be upgraded" +msgstr "" + +#. module: base +#: model:res.country,name:base.ly +msgid "Libya" +msgstr "" + +#. module: base +#: model:res.country,name:base.cf +msgid "Central African Republic" +msgstr "" + +#. module: base +#: model:res.country,name:base.li +msgid "Liechtenstein" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_rpc +msgid "Openerp web web" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_project_issue_sheet +msgid "Timesheet on Issues" +msgstr "" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_ltd +msgid "Ltd" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_voucher +msgid "" +"\n" +"Account Voucher module includes all the basic requirements of Voucher " +"Entries for Bank, Cash, Sales, Purchase, Expanse, Contra, etc.\n" +"=============================================================================" +"=======================================================\n" +"\n" +" * Voucher Entry\n" +" * Voucher Receipt\n" +" * Cheque Register\n" +" " +msgstr "" + +#. module: base +#: field:res.partner,ean13:0 +msgid "EAN13" +msgstr "" + +#. module: base +#: code:addons/orm.py:2134 +#, python-format +msgid "Invalid Architecture!" +msgstr "" + +#. module: base +#: model:res.country,name:base.pt +msgid "Portugal" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_share +msgid "Share any Document" +msgstr "" + +#. module: base +#: field:ir.module.module,certificate:0 +msgid "Quality Certificate" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "6. %d, %m ==> 05, 12" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_analytic_multicurrency +msgid "" +"\n" +"This improve OpenERP multi-currency handling in analytic accountiong, " +"overall for multi-company.\n" +"\n" +"This module is based on the work made in all c2c_multicost* available on the " +"v5.0 stable version and\n" +"allow you to shar analytic account between company (even if currency differs " +"in each one).\n" +"\n" +"What has been done here:\n" +"\n" +" * Adapt the owner of analytic line (= to company that own the general " +"account associated with en analytic line)\n" +" * Add multi-currency on analytic lines (similar to financial accounting)\n" +" * Correct all \"costs\" indicators into analytic account to base them on " +"the right currency (owner's company)\n" +" * By default, nothing change for single company implementation.\n" +"\n" +"As a result, we can now really share the same analytic account between " +"companies that doesn't have the same \n" +"currency. This setup becomes True, Enjoy !\n" +"\n" +"- Company A : EUR\n" +"- Company B : CHF\n" +"\n" +"- Analytic Account A : USD, owned by Company A\n" +" - Analytic Account B : CHF, owned by Company A\n" +" - Analytic Account C : EUR, owned by Company B\n" +"\n" +"\n" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_it +msgid "Italy - Accounting" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,help:0 +msgid "Action description" +msgstr "" + +#. module: base +#: help:res.partner,customer:0 +msgid "Check this box if the partner is a customer." +msgstr "" + +#. module: base +#: help:ir.module.module,auto_install:0 +msgid "" +"An auto-installable module is automatically installed by the system when all " +"its dependencies are satisfied. If the module has no dependency, it is " +"always installed." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_lang_act_window +#: model:ir.model,name:base.model_res_lang +#: model:ir.ui.menu,name:base.menu_res_lang_act_window +#: view:res.lang:0 +msgid "Languages" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_crm_claim +msgid "" +"\n" +"This modules allows you to track your customers/suppliers claims and " +"grievances.\n" +"=============================================================================" +"===\n" +"\n" +"It is fully integrated with the email gateway so that you can create\n" +"automatically new claims based on incoming emails.\n" +" " +msgstr "" + +#. module: base +#: selection:workflow.activity,join_mode:0 +#: selection:workflow.activity,split_mode:0 +msgid "Xor" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_localization_account_charts +msgid "Account Charts" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Request Date" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:52 +#, python-format +msgid "" +"Save this document to a .CSV file and open it with your favourite " +"spreadsheet software. The file encoding is UTF-8. You have to translate the " +"latest column before reimporting it." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_customer_form +#: model:ir.actions.act_window,name:base.action_partner_form +#: model:ir.ui.menu,name:base.menu_partner_form +#: view:res.partner:0 +msgid "Customers" +msgstr "" + +#. module: base +#: model:res.country,name:base.au +msgid "Australia" +msgstr "" + +#. module: base +#: help:res.partner,lang:0 +msgid "" +"If the selected language is loaded in the system, all documents related to " +"this partner will be printed in this language. If not, it will be english." +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Menu :" +msgstr "" + +#. module: base +#: selection:ir.model.fields,state:0 +msgid "Base Field" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_anonymization +msgid "" +"\n" +"This module allows you to anonymize a database.\n" +"===============================================\n" +"\n" +"This module allows you to keep your data confidential for a given database.\n" +"This process is useful if you want to use the migration process and protect\n" +"your own or your customer’s confidential data. The principle is that you " +"run\n" +"an anonymization tool which will hide your confidential data(they are " +"replaced\n" +"by ‘XXX’ characters). Then you can send the anonymized database to the " +"migration\n" +"team. Once you get back your migrated database, you restore it and reverse " +"the\n" +"anonymization process to recover your previous data.\n" +" " +msgstr "" + +#. module: base +#: help:publisher_warranty.contract,name:0 +#: help:publisher_warranty.contract.wizard,name:0 +msgid "" +"Your OpenERP Publisher's Warranty Contract unique key, also called serial " +"number." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_setup +msgid "" +"\n" +"This module helps to configure the system at the installation of a new " +"database.\n" +"=============================================================================" +"===\n" +"\n" +"Shows you a list of applications features to install from.\n" +"\n" +" " +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_sxw_content:0 +#: field:ir.actions.report.xml,report_sxw_content_data:0 +msgid "SXW content" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_pl +msgid "Poland - Accounting" +msgstr "" + +#. module: base +#: view:ir.cron:0 +msgid "Action to Trigger" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Constraint" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_purchase +msgid "" +"\n" +"Purchase module is for generating a purchase order for purchase of goods " +"from a supplier.\n" +"=============================================================================" +"============\n" +"\n" +"A supplier invoice is created for the particular purchase order.\n" +"\n" +"Dashboard for purchase management that includes:\n" +" * Current Purchase Orders\n" +" * Draft Purchase Orders\n" +" * Graph for quantity and amount per month\n" +"\n" +" " +msgstr "" + +#. module: base +#: view:ir.model.fields:0 +#: field:ir.model.fields,required:0 +#: field:res.partner.bank.type.field,required:0 +msgid "Required" +msgstr "" + +#. module: base +#: view:res.users:0 +msgid "Default Filters" +msgstr "" + +#. module: base +#: field:res.request.history,name:0 +msgid "Summary" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_hidden_dependency +msgid "Dependency" +msgstr "" + +#. module: base +#: field:multi_company.default,expression:0 +msgid "Expression" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Validate" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Header/Footer" +msgstr "" + +#. module: base +#: help:ir.mail_server,sequence:0 +msgid "" +"When no specific mail server is requested for a mail, the highest priority " +"one is used. Default priority is 10 (smaller number = higher priority)" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_crm_partner_assign +msgid "" +"\n" +"This is the module used by OpenERP SA to redirect customers to its partners, " +"based on geolocalization.\n" +"=============================================================================" +"=========================\n" +"\n" +"You can geolocalize your opportunities by using this module.\n" +"\n" +"Use geolocalization when assigning opportunities to partners.\n" +"Determine the GPS coordinates according to the address of the partner.\n" +"The most appropriate partner can be assigned.\n" +"You can also use the geolocalization without using the GPS coordinates.\n" +" " +msgstr "" + +#. module: base +#: help:ir.actions.act_window,help:0 +msgid "" +"Optional help text for the users with a description of the target view, such " +"as its usage and purpose." +msgstr "" + +#. module: base +#: model:res.country,name:base.va +msgid "Holy See (Vatican City State)" +msgstr "" + +#. module: base +#: field:base.module.import,module_file:0 +msgid "Module .ZIP file" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_16 +msgid "Telecom sector" +msgstr "" + +#. module: base +#: field:workflow.transition,trigger_model:0 +msgid "Trigger Object" +msgstr "" + +#. module: base +#: sql_constraint:ir.sequence.type:0 +msgid "`code` must be unique." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr_expense +msgid "Expenses Management" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,in_transitions:0 +msgid "Incoming Transitions" +msgstr "" + +#. module: base +#: field:ir.values,value_unpickle:0 +msgid "Default value or action reference" +msgstr "" + +#. module: base +#: model:res.country,name:base.sr +msgid "Suriname" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_project_timesheet +msgid "Bill Time on Tasks" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_marketing +#: model:ir.module.module,shortdesc:base.module_marketing +#: model:ir.ui.menu,name:base.marketing_menu +msgid "Marketing" +msgstr "" + +#. module: base +#: view:res.partner.bank:0 +msgid "Bank account" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_gr +msgid "Greece - Accounting" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (HN) / Español (HN)" +msgstr "" + +#. module: base +#: view:ir.sequence.type:0 +msgid "Sequence Type" +msgstr "" + +#. module: base +#: view:ir.ui.view.custom:0 +msgid "Customized Architecture" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_gantt +msgid "web Gantt" +msgstr "" + +#. module: base +#: field:ir.module.module,license:0 +msgid "License" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_graph +msgid "web Graph" +msgstr "" + +#. module: base +#: field:ir.attachment,url:0 +msgid "Url" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "SQL Constraint" +msgstr "" + +#. module: base +#: help:ir.ui.menu,groups_id:0 +msgid "" +"If you have groups, the visibility of this menu will be based on these " +"groups. If this field is empty, OpenERP will compute visibility based on the " +"related object's read access." +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "" +"We suggest to reload the menu tab to see the new menus (Ctrl+T then Ctrl+R)." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_subscription +msgid "" +"\n" +"Create recurring documents.\n" +"===========================\n" +"\n" +"This module allows to create new documents and add subscriptions on that " +"document.\n" +"\n" +"e.g. To have an invoice generated automatically periodically:\n" +" * Define a document type based on Invoice object\n" +" * Define a subscription whose source document is the document defined as " +"above. Specify the interval information and partner to be invoice.\n" +" " +msgstr "" + +#. module: base +#: field:ir.actions.server,srcmodel_id:0 +#: field:ir.model,model:0 +#: field:ir.model.fields,model_id:0 +#: view:ir.values:0 +msgid "Model" +msgstr "" + +#. module: base +#: view:base.language.install:0 +msgid "" +"The selected language has been successfully installed. You must change the " +"preferences of the user and open a new menu to view the changes." +msgstr "" + +#. module: base +#: sql_constraint:ir.config_parameter:0 +msgid "Key must be unique." +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "Open a Window" +msgstr "" + +#. module: base +#: model:res.country,name:base.gq +msgid "Equatorial Guinea" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_warning +msgid "Warning Messages and Alerts" +msgstr "" + +#. module: base +#: view:base.module.import:0 +#: model:ir.actions.act_window,name:base.action_view_base_module_import +msgid "Module Import" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_ch +msgid "Switzerland - Accounting" +msgstr "" + +#. module: base +#: field:res.bank,zip:0 +#: field:res.company,zip:0 +#: field:res.partner.address,zip:0 +#: field:res.partner.bank,zip:0 +msgid "Zip" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: field:ir.module.module,author:0 +msgid "Author" +msgstr "" + +#. module: base +#: model:res.country,name:base.mk +msgid "FYROM" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Set as Todo" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%c - Appropriate date and time representation." +msgstr "" + +#. module: base +#: code:addons/base/res/res_config.py:386 +#, python-format +msgid "" +"Your database is now fully configured.\n" +"\n" +"Click 'Continue' and enjoy your OpenERP experience..." +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_marketing +msgid "Helps you manage your marketing campaigns step by step." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Hebrew / עִבְרִי" +msgstr "" + +#. module: base +#: model:res.country,name:base.bo +msgid "Bolivia" +msgstr "" + +#. module: base +#: model:res.country,name:base.gh +msgid "Ghana" +msgstr "" + +#. module: base +#: field:res.lang,direction:0 +msgid "Direction" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +#: model:ir.actions.act_window,name:base.action_ui_view +#: field:ir.actions.act_window,view_ids:0 +#: field:ir.actions.act_window,views:0 +#: view:ir.model:0 +#: field:ir.model,view_ids:0 +#: field:ir.module.module,views_by_module:0 +#: model:ir.ui.menu,name:base.menu_action_ui_view +#: view:ir.ui.view:0 +msgid "Views" +msgstr "" + +#. module: base +#: view:res.groups:0 +#: field:res.groups,rule_groups:0 +msgid "Rules" +msgstr "" + +#. module: base +#: field:ir.mail_server,smtp_host:0 +msgid "SMTP Server" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:256 +#, python-format +msgid "You try to remove a module that is installed or will be installed" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "The selected modules have been updated / installed !" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PR) / Español (PR)" +msgstr "" + +#. module: base +#: model:res.country,name:base.gt +msgid "Guatemala" +msgstr "" + +#. module: base +#: help:ir.actions.server,message:0 +msgid "" +"Email contents, may contain expressions enclosed in double brackets based on " +"the same values as those available in the condition field, e.g. `Dear [[ " +"object.partner_id.name ]]`" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_form +#: model:ir.ui.menu,name:base.menu_low_workflow +#: model:ir.ui.menu,name:base.menu_workflow +#: model:ir.ui.menu,name:base.menu_workflow_root +msgid "Workflows" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_profile_tools +msgid "" +"\n" +"Installer for extra Hidden like lunch, survey, idea, share, etc.\n" +"===============================================================\n" +"\n" +"Makes the Extra Hidden Configuration available from where you can install\n" +"modules like share, lunch, pad, idea, survey and subscription.\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_specific_industry_applications +msgid "Specific Industry Applications" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_retailers0 +msgid "Retailers" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_uservoice +msgid "Receive User Feedback" +msgstr "" + +#. module: base +#: model:res.country,name:base.ls +msgid "Lesotho" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_vat +msgid "VAT Number Validation" +msgstr "Validación del RFC" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_crm_partner_assign +msgid "Partners Geo-Localization" +msgstr "" + +#. module: base +#: model:res.country,name:base.ke +msgid "Kenya" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_translation +#: model:ir.ui.menu,name:base.menu_action_translation +msgid "Translated Terms" +msgstr "" + +#. module: base +#: view:res.partner.event:0 +msgid "Event" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_custom_reports +msgid "Custom Reports" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Abkhazian / аҧсуа" +msgstr "" + +#. module: base +#: view:base.module.configuration:0 +msgid "System Configuration Done" +msgstr "" + +#. module: base +#: code:addons/orm.py:1459 +#, python-format +msgid "Error occurred while validating the field(s) %s: %s" +msgstr "" + +#. module: base +#: view:ir.property:0 +msgid "Generic" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "SMS Configuration" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_document_webdav +msgid "" +"\n" +"With this module, the WebDAV server for documents is activated.\n" +"===============================================================\n" +"\n" +"You can then use any compatible browser to remotely see the attachments of " +"OpenObject.\n" +"\n" +"After installation, the WebDAV server can be controlled by a [webdav] " +"section in the server's config.\n" +"Server Configuration Parameter:\n" +"\n" +" [webdav]\n" +" ; enable = True ; Serve webdav over the http(s) servers\n" +" ; vdir = webdav ; the directory that webdav will be served at\n" +" ; this default val means that webdav will be\n" +" ; on \"http://localhost:8069/webdav/\n" +" ; verbose = True ; Turn on the verbose messages of webdav\n" +" ; debug = True ; Turn on the debugging messages of webdav\n" +" ; since the messages are routed to the python logging, with\n" +" ; levels \"debug\" and \"debug_rpc\" respectively, you can leave\n" +" ; these options on\n" +"\n" +"Also implements IETF RFC 5785 for services discovery on a http server,\n" +"which needs explicit configuration in openerp-server.conf, too.\n" +msgstr "" + +#. module: base +#: model:res.country,name:base.sm +msgid "San Marino" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_survey +msgid "" +"\n" +"This module is used for surveying.\n" +"==================================\n" +"\n" +"It depends on the answers or reviews of some questions by different users.\n" +"A survey may have multiple pages. Each page may contain multiple questions " +"and each question may have multiple answers.\n" +"Different users may give different answers of question and according to that " +"survey is done.\n" +"Partners are also sent mails with user name and password for the invitation " +"of the survey\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.bm +msgid "Bermuda" +msgstr "" + +#. module: base +#: model:res.country,name:base.pe +msgid "Peru" +msgstr "" + +#. module: base +#: selection:ir.model.fields,on_delete:0 +msgid "Set NULL" +msgstr "" + +#. module: base +#: model:res.country,name:base.bj +msgid "Benin" +msgstr "" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:295 +#: sql_constraint:publisher_warranty.contract:0 +#, python-format +msgid "That contract is already registered in the system." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_partner_bank_type_form +#: model:ir.ui.menu,name:base.menu_action_res_partner_bank_typeform +msgid "Bank Account Types" +msgstr "" + +#. module: base +#: help:ir.sequence,suffix:0 +msgid "Suffix value of the record for the sequence" +msgstr "" + +#. module: base +#: help:ir.mail_server,smtp_user:0 +msgid "Optional username for SMTP authentication" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_actions +msgid "ir.actions.actions" +msgstr "" + +#. module: base +#: selection:ir.model.fields,select_level:0 +msgid "Not Searchable" +msgstr "" + +#. module: base +#: field:ir.config_parameter,key:0 +msgid "Key" +msgstr "" + +#. module: base +#: field:res.company,rml_header:0 +msgid "RML Header" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:271 +#, python-format +msgid "" +"Please keep in mind that documents currently displayed may not be relevant " +"after switching to another company. If you have unsaved changes, please make " +"sure to save and close all forms before switching to a different company. " +"(You can click on Cancel in the User Preferences now)" +msgstr "" + +#. module: base +#: field:partner.sms.send,app_id:0 +msgid "API ID" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:533 +#, python-format +msgid "" +"You can not create this document (%s) ! Be sure your user belongs to one of " +"these groups: %s." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_chat +msgid "Web Chat" +msgstr "" + +#. module: base +#: field:res.company,rml_footer2:0 +msgid "Bank Accounts Footer" +msgstr "" + +#. module: base +#: model:res.country,name:base.mu +msgid "Mauritius" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: view:ir.rule:0 +msgid "Full Access" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +#: view:ir.actions.report.xml:0 +#: view:ir.actions.wizard:0 +#: view:ir.model.fields:0 +#: model:ir.ui.menu,name:base.menu_security +msgid "Security" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:311 +#, python-format +msgid "Changing the storing system for field \"%s\" is not allowed." +msgstr "" + +#. module: base +#: help:res.partner.bank,company_id:0 +msgid "Only if this bank account belong to your company" +msgstr "" + +#. module: base +#: model:res.country,name:base.za +msgid "South Africa" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "Installed" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Ukrainian / українська" +msgstr "" + +#. module: base +#: model:res.country,name:base.sn +msgid "Senegal" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_purchase_requisition +msgid "" +"\n" +"This module allows you to manage your Purchase Requisition.\n" +"===========================================================\n" +"\n" +"When a purchase order is created, you now have the opportunity to save the " +"related requisition.\n" +"This new object will regroup and will allow you to easily keep track and " +"order all your purchase orders.\n" +msgstr "" + +#. module: base +#: model:res.country,name:base.hu +msgid "Hungary" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr_recruitment +msgid "Recruitment Process" +msgstr "" + +#. module: base +#: model:res.country,name:base.br +msgid "Brazil" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%M - Minute [00,59]." +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "Affero GPL-3" +msgstr "" + +#. module: base +#: field:ir.sequence,number_next:0 +msgid "Next Number" +msgstr "" + +#. module: base +#: help:workflow.transition,condition:0 +msgid "Expression to be satisfied if we want the transition done." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_publisher_warranty_contract_wizard +msgid "publisher_warranty.contract.wizard" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PA) / Español (PA)" +msgstr "" + +#. module: base +#: view:res.currency:0 +#: field:res.currency,rate_ids:0 +msgid "Rates" +msgstr "" + +#. module: base +#: model:res.country,name:base.sy +msgid "Syria" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "======================================================" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "System update completed" +msgstr "" + +#. module: base +#: sql_constraint:ir.model:0 +msgid "Each model must be unique!" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_localization +msgid "Localization" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_sale_mrp +msgid "" +"\n" +"This module provides facility to the user to install mrp and sales modulesat " +"a time.\n" +"=============================================================================" +"=======\n" +"\n" +"It is basically used when we want to keep track of production\n" +"orders generated from sales order.\n" +"It adds sales name and sales Reference on production order.\n" +" " +msgstr "" + +#. module: base +#: selection:res.request,state:0 +msgid "draft" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +#: field:res.currency,date:0 +#: field:res.currency.rate,name:0 +#: field:res.partner,date:0 +#: field:res.partner.event,date:0 +#: field:res.request,date_sent:0 +msgid "Date" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_sxw:0 +msgid "SXW path" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Data" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr_timesheet_invoice +msgid "" +"Generate your Invoices from Expenses, Timesheet Entries, ...\n" +"Module to generate invoices based on costs (human resources, expenses, " +"...).\n" +"============================================================================" +"\n" +"\n" +"You can define price lists in analytic account, make some theoretical " +"revenue\n" +"reports, etc." +msgstr "" + +#. module: base +#: field:ir.ui.menu,parent_id:0 +#: field:wizard.ir.model.menu.create,menu_id:0 +msgid "Parent Menu" +msgstr "" + +#. module: base +#: field:res.partner.bank,owner_name:0 +msgid "Account Owner Name" +msgstr "" + +#. module: base +#: field:ir.rule,perm_unlink:0 +msgid "Apply For Delete" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:359 +#, python-format +msgid "Cannot rename column to %s, because that column already exists!" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Attached To" +msgstr "" + +#. module: base +#: field:res.lang,decimal_point:0 +msgid "Decimal Separator" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:346 +#: view:ir.module.module:0 +#, python-format +msgid "Install" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_groups +msgid "" +"A group is a set of functional areas that will be assigned to the user in " +"order to give them access and rights to specific applications and tasks in " +"the system. You can create custom groups or edit the ones existing by " +"default in order to customize the view of the menu that users will be able " +"to see. Whether they can have a read, write, create and delete access right " +"can be managed from here." +msgstr "" + +#. module: base +#: field:ir.filters,name:0 +msgid "Filter Name" +msgstr "" + +#. module: base +#: view:res.partner:0 +#: view:res.request:0 +#: field:res.request,history:0 +msgid "History" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_uk +msgid "" +"This is the latest UK OpenERP localisation necesary to run OpenERP " +"accounting for UK SME's with:\n" +" - a CT600-ready chart of accounts\n" +" - VAT100-ready tax structure\n" +" - InfoLogic UK counties listing\n" +" - a few other adaptations" +msgstr "" + +#. module: base +#: field:ir.attachment,create_uid:0 +msgid "Creator" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_asset +msgid "" +"Financial and accounting asset management.\n" +" This Module manages the assets owned by a company or an individual. It " +"will keep track of depreciation's occurred on\n" +" those assets. And it allows to create Move's of the depreciation lines.\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.bv +msgid "Bouvet Island" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_config_plugins +msgid "Plugins" +msgstr "" + +#. module: base +#: field:res.company,child_ids:0 +msgid "Child Companies" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_users +msgid "res.users" +msgstr "" + +#. module: base +#: model:res.country,name:base.ni +msgid "Nicaragua" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_be +msgid "" +"\n" +"This is the base module to manage the accounting chart for Belgium in " +"OpenERP.\n" +"=============================================================================" +"=\n" +"\n" +"After installing this module, the Configuration wizard for accounting is " +"launched.\n" +" * We have the account templates which can be helpful to generate Charts " +"of Accounts.\n" +" * On that particular wizard, you will be asked to pass the name of the " +"company, the chart template to follow, the no. of digits to generate, the " +"code for your account and bank account, currency to create journals.\n" +"\n" +"Thus, the pure copy of Chart Template is generated.\n" +"\n" +"Wizards provided by this module:\n" +" * Partner VAT Intra: Enlist the partners with their related VAT and " +"invoiced amounts.Prepares an XML file format.\n" +" Path to access : Accounting/Reporting//Legal Statements/Belgium " +"Statements/Partner VAT Listing\n" +" * Periodical VAT Declaration: Prepares an XML file for Vat Declaration " +"of the Main company of the User currently Logged in.\n" +" Path to access : Accounting/Reporting/Legal Statements/Belgium " +"Statements/Periodical VAT Declaration\n" +" * Annual Listing Of VAT-Subjected Customers: Prepares an XML file for " +"Vat Declaration of the Main company of the User currently Logged in.Based on " +"Fiscal year\n" +" Path to access : Accounting/Reporting/Legal Statements/Belgium " +"Statements/Annual Listing Of VAT-Subjected Customers\n" +"\n" +" " +msgstr "" + +#. module: base +#: field:ir.property,fields_id:0 +#: selection:ir.translation,type:0 +#: field:multi_company.default,field_id:0 +msgid "Field" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_project_long_term +msgid "Long Term Projects" +msgstr "" + +#. module: base +#: model:res.country,name:base.ve +msgid "Venezuela" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "9. %j ==> 340" +msgstr "" + +#. module: base +#: model:res.country,name:base.zm +msgid "Zambia" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Launch Configuration Wizard" +msgstr "" + +#. module: base +#: help:res.partner,user_id:0 +msgid "" +"The internal user that is in charge of communicating with this partner if " +"any." +msgstr "" + +#. module: base +#: field:res.partner,parent_id:0 +msgid "Parent Partner" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Cancel Upgrade" +msgstr "" + +#. module: base +#: model:res.country,name:base.ci +msgid "Ivory Coast (Cote D'Ivoire)" +msgstr "" + +#. module: base +#: model:res.country,name:base.kz +msgid "Kazakhstan" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%w - Weekday number [0(Sunday),6]." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_form +msgid "" +"A customer is an entity you do business with, like a company or an " +"organization. A customer can have several contacts or addresses which are " +"the people working for this company. You can use the history tab, to follow " +"all transactions related to a customer: sales order, emails, opportunities, " +"claims, etc. If you use the email gateway, the Outlook or the Thunderbird " +"plugin, don't forget to register emails to each contact so that the gateway " +"will automatically attach incoming emails to the right partner." +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,name:0 +#: field:ir.actions.todo,name:0 +#: field:ir.actions.todo.category,name:0 +#: field:ir.cron,name:0 +#: field:ir.model.access,name:0 +#: field:ir.model.fields,name:0 +#: field:ir.module.category,name:0 +#: view:ir.module.module:0 +#: field:ir.module.module,name:0 +#: field:ir.module.module.dependency,name:0 +#: report:ir.module.reference.graph:0 +#: field:ir.property,name:0 +#: field:ir.rule,name:0 +#: field:ir.sequence,name:0 +#: field:ir.sequence.type,name:0 +#: field:ir.values,name:0 +#: field:multi_company.default,name:0 +#: field:res.bank,name:0 +#: field:res.currency.rate.type,name:0 +#: field:res.groups,name:0 +#: field:res.lang,name:0 +#: field:res.partner,name:0 +#: field:res.partner.bank.type,name:0 +#: view:res.partner.event:0 +#: field:res.request.link,name:0 +#: field:workflow,name:0 +#: field:workflow.activity,name:0 +msgid "Name" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,multi:0 +msgid "" +"If set to true, the action will not be displayed on the right toolbar of a " +"form view" +msgstr "" + +#. module: base +#: model:res.country,name:base.ms +msgid "Montserrat" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_decimal_precision +msgid "Decimal Precision Configuration" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_translation_app +msgid "Application Terms" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_stock +msgid "" +"\n" +"OpenERP Inventory Management module can manage multi-warehouses, multi and " +"structured stock locations.\n" +"=============================================================================" +"=========================\n" +"\n" +"Thanks to the double entry management, the inventory controlling is powerful " +"and flexible:\n" +" * Moves history and planning,\n" +" * Different inventory methods (FIFO, LIFO, ...)\n" +" * Stock valuation (standard or average price, ...)\n" +" * Robustness faced with Inventory differences\n" +" * Automatic reordering rules (stock level, JIT, ...)\n" +" * Bar code supported\n" +" * Rapid detection of mistakes through double entry system\n" +" * Traceability (upstream/downstream, production lots, serial number, " +"...)\n" +" * Dashboard for warehouse that includes:\n" +" * Procurement in exception\n" +" * List of Incoming Products\n" +" * List of Outgoing Products\n" +" * Graph : Products to receive in delay (date < = today)\n" +" * Graph : Products to send in delay (date < = today)\n" +" " +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_module_module +#: view:ir.model.data:0 +#: field:ir.model.data,module:0 +#: view:ir.module.module:0 +#: field:ir.module.module.dependency,module_id:0 +#: report:ir.module.reference.graph:0 +msgid "Module" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "English (UK)" +msgstr "" + +#. module: base +#: model:res.country,name:base.aq +msgid "Antarctica" +msgstr "" + +#. module: base +#: help:workflow.transition,act_from:0 +msgid "" +"Source activity. When this activity is over, the condition is tested to " +"determine if we can start the ACT_TO activity." +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_3 +msgid "Starter Partner" +msgstr "" + +#. module: base +#: help:ir.model.fields,relation_field:0 +msgid "" +"For one2many fields, the field on the target model that implement the " +"opposite many2one relationship" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_budget +msgid "" +"\n" +"This module allows accountants to manage analytic and crossovered budgets.\n" +"==========================================================================\n" +"\n" +"Once the Master Budgets and the Budgets are defined (in " +"Accounting/Budgets/),\n" +"the Project Managers can set the planned amount on each Analytic Account.\n" +"\n" +"The accountant has the possibility to see the total of amount planned for " +"each\n" +"Budget and Master Budget in order to ensure the total planned is not\n" +"greater/lower than what he planned for this Budget/Master Budget. Each list " +"of\n" +"record can also be switched to a graphical view of it.\n" +"\n" +"Three reports are available:\n" +" 1. The first is available from a list of Budgets. It gives the " +"spreading, for these Budgets, of the Analytic Accounts per Master Budgets.\n" +"\n" +" 2. The second is a summary of the previous one, it only gives the " +"spreading, for the selected Budgets, of the Analytic Accounts.\n" +"\n" +" 3. The last one is available from the Analytic Chart of Accounts. It " +"gives the spreading, for the selected Analytic Accounts, of the Master " +"Budgets per Budgets.\n" +"\n" +msgstr "" + +#. module: base +#: help:res.lang,iso_code:0 +msgid "This ISO code is the name of po files to use for translations" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_act_window_view +msgid "ir.actions.act_window.view" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Web" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_lunch +msgid "Lunch Orders" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "English (CA)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_publisher_warranty_contract +msgid "publisher_warranty.contract" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_coda +msgid "" +"\n" +" Module to import CODA bank statements.\n" +"\n" +" Supported are CODA flat files in V2 format from Belgian bank accounts.\n" +" - CODA v1 support.\n" +" - CODA v2.2 support.\n" +" - Foreign Currency support.\n" +" - Support for all data record types (0, 1, 2, 3, 4, 8, 9).\n" +" - Parsing & logging of all Transaction Codes and Structured Format " +"Communications.\n" +" - Automatic Financial Journal assignment via CODA configuration " +"parameters.\n" +" - Support for multiple Journals per Bank Account Number.\n" +" - Support for multiple statements from different bank accounts in a " +"single CODA file.\n" +" - Support for 'parsing only' CODA Bank Accounts (defined as type='info' " +"in the CODA Bank Account configuration records).\n" +" - Multi-language CODA parsing, parsing configuration data provided for " +"EN, NL, FR.\n" +"\n" +" The machine readable CODA Files are parsed and stored in human readable " +"format in CODA Bank Statements.\n" +" Also Bank Statements are generated containing a subset of the CODA " +"information (only those transaction lines\n" +" that are required for the creation of the Financial Accounting " +"records).\n" +" The CODA Bank Statement is a 'read-only' object, hence remaining a " +"reliable representation of the original CODA file\n" +" whereas the Bank Statement will get modified as required by accounting " +"business processes.\n" +"\n" +" CODA Bank Accounts configured as type 'Info' will only generate CODA " +"Bank Statements.\n" +"\n" +" A removal of one object in the CODA processing results in the removal of " +"the associated objects.\n" +" The removal of a CODA File containing multiple Bank Statements will also " +"remove those associated\n" +" statements.\n" +"\n" +" The following reconciliation logic has been implemented in the CODA " +"processing:\n" +" 1) The Company's Bank Account Number of the CODA statement is compared " +"against the Bank Account Number field\n" +" of the Company's CODA Bank Account configuration records (whereby " +"bank accounts defined in type='info' configuration records are ignored).\n" +" If this is the case an 'internal transfer' transaction is generated " +"using the 'Internal Transfer Account' field of the CODA File Import wizard.\n" +" 2) As a second step the 'Structured Communication' field of the CODA " +"transaction line is matched against\n" +" the reference field of in- and outgoing invoices (supported : Belgian " +"Structured Communication Type).\n" +" 3) When the previous step doesn't find a match, the transaction " +"counterparty is located via the\n" +" Bank Account Number configured on the OpenERP Customer and Supplier " +"records.\n" +" 4) In case the previous steps are not successful, the transaction is " +"generated by using the 'Default Account\n" +" for Unrecognized Movement' field of the CODA File Import wizard in " +"order to allow further manual processing.\n" +"\n" +" In stead of a manual adjustment of the generated Bank Statements, you " +"can also re-import the CODA\n" +" after updating the OpenERP database with the information that was " +"missing to allow automatic reconciliation.\n" +"\n" +" Remark on CODA V1 support:\n" +" In some cases a transaction code, transaction category or structured " +"communication code has been given a new or clearer description in CODA V2.\n" +" The description provided by the CODA configuration tables is based upon " +"the CODA V2.2 specifications.\n" +" If required, you can manually adjust the descriptions via the CODA " +"configuration menu.\n" +"\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.et +msgid "Ethiopia" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_analytic_plans +msgid "" +"\n" +"This module allows to use several analytic plans, according to the general " +"journal.\n" +"=============================================================================" +"======\n" +"\n" +"Here multiple analytic lines are created when the invoice or the entries\n" +"are confirmed.\n" +"\n" +"For example, you can define the following analytic structure:\n" +" Projects\n" +" Project 1\n" +" SubProj 1.1\n" +" SubProj 1.2\n" +"\n" +" Project 2\n" +" Salesman\n" +" Eric\n" +" Fabien\n" +"\n" +"Here, we have two plans: Projects and Salesman. An invoice line must\n" +"be able to write analytic entries in the 2 plans: SubProj 1.1 and\n" +"Fabien. The amount can also be split. The following example is for\n" +"an invoice that touches the two subproject and assigned to one salesman:\n" +"\n" +"Plan1:\n" +" SubProject 1.1 : 50%\n" +" SubProject 1.2 : 50%\n" +"Plan2:\n" +" Eric: 100%\n" +"\n" +"So when this line of invoice will be confirmed, it will generate 3 analytic " +"lines,\n" +"for one account entry.\n" +"The analytic plan validates the minimum and maximum percentage at the time " +"of creation\n" +"of distribution models.\n" +" " +msgstr "" + +#. module: base +#: help:res.country.state,code:0 +msgid "The state code in three chars.\n" +msgstr "" + +#. module: base +#: model:res.country,name:base.sj +msgid "Svalbard and Jan Mayen Islands" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_hidden_test +msgid "Test" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_kanban +msgid "Base Kanban" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +#: view:ir.actions.report.xml:0 +#: view:ir.actions.server:0 +#: view:res.request:0 +msgid "Group By" +msgstr "" + +#. module: base +#: view:res.config:0 +#: view:res.config.installer:0 +msgid "title" +msgstr "" + +#. module: base +#: field:base.language.install,state:0 +#: field:base.module.import,state:0 +#: field:base.module.update,state:0 +msgid "state" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_analytic_analysis +msgid "" +"\n" +"This module is for modifying account analytic view to show important data to " +"project manager of services companies.\n" +"=============================================================================" +"======================================\n" +"\n" +"Adds menu to show relevant information to each manager.\n" +"You can also view the report of account analytic summary\n" +"user-wise as well as month wise.\n" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_language_install +msgid "Install Language" +msgstr "" + +#. module: base +#: view:ir.translation:0 +msgid "Translation" +msgstr "" + +#. module: base +#: selection:res.request,state:0 +msgid "closed" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_cr +msgid "" +"\n" +"Chart of accounts for Costa Rica.\n" +"=================================\n" +"\n" +"Includes:\n" +"* account.type\n" +"* account.account.template\n" +"* account.tax.template\n" +"* account.tax.code.template\n" +"* account.chart.template\n" +"\n" +"Everything is in English with Spanish translation. Further translations are " +"welcome, please go to\n" +"http://translations.launchpad.net/openerp-costa-rica\n" +" " +msgstr "" + +#. module: base +#: selection:base.language.export,state:0 +msgid "get" +msgstr "" + +#. module: base +#: help:ir.model.fields,on_delete:0 +msgid "On delete property for many2one fields" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_accounting_and_finance +msgid "Accounting & Finance" +msgstr "" + +#. module: base +#: field:ir.actions.server,write_id:0 +msgid "Write Id" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_product +msgid "Products" +msgstr "" + +#. module: base +#: help:res.users,name:0 +msgid "The new user's real name, used for searching and most listings" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_values_form_defaults +#: model:ir.ui.menu,name:base.menu_values_form_defaults +#: view:ir.values:0 +msgid "User-defined Defaults" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_usability +#: view:res.users:0 +msgid "Usability" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,domain:0 +#: field:ir.filters,domain:0 +msgid "Domain Value" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_module_quality +msgid "Analyse Module Quality" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (BO) / Español (BO)" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_access_act +#: model:ir.ui.menu,name:base.menu_ir_access_act +msgid "Access Controls List" +msgstr "" + +#. module: base +#: model:res.country,name:base.um +msgid "USA Minor Outlying Islands" +msgstr "" + +#. module: base +#: help:ir.cron,numbercall:0 +msgid "" +"How many times the method is called,\n" +"a negative number indicates no limit." +msgstr "" + +#. module: base +#: field:res.partner.bank.type.field,bank_type_id:0 +msgid "Bank Type" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:87 +#: code:addons/base/res/res_users.py:96 +#, python-format +msgid "The name of the group can not start with \"-\"" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Apps" +msgstr "" + +#. module: base +#: view:ir.ui.view_sc:0 +#: field:res.partner.title,shortcut:0 +msgid "Shortcut" +msgstr "" + +#. module: base +#: field:ir.model.data,date_init:0 +msgid "Init Date" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Gujarati / ગુજરાતી" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:297 +#, python-format +msgid "" +"Unable to process module \"%s\" because an external dependency is not met: %s" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_be_hr_payroll +msgid "Belgium - Payroll" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "Please enter the serial key provided in your contract document:" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,flow_start:0 +msgid "Flow Start" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_title +msgid "res.partner.title" +msgstr "" + +#. module: base +#: view:res.partner.bank:0 +msgid "Bank Account Owner" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_uncategorized +msgid "Uncategorized" +msgstr "" + +#. module: base +#: field:ir.attachment,res_name:0 +#: field:ir.ui.view_sc,resource:0 +msgid "Resource Name" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_default +msgid "ir.default" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr_payroll +msgid "" +"\n" +"Generic Payroll system.\n" +"=======================\n" +"\n" +" * Employee Details\n" +" * Employee Contracts\n" +" * Passport based Contract\n" +" * Allowances / Deductions\n" +" * Allow to configure Basic / Grows / Net Salary\n" +" * Employee Payslip\n" +" * Monthly Payroll Register\n" +" * Integrated with Holiday Management\n" +" " +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Hours" +msgstr "" + +#. module: base +#: model:res.country,name:base.gp +msgid "Guadeloupe (French)" +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:187 +#: code:addons/base/res/res_lang.py:189 +#: code:addons/base/res/res_lang.py:191 +#, python-format +msgid "User Error" +msgstr "" + +#. module: base +#: help:workflow.transition,signal:0 +msgid "" +"When the operation of transition comes from a button pressed in the client " +"form, signal tests the name of the pressed button. If signal is NULL, no " +"button is necessary to validate this transition." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_diagram +msgid "OpenERP Web Diagram" +msgstr "" + +#. module: base +#: view:res.partner.bank:0 +msgid "My Banks" +msgstr "" + +#. module: base +#: help:multi_company.default,object_id:0 +msgid "Object affected by this rule" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Directory" +msgstr "" + +#. module: base +#: field:wizard.ir.model.menu.create,name:0 +msgid "Menu Name" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Author Website" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_board +msgid "" +"\n" +"Lets the user create a custom dashboard.\n" +"========================================\n" +"\n" +"This module also creates the Administration Dashboard.\n" +"\n" +"The user can also publish notes.\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_project_scrum +msgid "Methodology: SCRUM" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Month" +msgstr "" + +#. module: base +#: model:res.country,name:base.my +msgid "Malaysia" +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: model:ir.actions.act_window,name:base.action_view_base_language_install +msgid "Load Official Translation" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_cancel +msgid "Cancel Journal Entries" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Client Action Configuration" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_address +#: view:res.partner.address:0 +msgid "Partner Addresses" +msgstr "" + +#. module: base +#: help:ir.mail_server,smtp_debug:0 +msgid "" +"If enabled, the full output of SMTP sessions will be written to the server " +"log at DEBUG level(this is very verbose and may include confidential info!)" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_report_creator +msgid "Query Builder" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,type:0 +msgid "Launch Automatically" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_mail +msgid "" +"\n" +"A generic email subsystem with message storage and queuing\n" +"==========================================================\n" +"\n" +"This email subsystem is not intended to be used as as standalone\n" +"application, but to provide a unified email abstraction that all\n" +"other applications can use.\n" +"\n" +"The main features are:\n" +"\n" +" * Relies on the global Outgoing Mail Servers configured in the \n" +" Administration menu for delivering outgoing mail\n" +" * Provides an API for sending messages and archiving them,\n" +" grouped by conversation\n" +" * Any OpenERP document can act as a conversation topic, provided\n" +" it includes the necessary support for handling incoming emails\n" +" (see the ``mail.thread`` class for more details). \n" +" * Includes queuing mechanism with automated configurable\n" +" scheduler-based processing\n" +" * Includes a generic email composition assistant, that can turn\n" +" into a mass-mailing assistant, and is capable of interpreting\n" +" simple *placeholder expressions* that will be replaced with\n" +" dynamic data when each email is actually sent.\n" +" This generic assistant is easily extensible to provide advanced\n" +" features (see ``email_template`` for example, which adds email\n" +" templating features to this assistant)\n" +"\n" +" " +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%S - Seconds [00,61]." +msgstr "" + +#. module: base +#: model:res.country,name:base.cv +msgid "Cape Verde" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_contact +msgid "" +"\n" +"This module allows you to manage your contacts\n" +"==============================================\n" +"\n" +"It lets you define:\n" +" * contacts unrelated to a partner,\n" +" * contacts working at several addresses (possibly for different " +"partners),\n" +" * contacts with possibly different functions for each of its job's " +"addresses\n" +"\n" +"It also adds new menu items located in\n" +" Purchases / Address Book / Contacts\n" +" Sales / Address Book / Contacts\n" +"\n" +"Pay attention that this module converts the existing addresses into " +"\"addresses + contacts\". It means that some fields of the addresses will be " +"missing (like the contact name), since these are supposed to be defined in " +"an other object.\n" +" " +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_res_partner_event +#: model:ir.ui.menu,name:base.menu_event_association +#: field:res.partner,events:0 +#: field:res.partner.event,name:0 +#: model:res.widget,title:base.events_widget +msgid "Events" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_url +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.url" +msgstr "" + +#. module: base +#: model:res.widget,title:base.currency_converter_widget +msgid "Currency Converter" +msgstr "" + +#. module: base +#: help:ir.values,key:0 +msgid "" +"- Action: an action attached to one slot of the given model\n" +"- Default: a default value for a model field" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_addess_tree +#: view:res.partner:0 +msgid "Partner Contacts" +msgstr "" + +#. module: base +#: field:base.module.update,add:0 +msgid "Number of modules added" +msgstr "" + +#. module: base +#: view:res.currency:0 +msgid "Price Accuracy" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Latvian / latviešu valoda" +msgstr "" + +#. module: base +#: view:res.config:0 +#: view:res.config.installer:0 +msgid "vsep" +msgstr "" + +#. module: base +#: model:res.widget,title:base.openerp_favorites_twitter_widget +msgid "OpenERP Tweets" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:392 +#, python-format +msgid "Uninstall" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_budget +msgid "Budgets Management" +msgstr "" + +#. module: base +#: field:workflow.triggers,workitem_id:0 +msgid "Workitem" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_anonymization +msgid "Database Anonymization" +msgstr "" + +#. module: base +#: selection:ir.mail_server,smtp_encryption:0 +msgid "SSL/TLS" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,check_opw:0 +msgid "OPW" +msgstr "" + +#. module: base +#: field:res.log,secondary:0 +msgid "Secondary Log" +msgstr "" + +#. module: base +#: field:ir.actions.act_window.view,act_window_id:0 +#: view:ir.actions.actions:0 +#: field:ir.actions.todo,action_id:0 +#: field:ir.ui.menu,action:0 +#: view:ir.values:0 +#: selection:ir.values,key:0 +#: view:res.users:0 +msgid "Action" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Email Configuration" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_cron +msgid "ir.cron" +msgstr "" + +#. module: base +#: field:partner.sms.send,mobile_to:0 +#: field:res.request,act_to:0 +#: field:res.request.history,act_to:0 +msgid "To" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Current Year without Century: %(y)s" +msgstr "" + +#. module: base +#: help:ir.actions.client,tag:0 +msgid "" +"An arbitrary string, interpreted by the client according to its own needs " +"and wishes. There is no central tag repository across clients." +msgstr "" + +#. module: base +#: sql_constraint:ir.rule:0 +msgid "Rule must have at least one checked access right !" +msgstr "" + +#. module: base +#: model:res.country,name:base.fj +msgid "Fiji" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_document_ftp +msgid "" +"\n" +"This is a support FTP Interface with document management system.\n" +"================================================================\n" +"\n" +"With this module you would not only be able to access documents through " +"OpenERP\n" +"but you would also be able to connect with them through the file system " +"using the\n" +"FTP client.\n" +msgstr "" + +#. module: base +#: field:ir.model.fields,size:0 +msgid "Size" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_analytic_user_function +msgid "" +"\n" +"This module allows you to define what is the default function of a specific " +"user on a given account.\n" +"=============================================================================" +"=======================\n" +"\n" +"This is mostly used when a user encodes his timesheet: the values are " +"retrieved and the fields are auto-filled. But the possibility to change " +"these values is still available.\n" +"\n" +"Obviously if no data has been recorded for the current account, the default " +"value is given as usual by the employee data so that this module is " +"perfectly compatible with older configurations.\n" +"\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_audittrail +msgid "Audit Trail" +msgstr "" + +#. module: base +#: model:res.country,name:base.sd +msgid "Sudan" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_currency_rate_type_form +#: model:ir.model,name:base.model_res_currency_rate_type +#: field:res.currency.rate,currency_rate_type_id:0 +#: view:res.currency.rate.type:0 +msgid "Currency Rate Type" +msgstr "" + +#. module: base +#: model:res.country,name:base.fm +msgid "Micronesia" +msgstr "" + +#. module: base +#: field:res.widget,content:0 +msgid "Content" +msgstr "" + +#. module: base +#: field:ir.module.module,menus_by_module:0 +#: view:res.groups:0 +msgid "Menus" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,type:0 +msgid "Launch Manually Once" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_hidden +msgid "Hidden" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Serbian (Latin) / srpski" +msgstr "" + +#. module: base +#: model:res.country,name:base.il +msgid "Israel" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_syscohada +msgid "OHADA - Accounting" +msgstr "" + +#. module: base +#: help:res.bank,bic:0 +msgid "Sometimes called BIC or Swift." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_mx +msgid "" +"\n" +"This is the module to manage the accounting chart for Mexico in OpenERP.\n" +"========================================================================\n" +"\n" +"Mexican accounting chart and localization.\n" +" " +msgstr "" + +#. module: base +#: field:res.lang,time_format:0 +msgid "Time Format" +msgstr "" + +#. module: base +#: code:addons/orm.py:2134 +#, python-format +msgid "There is no view of type '%s' defined for the structure!" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Defined Reports" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_payterm_form +#: model:ir.model,name:base.model_res_payterm +msgid "Payment term" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Report xml" +msgstr "" + +#. module: base +#: field:base.language.export,modules:0 +#: model:ir.actions.act_window,name:base.action_module_open_categ +#: model:ir.actions.act_window,name:base.open_module_tree +#: field:ir.module.category,module_ids:0 +#: view:ir.module.module:0 +#: model:ir.ui.menu,name:base.menu_management +#: model:ir.ui.menu,name:base.menu_module_tree +msgid "Modules" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: selection:workflow.activity,kind:0 +#: field:workflow.activity,subflow_id:0 +#: field:workflow.workitem,subflow_id:0 +msgid "Subflow" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_config +msgid "res.config" +msgstr "" + +#. module: base +#: field:workflow.transition,signal:0 +msgid "Signal (button Name)" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_bank_form +#: model:ir.ui.menu,name:base.menu_action_res_bank_form +#: view:res.bank:0 +#: field:res.partner,bank_ids:0 +msgid "Banks" +msgstr "" + +#. module: base +#: view:res.log:0 +msgid "Unread" +msgstr "" + +#. module: base +#: field:res.users,id:0 +msgid "ID" +msgstr "" + +#. module: base +#: field:ir.cron,doall:0 +msgid "Repeat Missed" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_import.py:69 +#, python-format +msgid "Can not create the module file: %s !" +msgstr "" + +#. module: base +#: field:ir.server.object.lines,server_id:0 +msgid "Object Mapping" +msgstr "" + +#. module: base +#: field:ir.ui.view,xml_id:0 +msgid "External ID" +msgstr "" + +#. module: base +#: help:res.currency.rate,rate:0 +msgid "The rate of the currency to the currency of rate 1" +msgstr "" + +#. module: base +#: model:res.country,name:base.uk +msgid "United Kingdom" +msgstr "" + +#. module: base +#: view:res.config:0 +msgid "res_config_contents" +msgstr "" + +#. module: base +#: help:res.partner.category,active:0 +msgid "The active field allows you to hide the category without removing it." +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Object:" +msgstr "" + +#. module: base +#: model:res.country,name:base.bw +msgid "Botswana" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_title_partner +#: model:ir.ui.menu,name:base.menu_partner_title_partner +#: view:res.partner.title:0 +msgid "Partner Titles" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,auto_refresh:0 +msgid "Add an auto-refresh on the view" +msgstr "" + +#. module: base +#: help:res.partner,employee:0 +msgid "Check this box if the partner is an Employee." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_crm_profiling +msgid "Customer Profiling" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_project_issue +msgid "Issues Tracker" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Work Days" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_multi_company +msgid "Multi-Company" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_rml_content:0 +#: field:ir.actions.report.xml,report_rml_content_data:0 +msgid "RML content" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_workitem_form +#: model:ir.ui.menu,name:base.menu_workflow_workitem +msgid "Workitems" +msgstr "" + +#. module: base +#: code:addons/orm.py:1300 +#, python-format +msgid "" +"Please check that all your lines have %d columns.Stopped around line %d " +"having %d columns." +msgstr "" + +#. module: base +#: field:base.language.export,advice:0 +msgid "Advice" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Header/Footer of Reports" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:746 +#: view:res.users:0 +#, python-format +msgid "Applications" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_attachment +msgid "ir.attachment" +msgstr "" + +#. module: base +#: code:addons/orm.py:4086 +#, python-format +msgid "" +"You cannot perform this operation. New Record Creation is not allowed for " +"this object as this object is for reporting purpose." +msgstr "" + +#. module: base +#: help:ir.model.fields,translate:0 +msgid "" +"Whether values for this field can be translated (enables the translation " +"mechanism for that field)" +msgstr "" + +#. module: base +#: selection:res.currency,position:0 +msgid "After Amount" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Lithuanian / Lietuvių kalba" +msgstr "" + +#. module: base +#: help:ir.actions.server,record_id:0 +msgid "" +"Provide the field name where the record id is stored after the create " +"operations. If it is empty, you can not track the new record." +msgstr "" + +#. module: base +#: help:ir.model.fields,relation:0 +msgid "For relationship fields, the technical name of the target model" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Indonesian / Bahasa Indonesia" +msgstr "" + +#. module: base +#: help:base.language.import,overwrite:0 +msgid "" +"If you enable this option, existing translations (including custom ones) " +"will be overwritten and replaced by those in this file" +msgstr "" + +#. module: base +#: field:ir.ui.view,inherit_id:0 +msgid "Inherited View" +msgstr "" + +#. module: base +#: view:ir.translation:0 +msgid "Source Term" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr_timesheet_sheet +msgid "Timesheets Validation" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_main_pm +msgid "Project" +msgstr "" + +#. module: base +#: field:ir.ui.menu,web_icon_hover_data:0 +msgid "Web Icon Image (hover)" +msgstr "" + +#. module: base +#: view:base.module.import:0 +msgid "Module file successfully imported!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ws +msgid "Samoa" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,name:0 +#: field:publisher_warranty.contract.wizard,name:0 +msgid "Serial Key" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr_timesheet +msgid "Timesheets" +msgstr "" + +#. module: base +#: field:res.partner,function:0 +msgid "function" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_audit +msgid "Audit" +msgstr "" + +#. module: base +#: help:ir.values,company_id:0 +msgid "If set, action binding only applies for this company" +msgstr "" + +#. module: base +#: model:res.country,name:base.lc +msgid "Saint Lucia" +msgstr "" + +#. module: base +#: help:res.users,new_password:0 +msgid "" +"Specify a value only when creating a user or if you're changing the user's " +"password, otherwise leave empty. After a change of password, the user has to " +"login again." +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Maintenance Contract" +msgstr "" + +#. module: base +#: model:res.groups,name:base.group_user +#: field:res.partner,employee:0 +msgid "Employee" +msgstr "" + +#. module: base +#: field:ir.model.access,perm_create:0 +msgid "Create Access" +msgstr "" + +#. module: base +#: field:res.bank,state:0 +#: field:res.company,state_id:0 +#: field:res.partner.address,state_id:0 +#: field:res.partner.bank,state_id:0 +msgid "Fed. State" +msgstr "" + +#. module: base +#: field:ir.actions.server,copy_object:0 +msgid "Copy Of" +msgstr "" + +#. module: base +#: field:ir.model,osv_memory:0 +msgid "In-memory model" +msgstr "" + +#. module: base +#: view:partner.clear.ids:0 +msgid "Clear Ids" +msgstr "" + +#. module: base +#: view:res.partner:0 +#: view:res.partner.address:0 +msgid "Edit" +msgstr "" + +#. module: base +#: field:ir.actions.client,params:0 +msgid "Supplementary arguments" +msgstr "" + +#. module: base +#: field:res.users,view:0 +msgid "Interface" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Field Mapping" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Refresh Validation Dates" +msgstr "" + +#. module: base +#: field:ir.model.fields,ttype:0 +msgid "Field Type" +msgstr "" + +#. module: base +#: field:res.country.state,code:0 +msgid "State Code" +msgstr "" + +#. module: base +#: field:ir.model.fields,on_delete:0 +msgid "On delete" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_multilang +msgid "Multi Language Chart of Accounts" +msgstr "" + +#. module: base +#: selection:res.lang,direction:0 +msgid "Left-to-Right" +msgstr "" + +#. module: base +#: view:res.lang:0 +#: field:res.lang,translatable:0 +msgid "Translatable" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_analytic +msgid "" +"\n" +"Module for defining analytic accounting object.\n" +"===============================================\n" +"\n" +"In OpenERP, analytic accounts are linked to general accounts but are " +"treated\n" +"totally independently. So you can enter various different analytic " +"operations\n" +"that have no counterpart in the general financial accounts.\n" +" " +msgstr "" + +#. module: base +#: field:res.users,signature:0 +msgid "Signature" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_crm_caldav +msgid "Meetings Synchronization" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,context:0 +#: field:ir.filters,context:0 +msgid "Context Value" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_widget_user +msgid "res.widget.user" +msgstr "" + +#. module: base +#: field:res.partner.category,complete_name:0 +msgid "Full Name" +msgstr "" + +#. module: base +#: view:base.module.configuration:0 +msgid "_Ok" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:238 +#, python-format +msgid "The name of the module must be unique !" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_contact +msgid "Contacts Management" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_fr_rib +msgid "" +"\n" +"This module lets users enter the banking details of Partners in the RIB " +"format (French standard for bank accounts details).\n" +"RIB Bank Accounts can be entered in the \"Accounting\" tab of the Partner " +"form by specifying the account type \"RIB\". The four standard RIB fields " +"will then become mandatory:\n" +"- Bank Code\n" +"- Office Code\n" +"- Account number\n" +"- RIB key\n" +"As a safety measure, OpenERP will check the RIB key whenever a RIB is saved, " +"and will refuse to record the data if the key is incorrect. Please bear in " +"mind that this can only happen when the user presses the \"save\" button, " +"for example on the Partner Form.\n" +"Since each bank account may relate to a Bank, users may enter the RIB Bank " +"Code in the Bank form - it will the pre-fill the Bank Code on the RIB when " +"they select the Bank. \n" +"To make this easier, this module will also let users find Banks using their " +"RIB code.\n" +"\n" +"The module base_iban can be a useful addition to this module, because French " +"banks are now progressively adopting the international IBAN format instead " +"of the RIB format.\n" +"The RIB and IBAN codes for a single account can be entered by recording two " +"Bank Accounts in OpenERP: the first with the type \"RIB\", the second with " +"the type \"IBAN\". \n" +msgstr "" + +#. module: base +#: view:ir.property:0 +msgid "Parameters that are used by all resources." +msgstr "" + +#. module: base +#: model:res.country,name:base.mz +msgid "Mozambique" +msgstr "" + +#. module: base +#: help:ir.values,action_id:0 +msgid "" +"Action bound to this entry - helper field for binding an action, will " +"automatically set the correct reference" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_project_long_term +msgid "Long Term Planning" +msgstr "" + +#. module: base +#: field:ir.actions.server,message:0 +#: field:partner.massmail.wizard,text:0 +#: view:partner.sms.send:0 +#: field:res.log,name:0 +msgid "Message" +msgstr "" + +#. module: base +#: field:ir.actions.act_window.view,multi:0 +msgid "On Multiple Doc." +msgstr "" + +#. module: base +#: view:res.partner:0 +#: field:res.partner,user_id:0 +msgid "Salesman" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_accountant +msgid "Accounting and Finance" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:429 +#: view:ir.module.module:0 +#, python-format +msgid "Upgrade" +msgstr "" + +#. module: base +#: field:res.partner,address:0 +#: view:res.partner.address:0 +msgid "Contacts" +msgstr "" + +#. module: base +#: model:res.country,name:base.fo +msgid "Faroe Islands" +msgstr "" + +#. module: base +#: field:ir.mail_server,smtp_encryption:0 +msgid "Connection Security" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:653 +#, python-format +msgid "Please specify an action to launch !" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_us +msgid "" +"\n" +" United States - Chart of accounts\n" +" " +msgstr "" + +#. module: base +#: view:res.widget.wizard:0 +msgid "Add" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_ec +msgid "Ecuador - Accounting" +msgstr "" + +#. module: base +#: field:res.partner.category,name:0 +msgid "Category Name" +msgstr "" + +#. module: base +#: view:res.widget:0 +msgid "Widgets" +msgstr "" + +#. module: base +#: model:res.country,name:base.cz +msgid "Czech Republic" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr +msgid "" +"\n" +"Module for human resource management.\n" +"=====================================\n" +"\n" +"You can manage:\n" +" * Employees and hierarchies : You can define your employee with User and " +"display hierarchies\n" +" * HR Departments\n" +" * HR Jobs\n" +" " +msgstr "" + +#. module: base +#: view:res.widget.wizard:0 +msgid "Widget Wizard" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_hn +msgid "Honduras - Accounting" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_report_intrastat +msgid "Intrastat Reporting" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:222 +#, python-format +msgid "" +"Please use the change password wizard (in User Preferences or User menu) to " +"change your own password." +msgstr "" + +#. module: base +#: code:addons/orm.py:1883 +#, python-format +msgid "Insufficient fields for Calendar View!" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Integer" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Hindi / हिंदी" +msgstr "" + +#. module: base +#: help:res.users,company_id:0 +msgid "The company this user is currently working for." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_wizard_ir_model_menu_create +msgid "wizard.ir.model.menu.create" +msgstr "" + +#. module: base +#: view:workflow.transition:0 +msgid "Transition" +msgstr "" + +#. module: base +#: field:ir.cron,active:0 +#: field:ir.sequence,active:0 +#: field:res.bank,active:0 +#: field:res.currency,active:0 +#: field:res.lang,active:0 +#: field:res.partner,active:0 +#: field:res.partner.address,active:0 +#: field:res.partner.category,active:0 +#: field:res.request,active:0 +#: field:res.users,active:0 +#: view:workflow.instance:0 +#: view:workflow.workitem:0 +msgid "Active" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_ma +msgid "Maroc - Accounting" +msgstr "" + +#. module: base +#: model:res.country,name:base.mn +msgid "Mongolia" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Created Menus" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_analytic_default +msgid "Account Analytic Defaults" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr_contract +msgid "" +"\n" +"Add all information on the employee form to manage contracts.\n" +"=============================================================\n" +"\n" +" * Marital status,\n" +" * Security number,\n" +" * Place of birth, birth date, ...\n" +"\n" +"You can assign several contracts per employee.\n" +" " +msgstr "" + +#. module: base +#: selection:ir.ui.view,type:0 +msgid "mdx" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_sale_crm +msgid "" +"\n" +"This module adds a shortcut on one or several opportunity cases in the CRM.\n" +"===========================================================================\n" +"\n" +"This shortcut allows you to generate a sales order based on the selected " +"case.\n" +"If different cases are open (a list), it generates one sale order by\n" +"case.\n" +"The case is then closed and linked to the generated sales order.\n" +"\n" +"We suggest you to install this module if you installed both the sale and " +"the\n" +"crm modules.\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.bi +msgid "Burundi" +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: view:base.module.import:0 +#: view:base.module.update:0 +#: view:publisher_warranty.contract.wizard:0 +#: view:res.request:0 +msgid "Close" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (MX) / Español (MX)" +msgstr "" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:145 +#, python-format +msgid "Please verify your publisher warranty serial number and validity." +msgstr "" + +#. module: base +#: view:res.log:0 +msgid "My Logs" +msgstr "" + +#. module: base +#: model:res.country,name:base.bt +msgid "Bhutan" +msgstr "" + +#. module: base +#: help:ir.sequence,number_next:0 +msgid "Next number of this sequence" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_11 +msgid "Textile Suppliers" +msgstr "" + +#. module: base +#: selection:ir.actions.url,target:0 +msgid "This Window" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Publisher Warranty Contracts" +msgstr "" + +#. module: base +#: help:res.log,name:0 +msgid "The logging message." +msgstr "" + +#. module: base +#: field:base.language.export,format:0 +msgid "File Format" +msgstr "" + +#. module: base +#: field:res.lang,iso_code:0 +msgid "ISO code" +msgstr "" + +#. module: base +#: view:res.log:0 +#: field:res.log,read:0 +msgid "Read" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_association +msgid "Associations Management" +msgstr "" + +#. module: base +#: help:ir.model,modules:0 +msgid "List of modules in which the object is defined or inherited" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr_payroll +msgid "Payroll" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_country_state +msgid "" +"If you are working on the American market, you can manage the different " +"federal states you are working on from here. Each state is attached to one " +"country." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_delivery +msgid "" +"\n" +"Allows you to add delivery methods in sale orders and picking.\n" +"==============================================================\n" +"\n" +"You can define your own carrier and delivery grids for prices.\n" +"When creating invoices from picking, OpenERP is able to add and compute the " +"shipping line.\n" +"\n" +" " +msgstr "" + +#. module: base +#: view:workflow.workitem:0 +msgid "Workflow Workitems" +msgstr "" + +#. module: base +#: model:res.country,name:base.vc +msgid "Saint Vincent & Grenadines" +msgstr "" + +#. module: base +#: field:ir.mail_server,smtp_pass:0 +#: field:partner.sms.send,password:0 +#: field:res.users,password:0 +msgid "Password" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_anglo_saxon +msgid "" +"\n" +"This module supports the Anglo-Saxon accounting methodology by changing the " +"accounting logic with stock transactions.\n" +"=============================================================================" +"========================================\n" +"\n" +"The difference between the Anglo-Saxon accounting countries\n" +"and the Rhine or also called Continental accounting countries is the moment " +"of taking the Cost of Goods Sold versus Cost of Sales.\n" +"Anglo-Saxons accounting does take the cost when sales invoice is created, " +"Continental accounting will take the cost at the moment the goods are " +"shipped.\n" +"This module will add this functionality by using a interim account, to store " +"the value of shipped goods and will contra book this interim account\n" +"when the invoice is created to transfer this amount to the debtor or " +"creditor account.\n" +"Secondly, price differences between actual purchase price and fixed product " +"standard price are booked on a separate account" +msgstr "" + +#. module: base +#: field:res.partner,title:0 +msgid "Partner Firm" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_model_fields +#: view:ir.model:0 +#: field:ir.model,field_id:0 +#: model:ir.model,name:base.model_ir_model_fields +#: view:ir.model.fields:0 +#: model:ir.ui.menu,name:base.ir_model_model_fields +msgid "Fields" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_employee_form +msgid "Employees" +msgstr "" + +#. module: base +#: field:ir.exports.line,name:0 +#: field:ir.translation,name:0 +#: field:res.partner.bank.type.field,name:0 +msgid "Field Name" +msgstr "" + +#. module: base +#: help:res.log,read:0 +msgid "" +"If this log item has been read, get() should not send it to the client" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_uservoice +msgid "" +"\n" +"Add Feedback button in header.\n" +"==============================\n" +"\n" +"Invite OpenERP user feedback, powered by uservoice.\n" +" " +msgstr "" + +#. module: base +#: field:res.company,rml_header2:0 +#: field:res.company,rml_header3:0 +msgid "RML Internal Header" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,search_view_id:0 +msgid "Search View Ref." +msgstr "" + +#. module: base +#: field:ir.module.module,installed_version:0 +msgid "Latest version" +msgstr "" + +#. module: base +#: view:ir.mail_server:0 +msgid "Test Connection" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_address_form +#: model:ir.ui.menu,name:base.menu_partner_address_form +msgid "Addresses" +msgstr "" + +#. module: base +#: model:res.country,name:base.mm +msgid "Myanmar" +msgstr "" + +#. module: base +#: help:ir.model.fields,modules:0 +msgid "List of modules in which the field is defined" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Chinese (CN) / 简体中文" +msgstr "" + +#. module: base +#: field:res.bank,street:0 +#: field:res.company,street:0 +#: field:res.partner.address,street:0 +#: field:res.partner.bank,street:0 +msgid "Street" +msgstr "" + +#. module: base +#: model:res.country,name:base.yu +msgid "Yugoslavia" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_purchase_double_validation +msgid "" +"\n" +"Double-validation for purchases exceeding minimum amount.\n" +"=========================================================\n" +"\n" +"This module modifies the purchase workflow in order to validate purchases\n" +"that exceeds minimum amount set by configuration wizard.\n" +" " +msgstr "" + +#. module: base +#: field:res.currency,rounding:0 +msgid "Rounding Factor" +msgstr "" + +#. module: base +#: model:res.country,name:base.ca +msgid "Canada" +msgstr "" + +#. module: base +#: code:addons/base/res/res_company.py:158 +#, python-format +msgid "Reg: " +msgstr "" + +#. module: base +#: help:res.currency.rate,currency_rate_type_id:0 +msgid "" +"Allow you to define your own currency rate types, like 'Average' or 'Year to " +"Date'. Leave empty if you simply want to use the normal 'spot' rate type" +msgstr "" + +#. module: base +#: selection:ir.module.module.dependency,state:0 +msgid "Unknown" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_users_my +msgid "Change My Preferences" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:167 +#, python-format +msgid "Invalid model name in the action definition." +msgstr "" + +#. module: base +#: field:partner.sms.send,text:0 +msgid "SMS Message" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_ro +msgid "" +"\n" +"This is the module to manage the accounting chart, VAT structure and " +"Registration Number for Romania in OpenERP.\n" +"=============================================================================" +"===================================\n" +"\n" +"Romanian accounting chart and localization.\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.cm +msgid "Cameroon" +msgstr "" + +#. module: base +#: model:res.country,name:base.bf +msgid "Burkina Faso" +msgstr "" + +#. module: base +#: selection:ir.model.fields,state:0 +msgid "Custom Field" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project_retro_planning +msgid "" +"\n" +"Changes dates according to change in project End Date.\n" +"======================================================\n" +"\n" +"If end date of project is changed then the deadline date and start date for " +"all the tasks will change accordingly.\n" +" " +msgstr "" + +#. module: base +#: help:res.users,view:0 +msgid "" +"OpenERP offers a simplified and an extended user interface. If you use " +"OpenERP for the first time we strongly advise you to select the simplified " +"interface, which has less features but is easier to use. You can switch to " +"the other interface from the User/Preferences menu at any time." +msgstr "" + +#. module: base +#: model:res.country,name:base.cc +msgid "Cocos (Keeling) Islands" +msgstr "" + +#. module: base +#: selection:base.language.install,state:0 +#: selection:base.module.import,state:0 +#: selection:base.module.update,state:0 +msgid "init" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "11. %U or %W ==> 48 (49th week)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_bank_type_field +msgid "Bank type fields" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Dutch / Nederlands" +msgstr "" + +#. module: base +#: selection:res.company,paper_format:0 +msgid "US Letter" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_stock_location +msgid "" +"\n" +"This module supplements the Warehouse application by effectively " +"implementing Push and Pull inventory flows.\n" +"=============================================================================" +"===============================\n" +"\n" +"Typically this could be used to:\n" +" * Manage product manufacturing chains\n" +" * Manage default locations per product\n" +" * Define routes within your warehouse according to business needs, such " +"as:\n" +" - Quality Control\n" +" - After Sales Services\n" +" - Supplier Returns\n" +"\n" +" * Help rental management, by generating automated return moves for " +"rented products\n" +"\n" +"Once this module is installed, an additional tab appear on the product form, " +"where you can add\n" +"Push and Pull flow specifications. The demo data of CPU1 product for that " +"push/pull :\n" +"\n" +"Push flows\n" +"----------\n" +"Push flows are useful when the arrival of certain products in a given " +"location should always\n" +"be followed by a corresponding move to another location, optionally after a " +"certain delay.\n" +"The original Warehouse application already supports such Push flow " +"specifications on the\n" +"Locations themselves, but these cannot be refined per-product.\n" +"\n" +"A push flow specification indicates which location is chained with which " +"location, and with\n" +"what parameters. As soon as a given quantity of products is moved in the " +"source location,\n" +"a chained move is automatically foreseen according to the parameters set on " +"the flow specification\n" +"(destination location, delay, type of move, journal, etc.) The new move can " +"be automatically\n" +"processed, or require a manual confirmation, depending on the parameters.\n" +"\n" +"Pull flows\n" +"----------\n" +"Pull flows are a bit different from Push flows, in the sense that they are " +"not related to\n" +"the processing of product moves, but rather to the processing of procurement " +"orders.\n" +"What is being pulled is a need, not directly products.\n" +"A classical example of Pull flow is when you have an Outlet company, with a " +"parent Company\n" +"that is responsible for the supplies of the Outlet.\n" +"\n" +" [ Customer ] <- A - [ Outlet ] <- B - [ Holding ] <~ C ~ [ Supplier ]\n" +"\n" +"When a new procurement order (A, coming from the confirmation of a Sale " +"Order for example) arrives\n" +"in the Outlet, it is converted into another procurement (B, via a Pull flow " +"of type 'move')\n" +"requested from the Holding. When procurement order B is processed by the " +"Holding company, and\n" +"if the product is out of stock, it can be converted into a Purchase Order " +"(C) from the Supplier\n" +"(Pull flow of type Purchase). The result is that the procurement order, the " +"need, is pushed\n" +"all the way between the Customer and Supplier.\n" +"\n" +"Technically, Pull flows allow to process procurement orders differently, not " +"only depending on\n" +"the product being considered, but also depending on which location holds the " +"\"need\" for that\n" +"product (i.e. the destination location of that procurement order).\n" +"\n" +"Use-Case\n" +"--------\n" +"\n" +"You can use the demo data as follow:\n" +" CPU1: Sell some CPU1 from Shop 1 and run the scheduler\n" +" - Warehouse: delivery order, Shop 1: reception\n" +" CPU3:\n" +" - When receiving the product, it goes to Quality Control location then " +"stored to shelf 2.\n" +" - When delivering the customer: Pick List -> Packing -> Delivery Order " +"from Gate A\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_marketing +msgid "" +"\n" +"Menu for Marketing.\n" +"===================\n" +"\n" +"Contains the installer for marketing-related modules.\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_knowledge_management +msgid "Knowledge Management" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.bank_account_update +msgid "Company Bank Accounts" +msgstr "" + +#. module: base +#: help:ir.mail_server,smtp_pass:0 +msgid "Optional password for SMTP authentication" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project_mrp +msgid "" +"\n" +"Automatically creates project tasks from procurement lines\n" +"==========================================================\n" +"\n" +"This module will automatically create a new task for each procurement\n" +"order line (e.g. for sale order lines), if the corresponding product\n" +"meets the following characteristics:\n" +"\n" +" * Type = Service\n" +" * Procurement method (Order fulfillment) = MTO (make to order)\n" +" * Supply/Procurement method = Produce\n" +"\n" +"If on top of that a projet is specified on the product form (in the " +"Procurement\n" +"tab), then the new task will be created in that specific project.\n" +"Otherwise, the new task will not belong to any project, and may be added to " +"a\n" +"project manually later.\n" +"\n" +"When the project task is completed or cancelled, the workflow of the " +"corresponding\n" +"procurement line is updated accordingly. For example if this procurement " +"corresponds\n" +"to a sale order line, the sale order line will be considered delivered when " +"the\n" +"task is completed.\n" +"\n" +msgstr "" + +#. module: base +#: code:addons/base/res/res_config.py:348 +#, python-format +msgid "" +"\n" +"\n" +"This addon is already installed on your system" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_check_writing +msgid "" +"\n" +" Module for the Check writing and check printing \n" +" " +msgstr "" + +#. module: base +#: model:res.partner.bank.type,name:base.bank_normal +msgid "Normal Bank Account" +msgstr "" + +#. module: base +#: view:ir.actions.wizard:0 +#: field:wizard.ir.model.menu.create.line,wizard_id:0 +msgid "Wizard" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project_mailgate +msgid "" +"\n" +"This module can automatically create Project Tasks based on incoming emails\n" +"===========================================================================\n" +"\n" +"Allows creating tasks based on new emails arriving at a given mailbox,\n" +"similarly to what the CRM application has for Leads/Opportunities.\n" +"There are two common alternatives to configure the mailbox integration:\n" +"\n" +" * Install the ``fetchmail`` module and configure a new mailbox, then " +"select\n" +" ``Project Tasks`` as the target for incoming emails.\n" +" * Set it up manually on your mail server based on the 'mail gateway' " +"script\n" +" provided in the ``mail`` module - and connect it to the `project.task` " +"model.\n" +"\n" +"\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_membership +msgid "" +"\n" +"This module allows you to manage all operations for managing memberships.\n" +"=========================================================================\n" +"\n" +"It supports different kind of members:\n" +"* Free member\n" +"* Associated member (eg.: a group subscribes to a membership for all " +"subsidiaries)\n" +"* Paid members,\n" +"* Special member prices, ...\n" +"\n" +"It is integrated with sales and accounting to allow you to automatically\n" +"invoice and send propositions for membership renewal.\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr_attendance +msgid "" +"\n" +"This module aims to manage employee's attendances.\n" +"==================================================\n" +"\n" +"Keeps account of the attendances of the employees on the basis of the\n" +"actions(Sign in/Sign out) performed by them.\n" +" " +msgstr "" + +#. module: base +#: field:ir.module.module,maintainer:0 +msgid "Maintainer" +msgstr "" + +#. module: base +#: field:ir.sequence,suffix:0 +msgid "Suffix" +msgstr "" + +#. module: base +#: model:res.country,name:base.mo +msgid "Macau" +msgstr "" + +#. module: base +#: model:ir.actions.report.xml,name:base.res_partner_address_report +msgid "Labels" +msgstr "" + +#. module: base +#: field:partner.massmail.wizard,email_from:0 +msgid "Sender's email" +msgstr "" + +#. module: base +#: field:ir.default,field_name:0 +msgid "Object Field" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PE) / Español (PE)" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "French (CH) / Français (CH)" +msgstr "" + +#. module: base +#: help:ir.actions.server,subject:0 +msgid "" +"Email subject, may contain expressions enclosed in double brackets based on " +"the same values as those available in the condition field, e.g. `Hello [[ " +"object.partner_id.name ]]`" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_sequence +msgid "" +"\n" +"This module maintains internal sequence number for accounting entries.\n" +"======================================================================\n" +"\n" +"Allows you to configure the accounting sequences to be maintained.\n" +"\n" +"You can customize the following attributes of the sequence:\n" +" * Prefix\n" +" * Suffix\n" +" * Next Number\n" +" * Increment Number\n" +" * Number Padding\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.to +msgid "Tonga" +msgstr "" + +#. module: base +#: help:ir.model.fields,serialization_field_id:0 +msgid "" +"If set, this field will be stored in the sparse structure of the " +"serialization field, instead of having its own database column. This cannot " +"be changed after creation." +msgstr "" + +#. module: base +#: view:res.partner.bank:0 +msgid "Bank accounts belonging to one of your companies" +msgstr "" + +#. module: base +#: help:res.users,action_id:0 +msgid "" +"If specified, this action will be opened at logon for this user, in addition " +"to the standard menu." +msgstr "" + +#. module: base +#: selection:ir.module.module,complexity:0 +msgid "Easy" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Client Actions" +msgstr "" + +#. module: base +#: help:ir.actions.server,trigger_obj_id:0 +msgid "" +"The field on the current object that links to the target object record (must " +"be a many2one, or an integer field with the record ID)" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:423 +#, python-format +msgid "" +"You try to upgrade a module that depends on the module: %s.\n" +"But this module is not available in your system." +msgstr "" + +#. module: base +#: field:workflow.transition,act_to:0 +msgid "Destination Activity" +msgstr "" + +#. module: base +#: help:res.currency,position:0 +msgid "" +"Determines where the currency symbol should be placed after or before the " +"amount." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_update_translations +msgid "base.update.translations" +msgstr "" + +#. module: base +#: field:res.partner.category,parent_id:0 +msgid "Parent Category" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Integer Big" +msgstr "" + +#. module: base +#: selection:res.partner.address,type:0 +#: selection:res.partner.title,domain:0 +msgid "Contact" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_at +msgid "Austria - Accounting" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_menu +msgid "ir.ui.menu" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_project_management +#: model:ir.module.module,shortdesc:base.module_project +msgid "Project Management" +msgstr "" + +#. module: base +#: model:res.country,name:base.us +msgid "United States" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_crm_fundraising +msgid "Fundraising" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Cancel Uninstall" +msgstr "" + +#. module: base +#: view:res.bank:0 +#: view:res.partner:0 +#: view:res.partner.address:0 +msgid "Communication" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_analytic +msgid "Analytic Accounting" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "RML Report" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_server_object_lines +msgid "ir.server.object.lines" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_be +msgid "Belgium - Accounting" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:622 +#, python-format +msgid "Module %s: Invalid Quality Certificate" +msgstr "" + +#. module: base +#: model:res.country,name:base.kw +msgid "Kuwait" +msgstr "" + +#. module: base +#: field:workflow.workitem,inst_id:0 +msgid "Instance" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,attachment:0 +msgid "" +"This is the filename of the attachment used to store the printing result. " +"Keep empty to not save the printed reports. You can use a python expression " +"with the object and time variables." +msgstr "" + +#. module: base +#: sql_constraint:ir.model.data:0 +msgid "" +"You cannot have multiple records with the same external ID in the same " +"module!" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Many2One" +msgstr "" + +#. module: base +#: model:res.country,name:base.ng +msgid "Nigeria" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_crm_caldav +msgid "" +"\n" +"Caldav features in Meeting.\n" +"===========================\n" +"\n" +" * Share meeting with other calendar clients like sunbird\n" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_iban +msgid "IBAN Bank Accounts" +msgstr "" + +#. module: base +#: field:res.company,user_ids:0 +msgid "Accepted Users" +msgstr "" + +#. module: base +#: field:ir.ui.menu,web_icon_data:0 +msgid "Web Icon Image" +msgstr "" + +#. module: base +#: field:ir.actions.server,wkf_model_id:0 +msgid "Target Object" +msgstr "" + +#. module: base +#: selection:ir.model.fields,select_level:0 +msgid "Always Searchable" +msgstr "" + +#. module: base +#: model:res.country,name:base.hk +msgid "Hong Kong" +msgstr "" + +#. module: base +#: field:ir.default,ref_id:0 +msgid "ID Ref." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_address_form +msgid "" +"Customers (also called Partners in other areas of the system) helps you " +"manage your address book of companies whether they are prospects, customers " +"and/or suppliers. The partner form allows you to track and record all the " +"necessary information to interact with your partners from the company " +"address to their contacts as well as pricelists, and much more. If you " +"installed the CRM, with the history tab, you can track all the interactions " +"with a partner such as opportunities, emails, or sales orders issued." +msgstr "" + +#. module: base +#: model:res.country,name:base.ph +msgid "Philippines" +msgstr "" + +#. module: base +#: model:res.country,name:base.ma +msgid "Morocco" +msgstr "" + +#. module: base +#: help:ir.values,model_id:0 +msgid "" +"Model to which this entry applies - helper field for setting a model, will " +"automatically set the correct model name" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "2. %a ,%A ==> Fri, Friday" +msgstr "" + +#. module: base +#: view:res.request.history:0 +msgid "Request History" +msgstr "" + +#. module: base +#: help:ir.rule,global:0 +msgid "If no group is specified the rule is global and applied to everyone" +msgstr "" + +#. module: base +#: model:res.country,name:base.td +msgid "Chad" +msgstr "" + +#. module: base +#: help:ir.cron,priority:0 +msgid "" +"The priority of the job, as an integer: 0 means higher priority, 10 means " +"lower priority." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_transition +msgid "workflow.transition" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%a - Abbreviated weekday name." +msgstr "" + +#. module: base +#: view:ir.ui.menu:0 +msgid "Submenus" +msgstr "" + +#. module: base +#: model:res.groups,name:base.group_extended +msgid "Extended View" +msgstr "" + +#. module: base +#: model:res.country,name:base.pf +msgid "Polynesia (French)" +msgstr "" + +#. module: base +#: model:res.country,name:base.dm +msgid "Dominica" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_module_record +msgid "Record and Create Modules" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_partner_sms_send +#: view:partner.sms.send:0 +msgid "Send SMS" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr_holidays +msgid "" +"\n" +"This module allows you to manage leaves and leaves' requests.\n" +"=============================================================\n" +"\n" +"Implements a dashboard for human resource management that includes.\n" +" * Leaves\n" +"\n" +"Note that:\n" +" - A synchronisation with an internal agenda (use of the CRM module) is " +"possible: in order to automatically create a case when an holiday request is " +"accepted, you have to link the holidays status to a case section. You can " +"set up this info and your colour preferences in\n" +" Human Resources/Configuration/Holidays/Leave Type\n" +" - An employee can make an ask for more off-days by making a new " +"Allocation It will increase his total of that leave type available (if the " +"request is accepted).\n" +" - There are two ways to print the employee's holidays:\n" +" * The first will allow to choose employees by department and is used " +"by clicking the menu item located in\n" +" Human Resources/Reporting/Holidays/Leaves by Department\n" +" * The second will allow you to choose the holidays report for " +"specific employees. Go on the list\n" +" Human Resources/Human Resources/Employees\n" +" then select the ones you want to choose, click on the print " +"icon and select the option\n" +" 'Employee's Holidays'\n" +" - The wizard allows you to choose if you want to print either the " +"Confirmed & Validated holidays or only the Validated ones. These states must " +"be set up by a user from the group 'HR'. You can define these features in " +"the security tab from the user data in\n" +" Administration / Users / Users\n" +" for example, you maybe will do it for the user 'admin'.\n" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_xsl:0 +msgid "XSL path" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_invoice_layout +msgid "Invoice Layouts" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_stock_location +msgid "Advanced Routes" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_pad +msgid "Collaborative Pads" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_anglo_saxon +msgid "Anglo-Saxon Accounting" +msgstr "" + +#. module: base +#: model:res.country,name:base.np +msgid "Nepal" +msgstr "" + +#. module: base +#: help:res.groups,implied_ids:0 +msgid "Users of this group automatically inherit those groups" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr_attendance +msgid "Attendances" +msgstr "" + +#. module: base +#: field:ir.module.category,visible:0 +msgid "Visible" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_ui_view_custom +#: model:ir.ui.menu,name:base.menu_action_ui_view_custom +#: view:ir.ui.view.custom:0 +msgid "Customized Views" +msgstr "" + +#. module: base +#: view:partner.sms.send:0 +msgid "Bulk SMS send" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_wiki_quality_manual +msgid "" +"\n" +"Quality Manual Template.\n" +"========================\n" +"\n" +"It provides demo data, thereby creating a Wiki Group and a Wiki Page\n" +"for Wiki Quality Manual.\n" +" " +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_values_form_action +#: model:ir.ui.menu,name:base.menu_values_form_action +#: view:ir.values:0 +msgid "Action Bindings" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Seconde: %(sec)s" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_view_base_module_update +msgid "Update Modules List" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:295 +#, python-format +msgid "" +"Unable to upgrade module \"%s\" because an external dependency is not met: %s" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account +msgid "eInvoicing" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_association +msgid "" +"\n" +"This module is to configure modules related to an association.\n" +"==============================================================\n" +"\n" +"It installs the profile for associations to manage events, registrations, " +"memberships, membership products (schemes), etc.\n" +" " +msgstr "" + +#. module: base +#: code:addons/orm.py:2693 +#, python-format +msgid "The value \"%s\" for the field \"%s.%s\" is not in the selection" +msgstr "" + +#. module: base +#: view:ir.actions.configuration.wizard:0 +msgid "Continue" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Thai / ภาษาไทย" +msgstr "" + +#. module: base +#: code:addons/orm.py:343 +#, python-format +msgid "Object %s does not exists" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%j - Day of the year [001,366]." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Slovenian / slovenščina" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_wiki +msgid "Wiki" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_de +msgid "" +"\n" +"Dieses Modul beinhaltet einen deutschen Kontenrahmen basierend auf dem " +"SKR03.\n" +"=============================================================================" +"=\n" +"\n" +"German accounting chart and localization.\n" +" " +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,attachment_use:0 +msgid "Reload from Attachment" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Hide technical modules" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_procurement +msgid "" +"\n" +"This is the module for computing Procurements.\n" +"==============================================\n" +"\n" +"In the MRP process, procurements orders are created to launch manufacturing\n" +"orders, purchase orders, stock allocations, etc. Procurement orders are\n" +"generated automatically by the system and unless there is a problem, the\n" +"user will not be notified. In case of problems, the system will raise some\n" +"procurement exceptions to inform the user about blocking problems that need\n" +"to be resolved manually (like, missing BoM structure or missing supplier).\n" +"\n" +"The procurement order will schedule a proposal for automatic procurement\n" +"for the product which needs replenishment. This procurement will start a\n" +"task, either a purchase order form for the supplier, or a production order\n" +"depending on the product's configuration.\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.mx +msgid "Mexico" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:414 +#, python-format +msgid "Missing SMTP Server" +msgstr "" + +#. module: base +#: field:ir.attachment,name:0 +msgid "Attachment Name" +msgstr "" + +#. module: base +#: field:base.language.export,data:0 +#: field:base.language.import,data:0 +msgid "File" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade_install +msgid "Module Upgrade Install" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_email_template +msgid "E-Mail Templates" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_configuration_wizard +msgid "ir.actions.configuration.wizard" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_report_webkit +msgid "" +"\n" +"This module adds a new Report Engine based on WebKit library (wkhtmltopdf) " +"to support reports designed in HTML + CSS.\n" +"=============================================================================" +"========================================\n" +"\n" +"The module structure and some code is inspired by the report_openoffice " +"module.\n" +"\n" +"The module allows:\n" +"\n" +" - HTML report definition\n" +" - Multi header support\n" +" - Multi logo\n" +" - Multi company support\n" +" - HTML and CSS-3 support (In the limit of the actual WebKIT version)\n" +" - JavaScript support\n" +" - Raw HTML debugger\n" +" - Book printing capabilities\n" +" - Margins definition\n" +" - Paper size definition\n" +"\n" +"... and much more\n" +"\n" +"Multiple headers and logos can be defined per company.\n" +"CSS style, header and footer body are defined per company.\n" +"\n" +"For a sample report see also the webkit_report_sample module, and this " +"video:\n" +" http://files.me.com/nbessi/06n92k.mov\n" +"\n" +"Requirements and Installation\n" +"-----------------------------\n" +"This module requires the ``wkthtmltopdf`` library to render HTML documents " +"as\n" +"PDF. Version 0.9.9 or later is necessary, and can be found at " +"http://code.google.com/p/wkhtmltopdf/\n" +"for Linux, Mac OS X (i386) and Windows (32bits).\n" +"\n" +"After installing the library on the OpenERP Server machine, you need to set " +"the\n" +"path to the ``wkthtmltopdf`` executable file on each Company.\n" +"\n" +"If you are experiencing missing header/footer problems on Linux, be sure to\n" +"install a \"static\" version of the library. The default ``wkhtmltopdf`` on\n" +"Ubuntu is known to have this issue.\n" +"\n" +"\n" +"TODO\n" +"----\n" +"\n" +" * JavaScript support activation deactivation\n" +" * Collated and book format support\n" +" * Zip return for separated PDF\n" +" * Web client WYSIWYG\n" +"\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_gt +msgid "" +"\n" +"This is the base module to manage the accounting chart for Guatemala.\n" +"=====================================================================\n" +"\n" +"Agrega una nomenclatura contable para Guatemala. También icluye impuestos y " +"la moneda del Quetzal. -- Adds accounting chart for Guatemala. It also " +"includes taxes and the Quetzal currency" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%b - Abbreviated month name." +msgstr "" + +#. module: base +#: field:res.partner,supplier:0 +#: view:res.partner.address:0 +#: field:res.partner.address,is_supplier_add:0 +#: model:res.partner.category,name:base.res_partner_category_8 +msgid "Supplier" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +#: selection:ir.actions.server,state:0 +msgid "Multi Actions" +msgstr "" + +#. module: base +#: view:base.language.export:0 +#: view:base.language.import:0 +#: view:wizard.ir.model.menu.create:0 +msgid "_Close" +msgstr "" + +#. module: base +#: field:multi_company.default,company_dest_id:0 +msgid "Default Company" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (EC) / Español (EC)" +msgstr "" + +#. module: base +#: help:ir.ui.view,xml_id:0 +msgid "ID of the view defined in xml file" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_module_import +msgid "Import Module" +msgstr "" + +#. module: base +#: model:res.country,name:base.as +msgid "American Samoa" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,res_model:0 +msgid "Model name of the object to open in the view window" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_caldav +msgid "" +"\n" +"This module contains basic functionality for Caldav system.\n" +"===========================================================\n" +"\n" +" - Webdav server that provides remote access to calendar\n" +" - Synchronisation of calendar using WebDAV\n" +" - Customize calendar event and todo attribute with any of OpenERP model\n" +" - Provides iCal Import/Export functionality\n" +"\n" +"To access Calendars using CalDAV clients, point them to:\n" +" http://HOSTNAME:PORT/webdav/DATABASE_NAME/calendars/users/USERNAME/c\n" +"\n" +"To access OpenERP Calendar using WebCal to remote site use the URL like:\n" +" http://HOSTNAME:PORT/webdav/DATABASE_NAME/Calendars/CALENDAR_NAME.ics\n" +"\n" +" Where,\n" +" HOSTNAME: Host on which OpenERP server(With webdav) is running\n" +" PORT : Port on which OpenERP server is running (By Default : 8069)\n" +" DATABASE_NAME: Name of database on which OpenERP Calendar is " +"created\n" +" CALENDAR_NAME: Name of calendar to access\n" +msgstr "" + +#. module: base +#: field:ir.model.fields,selectable:0 +msgid "Selectable" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:199 +#, python-format +msgid "Everything seems properly set up!" +msgstr "" + +#. module: base +#: field:res.users,date:0 +msgid "Latest Connection" +msgstr "" + +#. module: base +#: view:res.request.link:0 +msgid "Request Link" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_plugin_outlook +msgid "" +"\n" +"This module provides the Outlook Plug-in.\n" +"=========================================\n" +"Outlook plug-in allows you to select an object that you would like to add\n" +"to your email and its attachments from MS Outlook. You can select a partner, " +"a task,\n" +"a project, an analytical account, or any other object and archive selected\n" +"mail into mail.message with attachments.\n" +" " +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: selection:ir.attachment,type:0 +#: field:ir.module.module,url:0 +msgid "URL" +msgstr "" + +#. module: base +#: help:res.users,context_tz:0 +msgid "" +"The user's timezone, used to output proper date and time values inside " +"printed reports. It is important to set a value for this field. You should " +"use the same timezone that is otherwise used to pick and render date and " +"time values: your computer's timezone." +msgstr "" + +#. module: base +#: help:res.country,name:0 +msgid "The full name of the country." +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Iteration" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_project_planning +msgid "Resources Planing" +msgstr "" + +#. module: base +#: field:ir.module.module,complexity:0 +msgid "Complexity" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window,target:0 +msgid "Inline" +msgstr "" + +#. module: base +#: model:res.partner.bank.type.field,name:base.bank_normal_field_bic +msgid "bank_bic" +msgstr "" + +#. module: base +#: code:addons/orm.py:3988 +#: code:addons/orm.py:4085 +#, python-format +msgid "UserError" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_analytic_default +msgid "" +"Set default values for your analytic accounts\n" +"Allows to automatically select analytic accounts based on criterions:\n" +"=====================================================================\n" +"\n" +"* Product\n" +"* Partner\n" +"* User\n" +"* Company\n" +"* Date\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.ae +msgid "United Arab Emirates" +msgstr "" + +#. module: base +#: code:addons/orm.py:3704 +#, python-format +msgid "" +"Unable to delete this document because it is used as a default property" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_crm_case_job_req_main +msgid "Recruitment" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_gr +msgid "" +"\n" +"This is the base module to manage the accounting chart for Greece.\n" +"==================================================================\n" +"\n" +"Greek accounting chart and localization.\n" +" " +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Action Reference" +msgstr "" + +#. module: base +#: model:res.country,name:base.re +msgid "Reunion (French)" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:361 +#, python-format +msgid "" +"New column name must still start with x_ , because it is a custom field!" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_wiki +msgid "" +"\n" +"The base module to manage documents(wiki).\n" +"==========================================\n" +"\n" +"Keep track of Wiki groups, pages, and history.\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_mrp_repair +msgid "Repairs Management" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_asset +msgid "Assets Management" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: view:ir.rule:0 +#: field:ir.rule,global:0 +msgid "Global" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_stock_planning +msgid "" +"\n" +"MPS allows to create a manual procurement plan apart of the normal MRP " +"scheduling, which works automatically based on minimum stock rules\n" +"=============================================================================" +"============================================================\n" +"\n" +"Quick Glossary\n" +"--------------\n" +"- Stock Period - the time boundaries (between Start Date and End Date) for " +"your Sales and Stock forecasts and planning\n" +"- Sales Forecast - the quantity of products you plan to sell during the " +"related Stock Period.\n" +"- Stock Planning - the quantity of products you plan to purchase or produce " +"for the related Stock Period.\n" +"\n" +"To avoid confusion with the terms used by the ``sale_forecast`` module, " +"(\"Sales Forecast\" and \"Planning\" are amounts) we use terms \"Stock and " +"Sales Forecast\" and \"Stock Planning\" to emphasize that we use quantity " +"values.\n" +"\n" +"Where to begin\n" +"--------------\n" +"Using this module is done in three steps:\n" +"\n" +" * Create Stock Periods via the Warehouse>Configuration>Stock Periods menu " +"(Mandatory step)\n" +" * Create Sale Forecasts fill them with forecast quantities, via the " +"Sales>Sales Forecast menu. (Optional step but useful for further planning)\n" +" * Create the actual MPS plan, check the balance and trigger the " +"procurements as required. The actual procurement is the final step for the " +"Stock Period.\n" +"\n" +"Stock Period configuration\n" +"--------------------------\n" +"You have two menu items for Periods in \"Warehouse > Configuration > Stock " +"Periods\". There are:\n" +"\n" +" * \"Create Stock Periods\" - can automatically creating daily, weekly or " +"monthly periods.\n" +" * \"Stock Periods\" - allows to create any type of periods, change the " +"dates and change the state of period.\n" +"\n" +"Creating periods is the first step. You can create custom periods using the " +"\"New\" button in \"Stock Periods\", but it is recommended to use the " +"automatic assistant \"Create Stock Periods\".\n" +"\n" +"Remarks:\n" +"\n" +" - These periods (Stock Periods) are completely distinct from Financial or " +"other periods in the system.\n" +" - Periods are not assigned to companies (when you use multicompany). Module " +"suppose that you use the same periods across companies. If you wish to use " +"different periods for different companies define them as you wish (they can " +"overlap). Later on in this text will be indications how to use such " +"periods.\n" +" - When periods are created automatically their start and finish dates are " +"with start hour 00:00:00 and end hour 23:59:00. When you create daily " +"periods they will have start date 31.01.2010 00:00:00 and end date " +"31.01.2010 23:59:00. It works only in automatic creation of periods. When " +"you create periods manually you have to take care about hours because you " +"can have incorrect values form sales or stock.\n" +" - If you use overlapping periods for the same product, warehouse and " +"company results can be unpredictable.\n" +" - If current date doesn't belong to any period or you have holes between " +"periods results can be unpredictable.\n" +"\n" +"Sales Forecasts configuration\n" +"-----------------------------\n" +"You have few menus for Sales forecast in \"Sales > Sales Forecasts\":\n" +"\n" +" - \"Create Sales Forecasts\" - can automatically create forecast lines " +"according to your needs\n" +" - \"Sales Forecasts\" - for managing the Sales forecasts\n" +"\n" +"Menu \"Create Sales Forecasts\" creates Forecasts for products from selected " +"Category, for selected Period and for selected Warehouse.\n" +"It is also possible to copy the previous forecast.\n" +"\n" +"Remarks:\n" +"\n" +" - This tool doesn't duplicate lines if you already have an entry for the " +"same Product, Period, Warehouse, created or validated by the same user. If " +"you wish to create another forecast, if relevant lines exists you have to do " +"it manually as described below.\n" +" - When created lines are validated by someone else you can use this tool to " +"create another line for the same Period, Product and Warehouse.\n" +" - When you choose \"Copy Last Forecast\", created line take quantity and " +"other settings from your (validated by you or created by you if not " +"validated yet) forecast which is for last period before period of created " +"forecast.\n" +"\n" +"On \"Sales Forecast\" form mainly you have to enter a forecast quantity in " +"\"Product Quantity\".\n" +"Further calculation can work for draft forecasts. But validation can save " +"your data against any accidental changes.\n" +"You can click \"Validate\" button but it is not mandatory.\n" +"\n" +"Instead of forecast quantity you may enter the amount of forecast sales via " +"the \"Product Amount\" field.\n" +"The system will count quantity from amount according to Sale price of the " +"Product.\n" +"\n" +"All values on the form are expressed in unit of measure selected on form.\n" +"You can select a unit of measure from the default category or from secondary " +"category.\n" +"When you change unit of measure the forecast product quantity will be re-" +"computed according to new UoM.\n" +"\n" +"To work out your Sale Forecast you can use the \"Sales History\" of the " +"product.\n" +"You have to enter parameters to the top and left of this table and system " +"will count sale quantities according to these parameters.\n" +"So you can get results for a given sales team or period.\n" +"\n" +"\n" +"MPS or Procurement Planning\n" +"---------------------------\n" +"An MPS planning consists in Stock Planning lines, used to analyze and " +"possibly drive the procurement of \n" +"products for each relevant Stock Period and Warehouse.\n" +"The menu is located in \"Warehouse > Schedulers > Master Procurement " +"Schedule\":\n" +"\n" +" - \"Create Stock Planning Lines\" - a wizard to help automatically create " +"many planning lines\n" +" - \"Master Procurement Schedule\" - management of your planning lines\n" +"\n" +"Similarly to the way Sales forecast serves to define your sales planning, " +"the MPS lets you plan your procurements (Purchase/Manufacturing).\n" +"You can quickly populate the MPS with the \"Create Stock Planning Lines\" " +"wizard, and then proceed to review them via the \"Master Procurement " +"Schedule\" menu.\n" +"\n" +"The \"Create Stock Planning Lines\" wizard lets you to quickly create all " +"MPS lines for a given Product Category, and a given Period and Warehouse.\n" +"When you enable the \"All Products with Forecast\" option of the wizard, the " +"system creates lines for all products having sales forecast for selected\n" +"Period and Warehouse (the selected Category will be ignored in this case).\n" +"\n" +"Under menu \"Master Procurement Schedule\" you will usually change the " +"\"Planned Out\" and \"Planned In\" quantities and observe the resulting " +"\"Stock Simulation\" value\n" +"to decide if you need to procure more products for the given Period.\n" +"\"Planned Out\" will be initially based on \"Warehouse Forecast\" which is " +"the sum of all outgoing stock moves already planned for the Period and " +"Warehouse.\n" +"Of course you can alter this value to provide your own quantities. It is not " +"necessary to have any forecast.\n" +"\"Planned In\" quantity is used to calculate field \"Incoming Left\" which " +"is the quantity to be procured to reach the \"Stock Simulation\" at the end " +"of Period.\n" +"You can compare \"Stock Simulation\" quantity to minimum stock rules visible " +"on the form.\n" +"And you can plan different quantity than in Minimum Stock Rules. " +"Calculations are done for whole Warehouse by default,\n" +"if you want to see values for Stock location of calculated warehouse you can " +"check \"Stock Location Only\".\n" +"\n" +"When you are satisfied with the \"Planned Out\", \"Planned In\" and end of " +"period \"Stock Simulation\",\n" +"you can click on \"Procure Incoming Left\" to create a procurement for the " +"\"Incoming Left\" quantity.\n" +"You can decide if procurement will go to the to Stock or Input location of " +"the Warehouse.\n" +"\n" +"If you don't want to Produce or Buy the product but just transfer the " +"calculated quantity from another warehouse\n" +"you can click \"Supply from Another Warehouse\" (instead of \"Procure " +"Incoming Left\") and the system will\n" +"create the appropriate picking list (stock moves).\n" +"You can choose to take the goods from the Stock or the Output location of " +"the source warehouse.\n" +"Destination location (Stock or Input) in the destination warehouse will be " +"taken as for the procurement case.\n" +"\n" +"To see update the quantities of \"Confirmed In\", \"Confirmed Out\", " +"\"Confirmed In Before\", \"Planned Out Before\"\n" +"and \"Stock Simulation\" you can press \"Calculate Planning\".\n" +"\n" +"All values on the form are expressed in unit of measure selected on form.\n" +"You can select one of unit of measure from default category or from " +"secondary category.\n" +"When you change unit of measure the editable quantities will be re-computed " +"according to new UoM. The others will be updated after pressing \"Calculate " +"Planning\".\n" +"\n" +"Computation of Stock Simulation quantities\n" +"------------------------------------------\n" +"The Stock Simulation value is the estimated stock quantity at the end of the " +"period.\n" +"The calculation always starts with the real stock on hand at the beginning " +"of the current period, then\n" +"adds or subtracts the computed quantities.\n" +"When you are in the same period (current period is the same as calculated) " +"Stock Simulation is calculated as follows:\n" +"\n" +"Stock Simulation =\n" +"\tStock of beginning of current Period\n" +"\t- Planned Out\n" +"\t+ Planned In\n" +"\n" +"When you calculate period next to current:\n" +"\n" +"Stock Simulation =\n" +"\tStock of beginning of current Period\n" +"\t- Planned Out of current Period\n" +"\t+ Confirmed In of current Period (incl. Already In)\n" +"\t- Planned Out of calculated Period\n" +"\t+ Planned In of calculated Period .\n" +"\n" +"As you see the calculated Period is taken the same way as in previous case, " +"but the calculation in the current\n" +"Period is a little bit different. First you should note that system takes " +"for only Confirmed moves for the\n" +"current period. This means that you should complete the planning and " +"procurement of the current Period before\n" +"going to the next one.\n" +"\n" +"When you plan for future Periods:\n" +"\n" +"Stock Simulation =\n" +"\tStock of beginning of current Period\n" +"\t- Sum of Planned Out of Periods before calculated\n" +"\t+ Sum of Confirmed In of Periods before calculated (incl. Already In)\n" +"\t- Planned Out of calculated Period\n" +"\t+ Planned In of calculated Period.\n" +"\n" +"Here \"Periods before calculated\" designates all periods starting with the " +"current until the period before the one being calculated.\n" +"\n" +"Remarks:\n" +"\n" +" - Remember to make the proceed with the planning of each period in " +"chronological order, otherwise the numbers will not reflect the\n" +" reality\n" +" - If you planned for future periods and find that real Confirmed Out is " +"larger than Planned Out in some periods before,\n" +" you can repeat Planning and make another procurement. You should do it in " +"the same planning line.\n" +" If you create another planning line the suggestions can be wrong.\n" +" - When you wish to work with different periods for some products, define " +"two kinds of periods (e.g. Weekly and Monthly) and use\n" +" them for different products. Example: If you use always Weekly periods " +"for Product A, and Monthly periods for Product B\n" +" all calculations will work correctly. You can also use different kind of " +"periods for the same product from different warehouse\n" +" or companies. But you cannot use overlapping periods for the same " +"product, warehouse and company because results\n" +" can be unpredictable. The same applies to Forecasts lines.\n" +msgstr "" + +#. module: base +#: model:res.country,name:base.mp +msgid "Northern Mariana Islands" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_claim_from_delivery +msgid "Claim on Deliveries" +msgstr "" + +#. module: base +#: model:res.country,name:base.sb +msgid "Solomon Islands" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:537 +#: code:addons/orm.py:3436 +#: code:addons/orm.py:3656 +#: code:addons/orm.py:3668 +#: code:addons/orm.py:3894 +#: code:addons/orm.py:4408 +#, python-format +msgid "AccessError" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Waiting" +msgstr "" + +#. module: base +#: field:ir.exports,resource:0 +#: model:ir.module.module,shortdesc:base.module_resource +#: view:ir.property:0 +#: field:ir.property,res_id:0 +msgid "Resource" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "8. %I:%M:%S %p ==> 06:25:20 PM" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_module_doc_rst +msgid "" +"\n" +"This module generates the Technical Guides of selected modules in " +"Restructured Text format (RST).\n" +"=============================================================================" +"====================\n" +"\n" +" * It uses the Sphinx (http://sphinx.pocoo.org) implementation of RST\n" +" * It creates a tarball (.tgz file suffix) containing an index file and " +"one file per module\n" +" * Generates Relationship Graph\n" +" " +msgstr "" + +#. module: base +#: field:res.log,create_date:0 +msgid "Creation Date" +msgstr "" + +#. module: base +#: view:ir.translation:0 +#: model:ir.ui.menu,name:base.menu_translation +msgid "Translations" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_project_gtd +msgid "Todo Lists" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Report" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:218 +#, python-format +msgid "" +"Your OpenERP Server does not support SMTP-over-SSL. You could use STARTTLS " +"instead.If SSL is needed, an upgrade to Python 2.6 on the server-side should " +"do the trick." +msgstr "" + +#. module: base +#: model:res.country,name:base.ua +msgid "Ukraine" +msgstr "" + +#. module: base +#: field:ir.module.module,website:0 +#: field:res.company,website:0 +#: field:res.partner,website:0 +msgid "Website" +msgstr "" + +#. module: base +#: selection:ir.mail_server,smtp_encryption:0 +msgid "None" +msgstr "" + +#. module: base +#: view:ir.module.category:0 +msgid "Module Category" +msgstr "" + +#. module: base +#: view:partner.wizard.ean.check:0 +msgid "Ignore" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Reference Guide" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Default Value Scope" +msgstr "" + +#. module: base +#: view:ir.ui.view:0 +msgid "Architecture" +msgstr "" + +#. module: base +#: model:res.country,name:base.ml +msgid "Mali" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_at +msgid "" +"This module provides the standard Accounting Chart for Austria which is " +"based on the Template from BMF.gv.at. Please keep in mind that you should " +"review and adapt it with your Accountant, before using it in a live " +"Environment." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Flemish (BE) / Vlaams (BE)" +msgstr "" + +#. module: base +#: field:ir.cron,interval_number:0 +msgid "Interval Number" +msgstr "" + +#. module: base +#: model:res.country,name:base.tk +msgid "Tokelau" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr_timesheet_sheet +msgid "" +"\n" +"This module helps you to easily encode and validate timesheet and " +"attendances within the same view.\n" +"=============================================================================" +"======================\n" +"\n" +"The upper part of the view is for attendances and track (sign in/sign out) " +"events.\n" +"The lower part is for timesheet.\n" +"\n" +"Other tabs contains statistics views to help you analyse your\n" +"time or the time of your team:\n" +"* Time spent by day (with attendances)\n" +"* Time spent by project\n" +"\n" +"This module also implements a complete timesheet validation process:\n" +"* Draft sheet\n" +"* Confirmation at the end of the period by the employee\n" +"* Validation by the project manager\n" +"\n" +"The validation can be configured in the company:\n" +"* Period size (day, week, month, year)\n" +"* Maximal difference between timesheet and attendances\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.bn +msgid "Brunei Darussalam" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_fetchmail_crm +#: model:ir.module.module,description:base.module_fetchmail_crm_claim +#: model:ir.module.module,description:base.module_fetchmail_hr_recruitment +#: model:ir.module.module,description:base.module_fetchmail_project_issue +msgid "" +"\n" +" " +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +#: field:ir.actions.act_window,view_type:0 +#: field:ir.actions.act_window.view,view_mode:0 +#: field:ir.ui.view,type:0 +#: field:wizard.ir.model.menu.create.line,view_type:0 +msgid "View Type" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_2 +msgid "User Interface" +msgstr "" + +#. module: base +#: field:res.partner,child_ids:0 +#: field:res.request,ref_partner_id:0 +msgid "Partner Ref." +msgstr "" + +#. module: base +#: field:ir.attachment,create_date:0 +msgid "Date Created" +msgstr "" + +#. module: base +#: help:ir.actions.server,trigger_name:0 +msgid "The workflow signal to trigger" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_mrp +msgid "" +"\n" +"This is the base module to manage the manufacturing process in OpenERP.\n" +"=======================================================================\n" +"\n" +"Features:\n" +"---------\n" +" * Make to Stock / Make to Order (by line)\n" +" * Multi-level BoMs, no limit\n" +" * Multi-level routing, no limit\n" +" * Routing and work center integrated with analytic accounting\n" +" * Scheduler computation periodically / Just In Time module\n" +" * Multi-pos, multi-warehouse\n" +" * Different reordering policies\n" +" * Cost method by product: standard price, average price\n" +" * Easy analysis of troubles or needs\n" +" * Very flexible\n" +" * Allows to browse Bill of Materials in complete structure that include " +"child and phantom BoMs\n" +"\n" +"It supports complete integration and planification of stockable goods,\n" +"consumable of services. Services are completely integrated with the rest\n" +"of the software. For instance, you can set up a sub-contracting service\n" +"in a BoM to automatically purchase on order the assembly of your " +"production.\n" +"\n" +"Reports provided by this module:\n" +"--------------------------------\n" +" * Bill of Material structure and components\n" +" * Load forecast on Work Centers\n" +" * Print a production order\n" +" * Stock forecasts\n" +"\n" +"Dashboard provided by this module:\n" +"----------------------------------\n" +" * List of next production orders\n" +" * List of procurements in exception\n" +" * Graph of work center load\n" +" * Graph of stock value variation\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_google_base_account +msgid "The module adds google user in res user" +msgstr "" + +#. module: base +#: selection:base.language.install,state:0 +#: selection:base.module.import,state:0 +#: selection:base.module.update,state:0 +msgid "done" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "General Settings" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_uy +msgid "Uruguay - Chart of Accounts" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_administration_shortcut +msgid "Custom Shortcuts" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Vietnamese / Tiếng Việt" +msgstr "" + +#. module: base +#: model:res.country,name:base.dz +msgid "Algeria" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_plugin +msgid "CRM Plugins" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_model_model +#: model:ir.model,name:base.model_ir_model +#: model:ir.ui.menu,name:base.ir_model_model_menu +msgid "Models" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_cron.py:292 +#, python-format +msgid "Record cannot be modified right now" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,type:0 +msgid "Launch Manually" +msgstr "" + +#. module: base +#: model:res.country,name:base.be +msgid "Belgium" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Preview Header" +msgstr "" + +#. module: base +#: field:res.company,paper_format:0 +msgid "Paper Format" +msgstr "" + +#. module: base +#: field:base.language.export,lang:0 +#: field:base.language.install,lang:0 +#: field:base.update.translations,lang:0 +#: field:ir.translation,lang:0 +#: field:res.partner,lang:0 +#: field:res.users,context_lang:0 +msgid "Language" +msgstr "" + +#. module: base +#: model:res.country,name:base.gm +msgid "Gambia" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_company_form +#: model:ir.model,name:base.model_res_company +#: model:ir.ui.menu,name:base.menu_action_res_company_form +#: model:ir.ui.menu,name:base.menu_res_company_global +#: view:res.company:0 +#: field:res.users,company_ids:0 +msgid "Companies" +msgstr "" + +#. module: base +#: help:res.currency,symbol:0 +msgid "Currency sign, to be used when printing amounts." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%H - Hour (24-hour clock) [00,23]." +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:451 +#, python-format +msgid "" +"Your server does not seem to support SSL, you may want to try STARTTLS " +"instead" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_widget +msgid "res.widget" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:290 +#, python-format +msgid "Model %s does not exist!" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_plugin +msgid "" +"\n" +"The common interface for pugin.\n" +"=====================================================\n" +"\n" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_mrp_jit +msgid "Just In Time Scheduling" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_bank_statement_extensions +msgid "Bank Statement extensions to support e-banking" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +#: field:ir.actions.server,code:0 +#: selection:ir.actions.server,state:0 +msgid "Python Code" +msgstr "" + +#. module: base +#: help:ir.actions.server,state:0 +msgid "Type of the Action that is to be executed" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base +msgid "The kernel of OpenERP, needed for all installation." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_osv_memory_autovacuum +msgid "osv_memory.autovacuum" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_us +msgid "United States - Chart of accounts" +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: view:base.module.import:0 +#: view:base.module.update:0 +#: view:base.module.upgrade:0 +#: view:base.update.translations:0 +#: view:partner.clear.ids:0 +#: view:partner.massmail.wizard:0 +#: view:partner.sms.send:0 +#: view:publisher_warranty.contract.wizard:0 +#: view:res.config:0 +#: view:res.config.installer:0 +#: view:res.widget.wizard:0 +msgid "Cancel" +msgstr "" + +#. module: base +#: selection:base.language.export,format:0 +msgid "PO File" +msgstr "" + +#. module: base +#: model:res.country,name:base.nt +msgid "Neutral Zone" +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "Custom" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Current" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_crm_fundraising +msgid "" +"\n" +"Fundraising.\n" +"============\n" +"\n" +"When you wish to support your organization or a campaign, you can trace\n" +"all your activities for collecting money. The menu opens a search list\n" +"where you can find fund descriptions, email, history and probability of\n" +"success. Several action buttons allow you to easily modify your different\n" +"fund status.\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_sale_margin +msgid "Margins in Sales Orders" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_9 +msgid "Components Supplier" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_purchase_management +#: model:ir.module.module,shortdesc:base.module_purchase +msgid "Purchase Management" +msgstr "" + +#. module: base +#: field:ir.module.module,published_version:0 +msgid "Published Version" +msgstr "" + +#. module: base +#: model:res.country,name:base.is +msgid "Iceland" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_action_window +#: model:ir.ui.menu,name:base.menu_ir_action_window +msgid "Window Actions" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%I - Hour (12-hour clock) [01,12]." +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract.wizard,state:0 +msgid "Finished" +msgstr "" + +#. module: base +#: model:res.country,name:base.de +msgid "Germany" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Week of the year: %(woy)s" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_14 +msgid "Bad customers" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Reports :" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_multi_company +msgid "" +"\n" +"This module is for managing a multicompany environment.\n" +"=======================================================\n" +"\n" +"This module is the base module for other multi-company modules.\n" +" " +msgstr "" + +#. module: base +#: sql_constraint:res.currency:0 +msgid "The currency code must be unique per company!" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_property +msgid "ir.property" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_fetchmail +msgid "" +"\n" +"Retrieve incoming email on POP / IMAP servers\n" +"=============================================\n" +"\n" +"Enter the parameters of your POP/IMAP account(s), and any incoming\n" +"emails on these accounts will be automatically downloaded into your OpenERP\n" +"system. All POP3/IMAP-compatible servers are supported, included those\n" +"that require an encrypted SSL/TLS connection.\n" +"\n" +"This can be used to easily create email-based workflows for many\n" +"email-enabled OpenERP documents, such as:\n" +"\n" +" * CRM Leads/Opportunities\n" +" * CRM Claims\n" +" * Project Issues\n" +" * Project Tasks\n" +" * Human Resource Recruitments (Applicants)\n" +" * etc.\n" +"\n" +"Just install the relevant application, and you can assign any of\n" +"these document types (Leads, Project Issues, etc.) to your incoming\n" +"email accounts. New emails will automatically spawn new documents\n" +"of the chosen type, so it's a snap to create a mailbox-to-OpenERP\n" +"integration. Even better: these documents directly act as mini\n" +"conversations synchronized by email. You can reply from within\n" +"OpenERP, and the answers will automatically be collected when\n" +"they come back, and attached to the same *conversation* document.\n" +"\n" +"For more specific needs, you may also assign custom-defined actions\n" +"(technically: Server Actions) to be triggered for each incoming\n" +"mail. \n" +" " +msgstr "" + +#. module: base +#: help:ir.actions.server,email:0 +msgid "" +"Expression that returns the email address to send to. Can be based on the " +"same values as for the condition field.\n" +"Example: object.invoice_address_id.email, or 'me@example.com'" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_hello +msgid "" +"\n" +" OpenERP Web example module.\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.gy +msgid "Guyana" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_product_expiry +msgid "Products Expiry Date" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account +msgid "" +"\n" +"Accounting and Financial Management.\n" +"====================================\n" +"\n" +"Financial and accounting module that covers:\n" +"--------------------------------------------\n" +"General accountings\n" +"Cost / Analytic accounting\n" +"Third party accounting\n" +"Taxes management\n" +"Budgets\n" +"Customer and Supplier Invoices\n" +"Bank statements\n" +"Reconciliation process by partner\n" +"\n" +"Creates a dashboard for accountants that includes:\n" +"--------------------------------------------------\n" +"* List of Customer Invoice to Approve\n" +"* Company Analysis\n" +"* Graph of Aged Receivables\n" +"* Graph of Treasury\n" +"\n" +"The processes like maintaining of general ledger is done through the defined " +"financial Journals (entry move line or\n" +"grouping is maintained through journal) for a particular financial year and " +"for preparation of vouchers there is a\n" +"module named account_voucher.\n" +" " +msgstr "" + +#. module: base +#: help:ir.actions.act_window,view_type:0 +msgid "" +"View type: set to 'tree' for a hierarchical tree view, or 'form' for other " +"views" +msgstr "" + +#. module: base +#: code:addons/base/res/res_config.py:385 +#, python-format +msgid "Click 'Continue' to configure the next addon..." +msgstr "" + +#. module: base +#: field:ir.actions.server,record_id:0 +msgid "Create Id" +msgstr "" + +#. module: base +#: model:res.country,name:base.hn +msgid "Honduras" +msgstr "" + +#. module: base +#: help:res.users,menu_tips:0 +msgid "" +"Check out this box if you want to always display tips on each menu action" +msgstr "" + +#. module: base +#: model:res.country,name:base.eg +msgid "Egypt" +msgstr "" + +#. module: base +#: field:ir.rule,perm_read:0 +msgid "Apply For Read" +msgstr "" + +#. module: base +#: help:ir.actions.server,model_id:0 +msgid "" +"Select the object on which the action will work (read, write, create)." +msgstr "" + +#. module: base +#: field:base.language.import,name:0 +msgid "Language Name" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Boolean" +msgstr "" + +#. module: base +#: help:ir.mail_server,smtp_encryption:0 +msgid "" +"Choose the connection encryption scheme:\n" +"- None: SMTP sessions are done in cleartext.\n" +"- TLS (STARTTLS): TLS encryption is requested at start of SMTP session " +"(Recommended)\n" +"- SSL/TLS: SMTP sessions are encrypted with SSL/TLS through a dedicated port " +"(default: 465)" +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "Fields Description" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_report_designer +msgid "" +"\n" +"Installer for reporting Hidden.\n" +"==============================\n" +"\n" +"Makes the Reporting Hidden Configuration available from where you can " +"install\n" +"modules like base_report_designer and base_report_creator.\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_synchro +msgid "Multi-DB Synchronization" +msgstr "" + +#. module: base +#: selection:ir.module.module,complexity:0 +msgid "Expert" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr_holidays +msgid "Leaves Management" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +#: view:ir.attachment:0 +#: view:ir.cron:0 +#: view:ir.model.access:0 +#: view:ir.model.data:0 +#: view:ir.model.fields:0 +#: view:ir.ui.view:0 +#: view:ir.values:0 +#: view:res.partner:0 +#: view:res.partner.address:0 +#: view:workflow.activity:0 +msgid "Group By..." +msgstr "" + +#. module: base +#: view:ir.model.fields:0 +#: field:ir.model.fields,readonly:0 +#: field:res.partner.bank.type.field,readonly:0 +msgid "Readonly" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_crm_todo +msgid "" +"\n" +"Todo list for CRM leads and opportunities.\n" +" " +msgstr "" + +#. module: base +#: field:ir.actions.act_window.view,view_id:0 +#: field:ir.default,page:0 +#: selection:ir.translation,type:0 +#: field:wizard.ir.model.menu.create.line,view_id:0 +msgid "View" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_wiki_sale_faq +msgid "Wiki: Sale FAQ" +msgstr "" + +#. module: base +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "To be installed" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,display_menu_tip:0 +msgid "" +"It gives the status if the tip has to be displayed or not when a user " +"executes an action" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: model:ir.module.module,shortdesc:base.module_base +#: field:res.currency,base:0 +msgid "Base" +msgstr "" + +#. module: base +#: field:ir.model.data,model:0 +#: field:ir.values,model:0 +msgid "Model Name" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Telugu / తెలుగు" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_document_ics +msgid "" +"\n" +"Allows to synchronise calendars with others applications.\n" +"=========================================================\n" +"\n" +"Will allow you to synchronise your OpenERP calendars with your phone, " +"outlook, Sunbird, ical, ...\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.lr +msgid "Liberia" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_in +msgid "" +"\n" +"Indian Accounting : Chart of Account.\n" +"=====================================\n" +"\n" +"Indian accounting chart and localization.\n" +" " +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: view:ir.model:0 +#: view:res.groups:0 +#: view:res.partner:0 +#: field:res.partner,comment:0 +#: model:res.widget,title:base.note_widget +msgid "Notes" +msgstr "" + +#. module: base +#: field:ir.config_parameter,value:0 +#: field:ir.property,value_binary:0 +#: field:ir.property,value_datetime:0 +#: field:ir.property,value_float:0 +#: field:ir.property,value_integer:0 +#: field:ir.property,value_reference:0 +#: field:ir.property,value_text:0 +#: selection:ir.server.object.lines,type:0 +#: field:ir.server.object.lines,value:0 +#: field:ir.values,value:0 +msgid "Value" +msgstr "" + +#. module: base +#: field:ir.sequence,code:0 +#: field:ir.sequence.type,code:0 +#: selection:ir.translation,type:0 +#: field:res.partner.bank.type,code:0 +msgid "Code" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_config_installer +msgid "res.config.installer" +msgstr "" + +#. module: base +#: model:res.country,name:base.mc +msgid "Monaco" +msgstr "" + +#. module: base +#: view:base.module.import:0 +msgid "Please be patient, this operation may take a few minutes..." +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Minutes" +msgstr "" + +#. module: base +#: view:res.currency:0 +msgid "Display" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Help" +msgstr "" + +#. module: base +#: help:res.users,menu_id:0 +msgid "" +"If specified, the action will replace the standard menu for this user." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_google_map +msgid "Google Maps on Customers" +msgstr "" + +#. module: base +#: model:ir.actions.report.xml,name:base.preview_report +msgid "Preview Report" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_purchase_analytic_plans +msgid "Purchase Analytic Plans" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_analytic_journal_billing_rate +msgid "" +"\n" +"This module allows you to define what is the default invoicing rate for a " +"specific journal on a given account.\n" +"=============================================================================" +"=================================\n" +"\n" +"This is mostly used when a user encodes his timesheet: the values are " +"retrieved and the fields are auto-filled. But the possibility to change " +"these values is still available.\n" +"\n" +"Obviously if no data has been recorded for the current account, the default " +"value is given as usual by the account data so that this module is perfectly " +"compatible with older configurations.\n" +"\n" +" " +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_fundrising +msgid "Fund Raising" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_sequence_type +#: model:ir.ui.menu,name:base.menu_ir_sequence_type +msgid "Sequence Codes" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (CO) / Español (CO)" +msgstr "" + +#. module: base +#: view:base.module.configuration:0 +msgid "" +"All pending configuration wizards have been executed. You may restart " +"individual wizards via the list of configuration wizards." +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Current Year with Century: %(year)s" +msgstr "" + +#. module: base +#: field:ir.exports,export_fields:0 +msgid "Export ID" +msgstr "" + +#. module: base +#: model:res.country,name:base.fr +msgid "France" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_log +msgid "res.log" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,flow_stop:0 +msgid "Flow Stop" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Weeks" +msgstr "" + +#. module: base +#: code:addons/base/res/res_company.py:157 +#, python-format +msgid "VAT: " +msgstr "RFC " + +#. module: base +#: model:res.country,name:base.af +msgid "Afghanistan, Islamic State of" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_import.py:60 +#: code:addons/base/module/wizard/base_module_import.py:68 +#, python-format +msgid "Error !" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_marketing_campaign_crm_demo +msgid "Marketing Campaign - Demo" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_fetchmail_hr_recruitment +msgid "eMail Gateway for Applicants" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_coda +msgid "Belgium - Import bank CODA statements" +msgstr "" + +#. module: base +#: field:ir.cron,interval_type:0 +msgid "Interval Unit" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,kind:0 +#: field:workflow.activity,kind:0 +msgid "Kind" +msgstr "" + +#. module: base +#: code:addons/orm.py:4368 +#, python-format +msgid "This method does not exist anymore" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_import_google +msgid "Google Import" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_12 +msgid "Segmentation" +msgstr "" + +#. module: base +#: field:res.lang,thousands_sep:0 +msgid "Thousands Separator" +msgstr "" + +#. module: base +#: field:res.request,create_date:0 +msgid "Created Date" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Keywords" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_cn +msgid "中国会计科目表 - Accounting" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: field:ir.model.access,perm_read:0 +#: view:ir.rule:0 +msgid "Read Access" +msgstr "" + +#. module: base +#: help:ir.actions.server,loop_action:0 +msgid "" +"Select the action that will be executed. Loop action will not be avaliable " +"inside loop." +msgstr "" + +#. module: base +#: help:ir.model.data,res_id:0 +msgid "ID of the target record in the database" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_analytic_analysis +msgid "Contracts Management" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Chinese (TW) / 正體字" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_request +msgid "res.request" +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "In Memory" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Todo" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_product_visible_discount +msgid "Prices Visible Discounts" +msgstr "" + +#. module: base +#: field:ir.attachment,datas:0 +msgid "File Content" +msgstr "" + +#. module: base +#: model:res.country,name:base.pa +msgid "Panama" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_bank_statement_extensions +msgid "" +"\n" +"Module that extends the standard account_bank_statement_line object for " +"improved e-banking support.\n" +"\n" +"Adds\n" +"- valuta date\n" +"- batch payments\n" +"- traceability of changes to bank statement lines\n" +"- bank statement line views\n" +"- bank statements balances report\n" +"- performance improvements for digital import of bank statement (via " +"'ebanking_import' context flag)\n" +"- name_search on res.partner.bank enhanced to allow search on bank and iban " +"account numbers\n" +" " +msgstr "" + +#. module: base +#: code:addons/orm.py:1895 +#, python-format +msgid "" +"Insufficient fields to generate a Calendar View for %s, missing a date_stop " +"or a date_delay\" % (self._name)))\n" +"\n" +" return view\n" +"\n" +" def _get_default_search_view(self, cr, uid, context=None):\n" +" \"\n" +" :param cr: database cursor\n" +" :param int user: user id\n" +" :param dict context: connection context\n" +" :returns: an lxml document of the view\n" +" :rtype: etree._Element\n" +" \"\n" +" form_view = self.fields_view_get(cr, uid, False, 'form', " +"context=context)\n" +" tree_view = self.fields_view_get(cr, uid, False, 'tree', " +"context=context)\n" +"\n" +" # TODO it seems _all_columns could be used instead of fields_get (no " +"need for translated fields info)\n" +" fields = self.fields_get(cr, uid, context=context)\n" +" fields_to_search = set(\n" +" field for field, descriptor in fields.iteritems()\n" +" if descriptor.get('select'))\n" +"\n" +" for view in (form_view, tree_view):\n" +" view_root = etree.fromstring(view['arch'])\n" +" # Only care about select=1 in xpath below, because select=2 is " +"covered\n" +" # by the custom advanced search in clients\n" +" " +"fields_to_search.update(view_root.xpath(\"//field[@select=1]/@name" +msgstr "" + +#. module: base +#: constraint:res.users:0 +msgid "The chosen company is not in the allowed companies for this user" +msgstr "" + +#. module: base +#: model:res.country,name:base.gi +msgid "Gibraltar" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_name:0 +msgid "Service Name" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_import_base +msgid "Framework for complex import" +msgstr "" + +#. module: base +#: view:ir.actions.todo.category:0 +msgid "Wizard Category" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_cancel +msgid "" +"\n" +"Allows cancelling accounting entries.\n" +"=====================================\n" +"\n" +"This module adds 'Allow cancelling entries' field on form view of account " +"journal. If set to true it allows user to cancel entries & invoices.\n" +" " +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_rule +#: model:ir.ui.menu,name:base.menu_action_rule +msgid "Record Rules" +msgstr "" + +#. module: base +#: field:res.users,name:0 +msgid "User Name" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Day of the year: %(doy)s" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_portal +#: model:ir.module.module,shortdesc:base.module_portal +msgid "Portal" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_claim_from_delivery +msgid "" +"\n" +"Create a claim from a delivery order.\n" +"=====================================\n" +"\n" +"Adds a Claim link to the delivery order.\n" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: view:ir.model.fields:0 +#: view:workflow.activity:0 +msgid "Properties" +msgstr "" + +#. module: base +#: help:ir.sequence,padding:0 +msgid "" +"OpenERP will automatically adds some '0' on the left of the 'Next Number' to " +"get the required padding size." +msgstr "" + +#. module: base +#: constraint:res.partner.bank:0 +msgid "" +"\n" +"Please define BIC/Swift code on bank for bank type IBAN Account to make " +"valid payments" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%A - Full weekday name." +msgstr "" + +#. module: base +#: help:ir.values,user_id:0 +msgid "If set, action binding only applies for this user." +msgstr "" + +#. module: base +#: model:res.country,name:base.gw +msgid "Guinea Bissau" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,search_view:0 +msgid "Search View" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "- module,type,name,res_id,src,value" +msgstr "" + +#. module: base +#: sql_constraint:res.lang:0 +msgid "The code of the language must be unique !" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_attachment +#: view:ir.actions.report.xml:0 +#: view:ir.attachment:0 +#: model:ir.ui.menu,name:base.menu_action_attachment +msgid "Attachments" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_uy +msgid "" +"\n" +"General Chart of Accounts\n" +"=========================\n" +"\n" +"Provide Templates for Chart of Accounts, Taxes for Uruguay\n" +"\n" +msgstr "" + +#. module: base +#: help:res.company,bank_ids:0 +msgid "Bank accounts related to this company" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_partner +#: model:ir.ui.menu,name:base.menu_sale_config_sales +#: model:ir.ui.menu,name:base.menu_sales +msgid "Sales" +msgstr "" + +#. module: base +#: field:ir.actions.server,child_ids:0 +msgid "Other Actions" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,state:0 +msgid "Done" +msgstr "" + +#. module: base +#: help:ir.cron,doall:0 +msgid "" +"Specify if missed occurrences should be executed when the server restarts." +msgstr "" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_miss +msgid "Miss" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: field:ir.model.access,perm_write:0 +#: view:ir.rule:0 +msgid "Write Access" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%m - Month number [01,12]." +msgstr "" + +#. module: base +#: field:res.bank,city:0 +#: field:res.company,city:0 +#: field:res.partner,city:0 +#: field:res.partner.address,city:0 +#: field:res.partner.bank,city:0 +msgid "City" +msgstr "" + +#. module: base +#: model:res.country,name:base.qa +msgid "Qatar" +msgstr "" + +#. module: base +#: model:res.country,name:base.it +msgid "Italy" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +#: selection:ir.actions.todo,state:0 +msgid "To Do" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Estonian / Eesti keel" +msgstr "" + +#. module: base +#: field:res.partner,email:0 +msgid "E-mail" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL-3 or later version" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_google_map +msgid "" +"\n" +"The module adds Google Map field in partner address.\n" +"====================================================\n" +"\n" +"Using this you can directly open Google Map from the URL widget." +msgstr "" + +#. module: base +#: field:workflow.activity,action:0 +msgid "Python Action" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_report_webkit_sample +msgid "" +"\n" +"Samples for Webkit Report Engine (report_webkit module).\n" +"========================================================\n" +"\n" +"A sample invoice report is included in this module, as well as a wizard to\n" +"add Webkit Report entries on any Document in the system.\n" +"\n" +"You have to create the print buttons by calling the wizard. For more details " +"see:\n" +" http://files.me.com/nbessi/06n92k.mov\n" +" " +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "English (US)" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_title_partner +msgid "" +"Manage the partner titles you want to have available in your system. The " +"partner titles is the legal status of the company: Private Limited, SA, etc." +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "To browse official translations, you can start with these links:" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:531 +#, python-format +msgid "" +"You can not read this document (%s) ! Be sure your user belongs to one of " +"these groups: %s." +msgstr "" + +#. module: base +#: view:res.bank:0 +#: view:res.partner.address:0 +msgid "Address" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:308 +#, python-format +msgid "" +"You try to install module '%s' that depends on module '%s'.\n" +"But the latter module is not available in your system." +msgstr "" + +#. module: base +#: field:ir.module.module,latest_version:0 +msgid "Installed version" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Mongolian / монгол" +msgstr "" + +#. module: base +#: model:res.country,name:base.mr +msgid "Mauritania" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_translation +msgid "ir.translation" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_product_manufacturer +msgid "" +"\n" +"A module that adds manufacturers and attributes on the product form.\n" +"====================================================================\n" +"\n" +"You can now define the following for a product:\n" +" * Manufacturer\n" +" * Manufacturer Product Name\n" +" * Manufacturer Product Code\n" +" * Product Attributes\n" +" " +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_todo_category +msgid "Configuration Wizard Category" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "Module update result" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.workitem,act_id:0 +msgid "Activity" +msgstr "" + +#. module: base +#: view:res.partner:0 +#: view:res.partner.address:0 +msgid "Postal Address" +msgstr "" + +#. module: base +#: field:res.company,parent_id:0 +msgid "Parent Company" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_iban +msgid "" +"\n" +"This module installs the base for IBAN (International Bank Account Number) " +"bank accounts and checks for its validity.\n" +"=============================================================================" +"========================================\n" +"\n" +"The ability to extract the correctly represented local accounts from IBAN " +"accounts with a single statement.\n" +" " +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_mail_server +msgid "ir.mail_server" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (CR) / Español (CR)" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"Global rules (non group-specific) are restrictions, and cannot be bypassed. " +"Group-local rules grant additional permissions, but are constrained within " +"the bounds of global ones. The first group rules restrict further than " +"global rules, but any additional group rule will add more permissions" +msgstr "" + +#. module: base +#: field:res.currency.rate,rate:0 +msgid "Rate" +msgstr "" + +#. module: base +#: model:res.country,name:base.cg +msgid "Congo" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "Examples" +msgstr "" + +#. module: base +#: field:ir.default,value:0 +#: view:ir.values:0 +msgid "Default Value" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_country_state +msgid "Country state" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_5 +msgid "Sequences & Identifiers" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_th +msgid "" +"\n" +"Chart of Accounts for Thailand.\n" +"===============================\n" +"\n" +"Thai accounting chart and localization.\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.kn +msgid "Saint Kitts & Nevis Anguilla" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_point_of_sale +msgid "Point of Sales" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr_payroll_account +msgid "" +"\n" +"Generic Payroll system Integrated with Accountings.\n" +"===================================================\n" +"\n" +" * Expense Encoding\n" +" * Payment Encoding\n" +" * Company Contribution Management\n" +" " +msgstr "" + +#. module: base +#: code:addons/base/res/res_currency.py:190 +#, python-format +msgid "" +"No rate found \n" +"for the currency: %s \n" +"at the date: %s" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_point_of_sale +msgid "" +"\n" +"This module provides a quick and easy sale process.\n" +"===================================================\n" +"\n" +"Main features :\n" +"---------------\n" +" * Fast encoding of the sale.\n" +" * Allow to choose one payment mode (the quick way) or to split the " +"payment between several payment mode.\n" +" * Computation of the amount of money to return.\n" +" * Create and confirm picking list automatically.\n" +" * Allow the user to create invoice automatically.\n" +" * Allow to refund former sales.\n" +" " +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_ui_view_custom +msgid "" +"Customized views are used when users reorganize the content of their " +"dashboard views (via web client)" +msgstr "" + +#. module: base +#: help:publisher_warranty.contract,check_opw:0 +msgid "" +"Checked if this is an OpenERP Publisher's Warranty contract (versus older " +"contract types" +msgstr "" + +#. module: base +#: field:ir.model.fields,model:0 +msgid "Object Name" +msgstr "" + +#. module: base +#: help:ir.actions.server,srcmodel_id:0 +msgid "" +"Object in which you want to create / write the object. If it is empty then " +"refer to the Object field." +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "Not Installed" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,out_transitions:0 +msgid "Outgoing Transitions" +msgstr "" + +#. module: base +#: field:ir.ui.menu,icon:0 +msgid "Icon" +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_human_resources +msgid "" +"Helps you manage your human resources by encoding your employees structure, " +"generating work sheets, tracking attendance and more." +msgstr "" + +#. module: base +#: help:ir.model.fields,model_id:0 +msgid "The model this field belongs to" +msgstr "" + +#. module: base +#: model:res.country,name:base.mq +msgid "Martinique (French)" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_wiki_sale_faq +msgid "" +"\n" +"This module provides a Wiki Sales FAQ Template.\n" +"===============================================\n" +"\n" +"It provides demo data, thereby creating a Wiki Group and a Wiki Page\n" +"for Wiki Sale FAQ.\n" +" " +msgstr "" + +#. module: base +#: view:ir.sequence.type:0 +msgid "Sequences Type" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_action_rule +msgid "" +"\n" +"This module allows to implement action rules for any object.\n" +"============================================================\n" +"\n" +"Use automated actions to automatically trigger actions for various screens.\n" +"\n" +"Example: a lead created by a specific user may be automatically set to a " +"specific\n" +"sales team, or an opportunity which still has status pending after 14 days " +"might\n" +"trigger an automatic reminder email.\n" +" " +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_request-act +#: model:ir.ui.menu,name:base.menu_res_request_act +#: model:ir.ui.menu,name:base.menu_resquest_ref +#: view:res.request:0 +msgid "Requests" +msgstr "" + +#. module: base +#: model:res.country,name:base.ye +msgid "Yemen" +msgstr "" + +#. module: base +#: selection:workflow.activity,split_mode:0 +msgid "Or" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_br +msgid "Brazilian - Accounting" +msgstr "" + +#. module: base +#: model:res.country,name:base.pk +msgid "Pakistan" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_product_margin +msgid "" +"\n" +"Adds a reporting menu in products that computes sales, purchases, margins " +"and other interesting indicators based on invoices.\n" +"=============================================================================" +"================================================\n" +"\n" +"The wizard to launch the report has several options to help you get the data " +"you need.\n" +msgstr "" + +#. module: base +#: model:res.country,name:base.al +msgid "Albania" +msgstr "" + +#. module: base +#: help:ir.module.module,complexity:0 +msgid "" +"Level of difficulty of module. Easy: intuitive and easy to use for everyone. " +"Normal: easy to use for business experts. Expert: requires technical skills." +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:191 +#, python-format +msgid "" +"You cannot delete the language which is Active !\n" +"Please de-activate the language first." +msgstr "" + +#. module: base +#: view:base.language.install:0 +msgid "" +"Please be patient, this operation may take a few minutes (depending on the " +"number of modules currently installed)..." +msgstr "" + +#. module: base +#: field:ir.ui.menu,child_id:0 +msgid "Child IDs" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:748 +#: code:addons/base/ir/ir_actions.py:751 +#, python-format +msgid "Problem in configuration `Record Id` in Server Action!" +msgstr "" + +#. module: base +#: code:addons/orm.py:2682 +#: code:addons/orm.py:2692 +#, python-format +msgid "ValidateError" +msgstr "" + +#. module: base +#: view:base.module.import:0 +#: view:base.module.update:0 +msgid "Open Modules" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_sale_margin +msgid "" +"\n" +"This module adds the 'Margin' on sales order.\n" +"=============================================\n" +"\n" +"This gives the profitability by calculating the difference between the Unit " +"Price and Cost Price.\n" +" " +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_bank_form +msgid "Manage bank records you want to be used in the system." +msgstr "" + +#. module: base +#: view:base.module.import:0 +msgid "Import module" +msgstr "" + +#. module: base +#: field:ir.actions.server,loop_action:0 +msgid "Loop Action" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,report_file:0 +msgid "" +"The path to the main report file (depending on Report Type) or NULL if the " +"content is in another field" +msgstr "" + +#. module: base +#: model:res.country,name:base.la +msgid "Laos" +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +#: model:ir.ui.menu,name:base.menu_email +#: field:res.company,email:0 +#: field:res.users,user_email:0 +msgid "Email" +msgstr "" + +#. module: base +#: field:res.users,action_id:0 +msgid "Home Action" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_event_project +msgid "Retro-Planning on Events" +msgstr "" + +#. module: base +#: code:addons/custom.py:555 +#, python-format +msgid "" +"The sum of the data (2nd field) is null.\n" +"We can't draw a pie chart !" +msgstr "" + +#. module: base +#: view:partner.clear.ids:0 +msgid "Want to Clear Ids ? " +msgstr "" + +#. module: base +#: view:res.partner.bank:0 +msgid "Information About the Bank" +msgstr "" + +#. module: base +#: help:ir.actions.server,condition:0 +msgid "" +"Condition that is tested before the action is executed, and prevent " +"execution if it is not verified.\n" +"Example: object.list_price > 5000\n" +"It is a Python expression that can use the following values:\n" +" - self: ORM model of the record on which the action is triggered\n" +" - object or obj: browse_record of the record on which the action is " +"triggered\n" +" - pool: ORM model pool (i.e. self.pool)\n" +" - time: Python time module\n" +" - cr: database cursor\n" +" - uid: current user id\n" +" - context: current context" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"2. Group-specific rules are combined together with a logical OR operator" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_woodsuppliers0 +msgid "Wood Suppliers" +msgstr "" + +#. module: base +#: model:res.country,name:base.tg +msgid "Togo" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "Other Proprietary" +msgstr "" + +#. module: base +#: model:res.country,name:base.ec +msgid "Ecuador" +msgstr "" + +#. module: base +#: selection:workflow.activity,kind:0 +msgid "Stop All" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_analytic_user_function +msgid "Jobs on Contracts" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_import_sugarcrm +msgid "" +"This Module Import SugarCRM \"Leads\", \"Opportunities\", \"Users\", " +"\"Accounts\", \n" +" \"Contacts\", \"Employees\", Meetings, Phonecalls, Emails, and " +"Project, Project Tasks Data into OpenERP Module." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_add_wizard +#: model:ir.ui.menu,name:base.menu_publisher_warranty_contract_add +#: view:publisher_warranty.contract.wizard:0 +msgid "Register a Contract" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_ve +msgid "" +"\n" +"This is the module to manage the accounting chart for Venezuela in OpenERP.\n" +"===========================================================================\n" +"\n" +"Este módulo es para manejar un catálogo de cuentas ejemplo para Venezuela.\n" +msgstr "" + +#. module: base +#: view:ir.model.data:0 +msgid "Updatable" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "3. %x ,%X ==> 12/05/08, 18:25:20" +msgstr "" + +#. module: base +#: selection:ir.model.fields,on_delete:0 +msgid "Cascade" +msgstr "" + +#. module: base +#: field:workflow.transition,group_id:0 +msgid "Group Required" +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_knowledge_management +msgid "" +"Lets you install addons geared towards sharing knowledge with and between " +"your employees." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Arabic / الْعَرَبيّة" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_hello +msgid "Hello" +msgstr "" + +#. module: base +#: view:ir.actions.configuration.wizard:0 +msgid "Next Configuration Step" +msgstr "" + +#. module: base +#: field:res.groups,comment:0 +msgid "Comment" +msgstr "" + +#. module: base +#: model:res.groups,name:base.group_hr_manager +msgid "HR Manager" +msgstr "" + +#. module: base +#: view:ir.filters:0 +#: field:ir.model.fields,domain:0 +#: field:ir.rule,domain:0 +#: field:ir.rule,domain_force:0 +#: field:res.partner.title,domain:0 +msgid "Domain" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_marketing_campaign +msgid "Marketing Campaigns" +msgstr "" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:144 +#, python-format +msgid "Contract validation error" +msgstr "" + +#. module: base +#: field:ir.values,key2:0 +msgid "Qualifier" +msgstr "" + +#. module: base +#: field:res.country.state,name:0 +msgid "State Name" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "Update Languague Terms" +msgstr "" + +#. module: base +#: field:workflow.activity,join_mode:0 +msgid "Join Mode" +msgstr "" + +#. module: base +#: field:res.users,context_tz:0 +msgid "Timezone" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_wiki_faq +msgid "Wiki: Internal FAQ" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_report_xml +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.report.xml" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project_issue_sheet +msgid "" +"\n" +"This module adds the Timesheet support for the Issues/Bugs Management in " +"Project.\n" +"=============================================================================" +"====\n" +"\n" +"Worklogs can be maintained to signify number of hours spent by users to " +"handle an issue.\n" +" " +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_sequence_form +#: view:ir.sequence:0 +#: model:ir.ui.menu,name:base.menu_ir_sequence_form +msgid "Sequences" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_miss +msgid "Mss" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_view +msgid "ir.ui.view" +msgstr "" + +#. module: base +#: help:res.lang,code:0 +msgid "This field is used to set/get locales for user" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_2 +msgid "OpenERP Partners" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:293 +#, python-format +msgid "" +"Unable to install module \"%s\" because an external dependency is not met: %s" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Search modules" +msgstr "" + +#. module: base +#: model:res.country,name:base.by +msgid "Belarus" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,name:0 +#: field:ir.actions.act_window_close,name:0 +#: field:ir.actions.actions,name:0 +#: field:ir.actions.client,name:0 +#: field:ir.actions.server,name:0 +#: field:ir.actions.url,name:0 +msgid "Action Name" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_users +msgid "" +"Create and manage users that will connect to the system. Users can be " +"deactivated should there be a period of time during which they will/should " +"not connect to the system. You can assign them groups in order to give them " +"specific access to the applications they need to use in the system." +msgstr "" + +#. module: base +#: selection:ir.module.module,complexity:0 +#: selection:res.request,priority:0 +msgid "Normal" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_purchase_double_validation +msgid "Double Validation on Purchases" +msgstr "" + +#. module: base +#: field:res.bank,street2:0 +#: field:res.company,street2:0 +#: field:res.partner.address,street2:0 +msgid "Street2" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_base_module_update +msgid "Module Update" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_upgrade.py:95 +#, python-format +msgid "Following modules are not installed or unknown: %s" +msgstr "" + +#. module: base +#: view:ir.cron:0 +#: field:ir.cron,user_id:0 +#: field:ir.filters,user_id:0 +#: field:ir.ui.view.custom,user_id:0 +#: field:ir.values,user_id:0 +#: model:res.groups,name:base.group_document_user +#: model:res.groups,name:base.group_tool_user +#: field:res.log,user_id:0 +#: field:res.partner.event,user_id:0 +#: view:res.users:0 +#: field:res.widget.user,user_id:0 +msgid "User" +msgstr "" + +#. module: base +#: model:res.country,name:base.pr +msgid "Puerto Rico" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "Open Window" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,auto_search:0 +msgid "Auto Search" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,filter:0 +msgid "Filter" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_madam +msgid "Ms." +msgstr "" + +#. module: base +#: view:base.module.import:0 +msgid "" +"This wizard helps you to import a new module to your OpenERP system. After " +"importing a new module you can install it by clicking on the button " +"\"Install\" from the form view." +msgstr "" + +#. module: base +#: model:res.country,name:base.ch +msgid "Switzerland" +msgstr "" + +#. module: base +#: model:res.country,name:base.gd +msgid "Grenada" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Trigger Configuration" +msgstr "" + +#. module: base +#: view:base.language.install:0 +msgid "Load" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_warning +msgid "" +"\n" +"Module to trigger warnings in OpenERP objects.\n" +"==============================================\n" +"\n" +"Warning messages can be displayed for objects like sale order, purchase " +"order,\n" +"picking and invoice. The message is triggered by the form's onchange event.\n" +" " +msgstr "" + +#. module: base +#: code:addons/osv.py:150 +#: code:addons/osv.py:152 +#, python-format +msgid "Integrity Error" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_wizard_screen +msgid "ir.wizard.screen" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow +msgid "workflow" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:255 +#, python-format +msgid "Size of the field can never be less than 1 !" +msgstr "" + +#. module: base +#: model:res.country,name:base.so +msgid "Somalia" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_mrp_operations +msgid "Manufacturing Operations" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Terminated" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_13 +msgid "Important customers" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "Update Terms" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project_messages +msgid "" +"\n" +"This module provides the functionality to send messages within a project.\n" +"=========================================================================\n" +"\n" +"A user can send messages individually to other user. He can even broadcast\n" +"it to all the users.\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr +msgid "Employee Directory" +msgstr "" + +#. module: base +#: view:ir.cron:0 +#: field:ir.cron,args:0 +msgid "Arguments" +msgstr "" + +#. module: base +#: code:addons/orm.py:1260 +#, python-format +msgid "Database ID doesn't exist: %s : %s" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL Version 2" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL Version 3" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_report_intrastat +msgid "" +"\n" +"A module that adds intrastat reports.\n" +"=====================================\n" +"\n" +"This module gives the details of the goods traded between the countries of " +"European Union " +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_stock_invoice_directly +msgid "" +"\n" +"Invoice Wizard for Delivery.\n" +"============================\n" +"\n" +"When you send or deliver goods, this module automatically launch\n" +"the invoicing wizard if the delivery is to be invoiced.\n" +" " +msgstr "" + +#. module: base +#: code:addons/orm.py:1388 +#, python-format +msgid "key '%s' not found in selection field '%s'" +msgstr "" + +#. module: base +#: selection:ir.values,key:0 +#: selection:res.partner.address,type:0 +msgid "Default" +msgstr "" + +#. module: base +#: view:partner.wizard.ean.check:0 +msgid "Correct EAN13" +msgstr "" + +#. module: base +#: selection:res.company,paper_format:0 +msgid "A4" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,check_support:0 +msgid "Support Level 1" +msgstr "" + +#. module: base +#: field:res.partner,customer:0 +#: view:res.partner.address:0 +#: field:res.partner.address,is_customer_add:0 +#: model:res.partner.category,name:base.res_partner_category_0 +msgid "Customer" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (NI) / Español (NI)" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_product_visible_discount +msgid "" +"\n" +"This module lets you calculate discounts on Sale Order lines and Invoice " +"lines base on the partner's pricelist.\n" +"=============================================================================" +"==================================\n" +"\n" +"To this end, a new check box named \"Visible Discount\" is added to the " +"pricelist form.\n" +"\n" +"Example:\n" +" For the product PC1 and the partner \"Asustek\": if listprice=450, and " +"the price calculated using Asustek's pricelist is 225\n" +" If the check box is checked, we will have on the sale order line: Unit " +"price=450, Discount=50,00, Net price=225\n" +" If the check box is unchecked, we will have on Sale Order and Invoice " +"lines: Unit price=225, Discount=0,00, Net price=225\n" +" " +msgstr "" + +#. module: base +#: field:ir.module.module,shortdesc:0 +msgid "Short Description" +msgstr "" + +#. module: base +#: field:res.country,code:0 +msgid "Country Code" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Hour 00->24: %(h24)s" +msgstr "" + +#. module: base +#: field:ir.cron,nextcall:0 +msgid "Next Execution Date" +msgstr "" + +#. module: base +#: field:ir.sequence,padding:0 +msgid "Number Padding" +msgstr "" + +#. module: base +#: help:multi_company.default,field_id:0 +msgid "Select field property" +msgstr "" + +#. module: base +#: field:res.request.history,date_sent:0 +msgid "Date sent" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Month: %(month)s" +msgstr "" + +#. module: base +#: field:ir.actions.act_window.view,sequence:0 +#: field:ir.actions.server,sequence:0 +#: field:ir.actions.todo,sequence:0 +#: field:ir.actions.todo.category,sequence:0 +#: view:ir.cron:0 +#: field:ir.module.category,sequence:0 +#: field:ir.module.module,sequence:0 +#: view:ir.sequence:0 +#: field:ir.ui.menu,sequence:0 +#: view:ir.ui.view:0 +#: field:ir.ui.view,priority:0 +#: field:ir.ui.view_sc,sequence:0 +#: field:multi_company.default,sequence:0 +#: field:res.partner.bank,sequence:0 +#: field:res.widget.user,sequence:0 +#: field:wizard.ir.model.menu.create.line,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: base +#: model:res.country,name:base.tn +msgid "Tunisia" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Wizards to be Launched" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_manufacturing +#: model:ir.ui.menu,name:base.menu_mrp_root +msgid "Manufacturing" +msgstr "" + +#. module: base +#: model:res.country,name:base.km +msgid "Comoros" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Draft and Active" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_server_action +#: view:ir.actions.server:0 +#: model:ir.ui.menu,name:base.menu_server_action +msgid "Server Actions" +msgstr "" + +#. module: base +#: field:res.partner.bank.type,format_layout:0 +msgid "Format Layout" +msgstr "" + +#. module: base +#: field:ir.model.fields,selection:0 +msgid "Selection Options" +msgstr "" + +#. module: base +#: field:res.partner.category,parent_right:0 +msgid "Right parent" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_auth_openid +msgid "OpenID Authentification" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_plugin_thunderbird +msgid "" +"\n" +"This module is required for the Thuderbird Plug-in to work properly.\n" +"====================================================================\n" +"\n" +"The plugin allows you archive email and its attachments to the selected\n" +"OpenERP objects. You can select a partner, a task, a project, an analytical\n" +"account, or any other object and attach the selected mail as a .eml file in\n" +"the attachment of a selected record. You can create documents for CRM Lead,\n" +"HR Applicant and Project Issue from selected mails.\n" +" " +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "Legends for Date and Time Formats" +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Copy Object" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_mail +msgid "Emails Management" +msgstr "" + +#. module: base +#: field:ir.actions.server,trigger_name:0 +msgid "Trigger Signal" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:119 +#, python-format +msgid "" +"Group(s) cannot be deleted, because some user(s) still belong to them: %s !" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_mrp_repair +msgid "" +"\n" +"The aim is to have a complete module to manage all products repairs. The " +"following topics should be covered by this module:\n" +"=============================================================================" +"==============================================\n" +"\n" +" * Add/remove products in the reparation\n" +" * Impact for stocks\n" +" * Invoicing (products and/or services)\n" +" * Warranty concept\n" +" * Repair quotation report\n" +" * Notes for the technician and for the final customer\n" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_country_state +#: model:ir.ui.menu,name:base.menu_country_state_partner +msgid "Fed. States" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: view:res.groups:0 +msgid "Access Rules" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_knowledge +msgid "" +"\n" +"Installer for knowledge-based Hidden.\n" +"====================================\n" +"\n" +"Makes the Knowledge Application Configuration available from where you can " +"install\n" +"document and Wiki based Hidden.\n" +" " +msgstr "" + +#. module: base +#: field:res.groups,trans_implied_ids:0 +msgid "Transitively inherits" +msgstr "" + +#. module: base +#: field:ir.default,ref_table:0 +msgid "Table Ref." +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:443 +#, python-format +msgid "Mail delivery failed" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,res_model:0 +#: field:ir.actions.report.xml,model:0 +#: field:ir.actions.server,model_id:0 +#: field:ir.actions.wizard,model:0 +#: field:ir.cron,model:0 +#: field:ir.default,field_tbl:0 +#: field:ir.filters,model_id:0 +#: view:ir.model.access:0 +#: field:ir.model.access,model_id:0 +#: view:ir.model.data:0 +#: view:ir.model.fields:0 +#: field:ir.rule,model_id:0 +#: selection:ir.translation,type:0 +#: view:ir.ui.view:0 +#: field:ir.ui.view,model:0 +#: field:multi_company.default,object_id:0 +#: field:res.log,res_model:0 +#: field:res.request.link,object:0 +#: field:workflow.triggers,model:0 +msgid "Object" +msgstr "" + +#. module: base +#: code:addons/osv.py:147 +#, python-format +msgid "" +"\n" +"\n" +"[object with reference: %s - %s]" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_analytic_plans +msgid "Multiple Analytic Plans" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project_timesheet +msgid "" +"\n" +"Synchronization of project task work entries with timesheet entries.\n" +"====================================================================\n" +"\n" +"This module lets you transfer the entries under tasks defined for Project " +"Management to\n" +"the Timesheet line entries for particular date and particular user with the " +"effect of creating, editing and deleting either ways.\n" +"\n" +" " +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Minute: %(min)s" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_10 +msgid "Scheduler" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_tools +msgid "Base Tools" +msgstr "" + +#. module: base +#: help:res.country,address_format:0 +msgid "" +"You can state here the usual format to use for the addresses belonging to " +"this country.\n" +"\n" +"You can use the python-style string patern with all the field of the address " +"(for example, use '%(street)s' to display the field 'street') plus\n" +" \n" +"%(state_name)s: the name of the state\n" +" \n" +"%(state_code)s: the code of the state\n" +" \n" +"%(country_name)s: the name of the country\n" +" \n" +"%(country_code)s: the code of the country" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_pad +msgid "" +"\n" +"Adds enhanced support for (Ether)Pad attachments in the web client.\n" +"===================================================================\n" +"\n" +"Lets the company customize which Pad installation should be used to link to " +"new pads\n" +"(by default, http://ietherpad.com/).\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_uk +msgid "UK - Accounting" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project_scrum +msgid "" +"\n" +"This module implements all concepts defined by the scrum project management " +"methodology for IT companies.\n" +"=============================================================================" +"============================\n" +"\n" +" * Project with sprints, product owner, scrum master\n" +" * Sprints with reviews, daily meetings, feedbacks\n" +" * Product backlog\n" +" * Sprint backlog\n" +"\n" +"It adds some concepts to the project management module:\n" +" * Mid-term, long-term road-map\n" +" * Customers/functional requests VS technical ones\n" +"\n" +"It also creates a new reporting:\n" +" * Burn-down chart\n" +"\n" +"The scrum projects and tasks inherit from the real projects and\n" +"tasks, so you can continue working on normal tasks that will also\n" +"include tasks from scrum projects.\n" +"\n" +"More information on the methodology:\n" +" * http://controlchaos.com\n" +" " +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:371 +#, python-format +msgid "" +"Changing the type of a column is not yet supported. Please drop it and " +"create it again!" +msgstr "" + +#. module: base +#: field:ir.ui.view_sc,user_id:0 +msgid "User Ref." +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:118 +#, python-format +msgid "Warning !" +msgstr "" + +#. module: base +#: model:res.widget,title:base.google_maps_widget +msgid "Google Maps" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_config +#: model:ir.ui.menu,name:base.menu_config +#: model:ir.ui.menu,name:base.menu_event_config +#: model:ir.ui.menu,name:base.menu_lunch_survey_root +#: model:ir.ui.menu,name:base.menu_marketing_config_association +#: model:ir.ui.menu,name:base.menu_marketing_config_root +#: view:res.company:0 +#: model:res.groups,name:base.group_system +msgid "Configuration" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_in +msgid "India - Accounting" +msgstr "" + +#. module: base +#: field:ir.actions.server,expression:0 +msgid "Loop Expression" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,date_start:0 +msgid "Starting Date" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_gt +msgid "Guatemala - Accounting" +msgstr "" + +#. module: base +#: help:ir.cron,args:0 +msgid "Arguments to be passed to the method, e.g. (uid,)." +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_5 +msgid "Gold Partner" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner +#: field:res.company,partner_id:0 +#: view:res.partner.address:0 +#: field:res.partner.event,partner_id:0 +#: selection:res.partner.title,domain:0 +#: model:res.request.link,name:base.req_link_partner +msgid "Partner" +msgstr "" + +#. module: base +#: field:ir.model.fields,complete_name:0 +#: field:ir.ui.menu,complete_name:0 +msgid "Complete Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.tr +msgid "Turkey" +msgstr "" + +#. module: base +#: model:res.country,name:base.fk +msgid "Falkland Islands" +msgstr "" + +#. module: base +#: model:res.country,name:base.lb +msgid "Lebanon" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +#: field:ir.actions.report.xml,report_type:0 +msgid "Report Type" +msgstr "" + +#. module: base +#: field:ir.actions.todo,state:0 +#: field:ir.module.module,state:0 +#: field:ir.module.module.dependency,state:0 +#: field:publisher_warranty.contract,state:0 +#: view:res.country.state:0 +#: view:res.request:0 +#: field:res.request,state:0 +#: field:workflow.instance,state:0 +#: field:workflow.workitem,state:0 +msgid "State" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr_evaluation +msgid "" +"\n" +"Ability to create employees evaluation.\n" +"=======================================\n" +"\n" +"An evaluation can be created by employee for subordinates,\n" +"juniors as well as his manager.The evaluation is done under a plan\n" +"in which various surveys can be created and it can be defined which\n" +"level of employee hierarchy fills what and final review and evaluation\n" +"is done by the manager.Every evaluation filled by the employees can be " +"viewed\n" +"in the form of pdf file. Implements a dashboard for My Current Evaluations\n" +" " +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Galician / Galego" +msgstr "" + +#. module: base +#: model:res.country,name:base.no +msgid "Norway" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "4. %b, %B ==> Dec, December" +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: model:ir.ui.menu,name:base.menu_view_base_language_install +msgid "Load an Official Translation" +msgstr "" + +#. module: base +#: view:res.currency:0 +msgid "Miscelleanous" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_10 +msgid "Open Source Service Company" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Sinhalese / සිංහල" +msgstr "" + +#. module: base +#: selection:res.request,state:0 +msgid "waiting" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_file:0 +msgid "Report file" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_triggers +msgid "workflow.triggers" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:74 +#, python-format +msgid "Invalid search criterions" +msgstr "" + +#. module: base +#: view:ir.mail_server:0 +msgid "Connection Information" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Created" +msgstr "" + +#. module: base +#: help:ir.actions.wizard,multi:0 +msgid "" +"If set to true, the wizard will not be displayed on the right toolbar of a " +"form view." +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "- type,name,res_id,src,value" +msgstr "" + +#. module: base +#: model:res.country,name:base.hm +msgid "Heard and McDonald Islands" +msgstr "" + +#. module: base +#: help:ir.model.data,name:0 +msgid "" +"External Key/Identifier that can be used for data integration with third-" +"party systems" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_mrp_operations +msgid "" +"\n" +"This module adds state, date_start,date_stop in production order operation " +"lines (in the \"Work Centers\" tab).\n" +"=============================================================================" +"================================\n" +"\n" +"State: draft, confirm, done, cancel\n" +"When finishing/confirming,cancelling production orders set all state lines " +"to the according state\n" +"\n" +"Create menus:\n" +" Manufacturing > Manufacturing > Work Orders\n" +"\n" +"Which is a view on \"Work Centers\" lines in production order.\n" +"\n" +"Add buttons in the form view of production order under workcenter tab:\n" +" * start (set state to confirm), set date_start\n" +" * done (set state to done), set date_stop\n" +" * set to draft (set state to draft)\n" +" * cancel set state to cancel\n" +"\n" +"When the production order becomes \"ready to produce\", operations must\n" +"become 'confirmed'. When the production order is done, all operations\n" +"must become done.\n" +"\n" +"The field delay is the delay(stop date - start date).\n" +"So that we can compare the theoretic delay and real delay.\n" +"\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_auction +msgid "" +"\n" +"This module manages the records of artists, auction articles, buyers and " +"sellers.\n" +"=============================================================================" +"====\n" +"\n" +"It completely manages an auction such as managing bids,\n" +"keeping track of the sold articles along with the paid\n" +"and unpaid objects including delivery of the articles.\n" +"\n" +"The dashboard for auction includes:\n" +" * Latest Objects (list)\n" +" * Latest Deposits (list)\n" +" * Objects Statistics (list)\n" +" * Total Adjudications (graph)\n" +" * Min/Adj/Max (graph)\n" +" * Objects By Day (graph)\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_crypt +msgid "" +"\n" +"Replaces cleartext passwords in the database with a secure hash\n" +"===============================================================\n" +"For your existing user base, the removal of the cleartext\n" +"passwords occurs immediately when you instal base_crypt.\n" +"\n" +"All passwords will be replaced by a secure, salted, cryptographic\n" +"hash, preventing anyone from reading the original password in\n" +"the database.\n" +"\n" +"After installing this module it won't be possible to recover a\n" +"forgotten password for your users, the only solution is for an\n" +"admin to set a new password.\n" +"\n" +"Security Warning\n" +"++++++++++++++++\n" +"Installing this module does not mean you can ignore other security " +"measures,\n" +"as the password is still transmitted unencrypted on the network, unless you\n" +"are using a secure protocol such as XML-RPCS or HTTPS.\n" +"It also does not protect the rest of the content of the database, which may\n" +"contain critical data. Appropriate security measures need to be implemented\n" +"by the system administrator in all areas, such as: protection of database\n" +"backups, system files, remote shell access, physical server access, etc.\n" +"\n" +"Interation with LDAP authentication\n" +"+++++++++++++++++++++++++++++++++++\n" +"This module is currently not compatible with the ``user_ldap`` module and\n" +"will disable LDAP authentication completely if installed at the same time.\n" +"\n" +" " +msgstr "" + +#. module: base +#: field:ir.actions.act_window,view_id:0 +msgid "View Ref." +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_sales_management +msgid "Helps you handle your quotations, sale orders and invoicing." +msgstr "" + +#. module: base +#: field:res.groups,implied_ids:0 +msgid "Inherits" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Selection" +msgstr "" + +#. module: base +#: field:ir.module.module,icon:0 +msgid "Icon URL" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,type:0 +#: field:ir.actions.act_window_close,type:0 +#: field:ir.actions.actions,type:0 +#: field:ir.actions.client,type:0 +#: field:ir.actions.report.xml,type:0 +#: view:ir.actions.server:0 +#: field:ir.actions.server,state:0 +#: field:ir.actions.server,type:0 +#: field:ir.actions.url,type:0 +#: field:ir.actions.wizard,type:0 +msgid "Action Type" +msgstr "" + +#. module: base +#: model:res.country,name:base.vn +msgid "Vietnam" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_syscohada +msgid "" +"This module implements the accounting chart for OHADA area.\n" +" It allows any company or association to manage its financial " +"accounting.\n" +" Countries that use OHADA are the following:\n" +" Benin, Burkina Faso, Cameroon, Central African Republic, Comoros, " +"Congo,\n" +" Ivory Coast, Gabon, Guinea, Guinea Bissau,\n" +" Equatorial Guinea, Mali, Niger, Replica of Democratic Congo, Senegal, " +"Chad, Togo.\n" +" " +msgstr "" + +#. module: base +#: view:base.language.import:0 +#: model:ir.actions.act_window,name:base.action_view_base_import_language +#: model:ir.ui.menu,name:base.menu_view_base_import_language +msgid "Import Translation" +msgstr "" + +#. module: base +#: field:res.partner.bank.type,field_ids:0 +msgid "Type fields" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +#: field:ir.actions.todo,category_id:0 +#: field:ir.module.module,category_id:0 +msgid "Category" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: selection:ir.attachment,type:0 +#: selection:ir.property,type:0 +msgid "Binary" +msgstr "" + +#. module: base +#: field:ir.actions.server,sms:0 +#: selection:ir.actions.server,state:0 +msgid "SMS" +msgstr "" + +#. module: base +#: model:res.country,name:base.cr +msgid "Costa Rica" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_module_doc_rst +msgid "Generate Docs of Modules" +msgstr "" + +#. module: base +#: model:res.company,overdue_msg:base.main_company +msgid "" +"Our records indicate that the following payments are still due. If the " +"amount\n" +"has already been paid, please disregard this notice. However, if you have " +"any\n" +"queries regarding your account, please contact us.\n" +"Thank you in advance.\n" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_users_ldap +msgid "Authentication via LDAP" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +msgid "Conditions" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_other_form +msgid "Other Partners" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_currency_form +#: model:ir.ui.menu,name:base.menu_action_currency_form +#: view:res.currency:0 +msgid "Currencies" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_client +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.client" +msgstr "" + +#. module: base +#: help:ir.values,value:0 +msgid "Default value (pickled) or reference to an action" +msgstr "" + +#. module: base +#: sql_constraint:res.groups:0 +msgid "The name of the group must be unique !" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_report_designer +msgid "" +"\n" +"This module is used along with OpenERP OpenOffice Plugin.\n" +"=========================================================\n" +"\n" +"This module adds wizards to Import/Export .sxw report that\n" +"you can modify in OpenOffice. Once you have modified it you can\n" +"upload the report using the same wizard.\n" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Hour 00->12: %(h12)s" +msgstr "" + +#. module: base +#: help:res.partner.address,active:0 +msgid "Uncheck the active field to hide the contact." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_widget_wizard +msgid "Add a widget for User" +msgstr "" + +#. module: base +#: model:res.country,name:base.dk +msgid "Denmark" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_calendar +msgid "" +"\n" +"This is a full-featured calendar system.\n" +"========================================\n" +"\n" +"It supports:\n" +" - Calendar of events\n" +" - Alerts (create requests)\n" +" - Recurring events\n" +" - Invitations to people\n" +"\n" +"If you need to manage your meetings, you should install the CRM module.\n" +" " +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "Rule definition (domain filter)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_instance +msgid "workflow.instance" +msgstr "" + +#. module: base +#: code:addons/orm.py:471 +#, python-format +msgid "Unknown attribute %s in %s " +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "10. %S ==> 20" +msgstr "" + +#. module: base +#: code:addons/fields.py:122 +#, python-format +msgid "undefined get method !" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Norwegian Bokmål / Norsk bokmål" +msgstr "" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_madam +msgid "Madam" +msgstr "" + +#. module: base +#: model:res.country,name:base.ee +msgid "Estonia" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_board +#: model:ir.ui.menu,name:base.menu_dashboard +msgid "Dashboards" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_procurement +msgid "Procurements" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_hr_payroll_account +msgid "Payroll Accounting" +msgstr "" + +#. module: base +#: help:ir.attachment,type:0 +msgid "Binary File or external URL" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_sale_order_dates +msgid "Dates on Sales Order" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Creation Month" +msgstr "" + +#. module: base +#: model:res.country,name:base.nl +msgid "Netherlands" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_edi +msgid "" +"\n" +"Provides a common EDI platform that other Applications can use\n" +"==============================================================\n" +"\n" +"OpenERP specifies a generic EDI format for exchanging business\n" +"documents between different systems, and provides generic\n" +"mechanisms to import and export them.\n" +"\n" +"More details about OpenERP's EDI format may be found in the\n" +"technical OpenERP documentation at http://doc.openerp.com\n" +" " +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_4 +msgid "Low Level Objects" +msgstr "" + +#. module: base +#: help:ir.values,model:0 +msgid "Model to which this entry applies" +msgstr "" + +#. module: base +#: field:res.country,address_format:0 +msgid "Address Format" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_values +msgid "ir.values" +msgstr "" + +#. module: base +#: model:res.groups,name:base.group_no_one +msgid "Technical Features" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Occitan (FR, post 1500) / Occitan" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:192 +#, python-format +msgid "" +"Here is what we got instead:\n" +" %s" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_model_data +#: view:ir.model.data:0 +#: model:ir.ui.menu,name:base.ir_model_data_menu +msgid "External Identifiers" +msgstr "" + +#. module: base +#: model:res.groups,name:base.group_sale_salesman +msgid "User - Own Leads Only" +msgstr "" + +#. module: base +#: model:res.country,name:base.cd +msgid "Congo, The Democratic Republic of the" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Malayalam / മലയാളം" +msgstr "" + +#. module: base +#: view:res.request:0 +#: field:res.request,body:0 +#: field:res.request.history,req_id:0 +msgid "Request" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.act_ir_actions_todo_form +msgid "" +"The configuration wizards are used to help you configure a new instance of " +"OpenERP. They are launched during the installation of new modules, but you " +"can choose to restart some wizards manually from this menu." +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Portrait" +msgstr "" + +#. module: base +#: field:ir.cron,numbercall:0 +msgid "Number of Calls" +msgstr "" + +#. module: base +#: code:addons/base/res/res_bank.py:189 +#, python-format +msgid "BANK" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +#: field:base.module.upgrade,module_info:0 +msgid "Modules to update" +msgstr "" + +#. module: base +#: help:ir.actions.server,sequence:0 +msgid "" +"Important when you deal with multiple actions, the execution order will be " +"decided based on this, low number is higher priority." +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,header:0 +msgid "Add RML header" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_tr +msgid "" +"\n" +"Türkiye için Tek düzen hesap planı şablonu OpenERP Modülü.\n" +"=============================================================================" +"=\n" +"\n" +"Bu modül kurulduktan sonra, Muhasebe yapılandırma sihirbazı çalışır\n" +" * Sihirbaz sizden hesap planı şablonu, planın kurulacağı şirket,banka " +"hesap bilgileriniz,ilgili para birimi gibi bilgiler isteyecek.\n" +" " +msgstr "" + +#. module: base +#: view:res.config:0 +msgid "Apply" +msgstr "" + +#. module: base +#: field:res.request,trigger_date:0 +msgid "Trigger Date" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Croatian / hrvatski jezik" +msgstr "" + +#. module: base +#: sql_constraint:res.country:0 +msgid "The code of the country must be unique !" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_kanban +msgid "" +"\n" +" OpenERP Web kanban view.\n" +" " +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_project_management_time_tracking +msgid "Time Tracking" +msgstr "" + +#. module: base +#: view:res.partner.category:0 +msgid "Partner Category" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +#: selection:ir.actions.server,state:0 +msgid "Trigger" +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_warehouse_management +msgid "" +"Helps you manage your inventory and main stock operations: delivery orders, " +"receptions, etc." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_module_update +msgid "Update Module" +msgstr "" + +#. module: base +#: view:ir.model.fields:0 +#: field:ir.model.fields,translate:0 +msgid "Translate" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_users_ldap +msgid "" +"\n" +"Adds support for authentication by LDAP server.\n" +"===============================================\n" +"This module allows users to login with their LDAP username and\n" +"password, and will automatically create OpenERP users for them\n" +"on the fly.\n" +"\n" +"**Note**: This module only work on servers who have Python's\n" +"``ldap`` module installed.\n" +"\n" +"Configuration\n" +"+++++++++++++\n" +"After installing this module, you need to configure the LDAP\n" +"parameters in the Configuration tab of the Company details.\n" +"Different companies may have different LDAP servers, as long\n" +"as they have unique usernames (usernames need to be unique in\n" +"OpenERP, even across multiple companies).\n" +"\n" +"Anonymous LDAP binding is also supported (for LDAP servers\n" +"that allow it), by simpling keeping the LDAP user and password\n" +"empty in the LDAP configuration. This does **not** allow\n" +"anonymous authentication for users, it is only for the master\n" +"LDAP account that is used to verify if a user exists before\n" +"attempting to authenticate it.\n" +"\n" +"Securing the connection with STARTTLS is available for LDAP\n" +"servers supporting it, by enabling the TLS option in the LDAP\n" +"configuration.\n" +"\n" +"For further options configuring the LDAP settings, refer to the\n" +"ldap.conf manpage :manpage:`ldap.conf(5)`.\n" +"\n" +"Security Considerations\n" +"+++++++++++++++++++++++\n" +"Users' LDAP passwords are never stored in the OpenERP database,\n" +"the LDAP server is queried whenever a user needs to be\n" +"authenticated. No duplication of the password occurs, and\n" +"passwords are managed in one place only.\n" +"\n" +"OpenERP does not manage password changes in the LDAP, so\n" +"any change of password should be conducted by other means\n" +"in the LDAP directory directly (for LDAP users).\n" +"\n" +"It is also possible to have local OpenERP users in the\n" +"database along with LDAP-authenticated users (the Administrator\n" +"account is one obvious example).\n" +"\n" +"Here is how it works:\n" +"\n" +" * The system first attempts to authenticate users against\n" +" the local OpenERP database ;\n" +" * if this authentication fails (for example because the\n" +" user has no local password), the system then attempts\n" +" to authenticate against LDAP ;\n" +"\n" +"As LDAP users have blank passwords by default in the local\n" +"OpenERP database (which means no access), the first step\n" +"always fails and the LDAP server is queried to do the\n" +"authentication.\n" +"\n" +"Enabling STARTTLS ensures that the authentication query to the\n" +"LDAP server is encrypted.\n" +"\n" +"User Template\n" +"+++++++++++++\n" +"In the LDAP configuration on the Company form, it is possible to\n" +"select a *User Template*. If set, this user will be used as\n" +"template to create the local users whenever someone authenticates\n" +"for the first time via LDAP authentication.\n" +"This allows pre-setting the default groups and menus of the\n" +"first-time users.\n" +"\n" +"**Warning**: if you set a password for the user template,\n" +"this password will be assigned as local password for each new\n" +"LDAP user, effectively setting a *master password* for these\n" +"users (until manually changed). You usually do not want this.\n" +"One easy way to setup a template user is to login once with\n" +"a valid LDAP user, let OpenERP create a blank local user with the\n" +"same login (and a blank password), then rename this new user\n" +"to a username that does not exist in LDAP, and setup its\n" +"groups the way you want.\n" +"\n" +"Interaction with base_crypt\n" +"+++++++++++++++++++++++++++\n" +"The base_crypt module is not compatible with this module, and\n" +"will disable LDAP authentication if installed at the same time.\n" +"\n" +" " +msgstr "" + +#. module: base +#: field:res.request.history,body:0 +msgid "Body" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:199 +#, python-format +msgid "Connection test succeeded!" +msgstr "" + +#. module: base +#: view:partner.massmail.wizard:0 +msgid "Send Email" +msgstr "" + +#. module: base +#: field:res.users,menu_id:0 +msgid "Menu Action" +msgstr "" + +#. module: base +#: help:ir.model.fields,selection:0 +msgid "" +"List of options for a selection field, specified as a Python expression " +"defining a list of (key, label) pairs. For example: " +"[('blue','Blue'),('yellow','Yellow')]" +msgstr "" + +#. module: base +#: selection:base.language.export,state:0 +msgid "choose" +msgstr "" + +#. module: base +#: help:ir.model,osv_memory:0 +msgid "" +"Indicates whether this object model lives in memory only, i.e. is not " +"persisted (osv.osv_memory)" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:415 +#, python-format +msgid "" +"Please define at least one SMTP server, or provide the SMTP parameters " +"explicitly." +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Filter on my documents" +msgstr "" + +#. module: base +#: help:ir.actions.server,code:0 +msgid "" +"Python code to be executed if condition is met.\n" +"It is a Python block that can use the same values as for the condition field" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_supplier_form +#: model:ir.ui.menu,name:base.menu_procurement_management_supplier_name +#: view:res.partner:0 +msgid "Suppliers" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "Register" +msgstr "" + +#. module: base +#: field:res.request,ref_doc2:0 +msgid "Document Ref 2" +msgstr "" + +#. module: base +#: field:res.request,ref_doc1:0 +msgid "Document Ref 1" +msgstr "" + +#. module: base +#: model:res.country,name:base.ga +msgid "Gabon" +msgstr "" + +#. module: base +#: model:res.groups,name:base.group_multi_company +msgid "Multi Companies" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: view:ir.rule:0 +#: view:res.groups:0 +#: model:res.groups,name:base.group_erp_manager +#: view:res.users:0 +msgid "Access Rights" +msgstr "" + +#. module: base +#: model:res.country,name:base.gl +msgid "Greenland" +msgstr "" + +#. module: base +#: model:res.groups,name:base.group_sale_salesman_all_leads +msgid "User - All Leads" +msgstr "" + +#. module: base +#: field:res.partner.bank,acc_number:0 +msgid "Account Number" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"Example: GLOBAL_RULE_1 AND GLOBAL_RULE_2 AND ( (GROUP_A_RULE_1 OR " +"GROUP_A_RULE_2) OR (GROUP_B_RULE_1 OR GROUP_B_RULE_2) )" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_th +msgid "Thailand - Accounting" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "1. %c ==> Fri Dec 5 18:25:20 2008" +msgstr "" + +#. module: base +#: model:res.country,name:base.nc +msgid "New Caledonia (French)" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_mrp_jit +msgid "" +"\n" +"This module allows Just In Time computation of procurement orders.\n" +"==================================================================\n" +"\n" +"If you install this module, you will not have to run the regular " +"procurement\n" +"scheduler anymore (but you still need to run the minimum order point rule\n" +"scheduler, or for example let it run daily.)\n" +"All procurement orders will be processed immediately, which could in some\n" +"cases entail a small performance impact.\n" +"\n" +"It may also increase your stock size because products are reserved as soon\n" +"as possible and the scheduler time range is not taken into account anymore.\n" +"In that case, you can not use priorities any more on the different picking.\n" +"\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.cy +msgid "Cyprus" +msgstr "" + +#. module: base +#: field:ir.actions.server,subject:0 +#: field:partner.massmail.wizard,subject:0 +#: field:res.request,name:0 +msgid "Subject" +msgstr "" + +#. module: base +#: selection:res.currency,position:0 +msgid "Before Amount" +msgstr "" + +#. module: base +#: field:res.request,act_from:0 +#: field:res.request.history,act_from:0 +msgid "From" +msgstr "" + +#. module: base +#: view:res.users:0 +msgid "Preferences" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_consumers0 +msgid "Consumers" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Set Bank Accounts" +msgstr "" + +#. module: base +#: field:ir.actions.client,tag:0 +msgid "Client action tag" +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:189 +#, python-format +msgid "You cannot delete the language which is User's Preferred Language !" +msgstr "" + +#. module: base +#: field:ir.values,model_id:0 +msgid "Model (change only)" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_marketing_campaign_crm_demo +msgid "" +"\n" +"Demo data for the module marketing_campaign.\n" +"============================================\n" +"\n" +"Creates demo data like leads, campaigns and segments for the module " +"marketing_campaign.\n" +" " +msgstr "" + +#. module: base +#: selection:ir.actions.act_window.view,view_mode:0 +#: selection:ir.ui.view,type:0 +msgid "Kanban" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:251 +#, python-format +msgid "" +"The Selection Options expression is must be in the [('key','Label'), ...] " +"format!" +msgstr "" + +#. module: base +#: view:ir.filters:0 +msgid "Current User" +msgstr "" + +#. module: base +#: field:res.company,company_registry:0 +msgid "Company Registry" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Miscellaneous" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_ir_mail_server_list +#: view:ir.mail_server:0 +#: model:ir.ui.menu,name:base.menu_mail_servers +msgid "Outgoing Mail Servers" +msgstr "" + +#. module: base +#: model:res.country,name:base.cn +msgid "China" +msgstr "" + +#. module: base +#: help:ir.actions.server,wkf_model_id:0 +msgid "" +"The object that should receive the workflow signal (must have an associated " +"workflow)" +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_account_voucher +msgid "" +"Allows you to create your invoices and track the payments. It is an easier " +"version of the accounting module for managers who are not accountants." +msgstr "" + +#. module: base +#: model:res.country,name:base.eh +msgid "Western Sahara" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_account_voucher +msgid "Invoicing & Payments" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_company_form +msgid "" +"Create and manage the companies that will be managed by OpenERP from here. " +"Shops or subsidiaries can be created and maintained from here." +msgstr "" + +#. module: base +#: model:res.country,name:base.id +msgid "Indonesia" +msgstr "" + +#. module: base +#: view:base.update.translations:0 +msgid "" +"This wizard will detect new terms to translate in the application, so that " +"you can then add translations manually or perform a complete export (as a " +"template for a new language example)." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_ch +msgid "" +"\n" +"Swiss localisation :\n" +" - DTA generation for a lot of payment types\n" +" - BVR management (number generation, report, etc..)\n" +" - Import account move from the bank file (like v11 etc..)\n" +" - Simplify the way you handle the bank statement for reconciliation\n" +"\n" +"You can also add ZIP and bank completion with:\n" +" - l10n_ch_zip\n" +" - l10n_ch_bank\n" +" \n" +" Author: Camptocamp SA\n" +" Donors: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA\n" +"\n" +"------------------------------------------------------------------------\n" +"\n" +"Module incluant la localisation Suisse de TinyERP revu et corrigé par " +"Camptocamp. Cette nouvelle version\n" +"comprend la gestion et l'émissionde BVR, le paiement électronique via DTA " +"(pour les banques, le système postal est en développement)\n" +"et l'import du relevé de compte depuis la banque de manière automatisée.\n" +"De plus, nous avons intégré la définition de toutes les banques " +"Suisses(adresse, swift et clearing).\n" +"\n" +"Par ailleurs, conjointement à ce module, nous proposons la complétion NPA:\n" +"\n" +"Vous pouvez ajouter la completion des banques et des NPA avec with:\n" +" - l10n_ch_zip\n" +" - l10n_ch_bank\n" +" \n" +" Auteur: Camptocamp SA\n" +" Donateurs: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA\n" +"\n" +"--------------------------------------------------------------------------\n" +"TODO :\n" +"- Implement bvr import partial reconciliation\n" +"- Replace wizard by osv_memory when possible\n" +"- Add mising HELP\n" +"- Finish code comment\n" +"- Improve demo data\n" +"\n" +"\n" +msgstr "" + +#. module: base +#: help:multi_company.default,expression:0 +msgid "" +"Expression, must be True to match\n" +"use context.get or user (browse)" +msgstr "" + +#. module: base +#: model:res.country,name:base.bg +msgid "Bulgaria" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "Publisher warranty contract successfully registered!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ao +msgid "Angola" +msgstr "" + +#. module: base +#: model:res.country,name:base.tf +msgid "French Southern Territories" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_currency +#: field:res.company,currency_id:0 +#: field:res.company,currency_ids:0 +#: view:res.currency:0 +#: field:res.currency,name:0 +#: field:res.currency.rate,currency_id:0 +msgid "Currency" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "5. %y, %Y ==> 08, 2008" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_ltd +msgid "ltd" +msgstr "" + +#. module: base +#: field:res.log,res_id:0 +msgid "Object ID" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Landscape" +msgstr "" + +#. module: base +#: model:ir.actions.todo.category,name:base.category_administration_config +#: model:ir.module.category,name:base.module_category_administration +msgid "Administration" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "Click on Update below to start the process..." +msgstr "" + +#. module: base +#: model:res.country,name:base.ir +msgid "Iran" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_widget_user_act_window +#: model:ir.ui.menu,name:base.menu_res_widget_user_act_window +msgid "Widgets per User" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_form +#: model:ir.ui.menu,name:base.menu_publisher_warranty_contract +msgid "Contracts" +msgstr "" + +#. module: base +#: field:base.language.export,state:0 +#: field:ir.ui.menu,icon_pict:0 +#: field:publisher_warranty.contract.wizard,state:0 +msgid "unknown" +msgstr "" + +#. module: base +#: field:res.currency,symbol:0 +msgid "Symbol" +msgstr "" + +#. module: base +#: help:res.users,login:0 +msgid "Used to log into the system" +msgstr "" + +#. module: base +#: view:base.update.translations:0 +msgid "Synchronize Translation" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_module_quality +msgid "" +"\n" +"The aim of this module is to check the quality of other modules.\n" +"================================================================\n" +"\n" +"It defines a wizard on the list of modules in OpenERP, which allows you to\n" +"evaluate them on different criteria such as: the respect of OpenERP coding\n" +"standards, the speed efficiency...\n" +"\n" +"This module also provides generic framework to define your own quality " +"test.\n" +"For further info, coders may take a look into base_module_quality\\" +"README.txt\n" +"\n" +"WARNING: This module cannot work as a ZIP file, you must unzip it before\n" +"using it, otherwise it may crash.\n" +" " +msgstr "" + +#. module: base +#: field:res.partner.bank,bank_name:0 +msgid "Bank Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.ki +msgid "Kiribati" +msgstr "" + +#. module: base +#: model:res.country,name:base.iq +msgid "Iraq" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_association +#: model:ir.ui.menu,name:base.menu_association +msgid "Association" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_stock_no_autopicking +msgid "" +"\n" +"This module allows an intermediate picking process to provide raw materials " +"to production orders.\n" +"=============================================================================" +"====================\n" +"\n" +"One example of usage of this module is to manage production made by your\n" +"suppliers (sub-contracting). To achieve this, set the assembled product\n" +"which is sub-contracted to \"No Auto-Picking\" and put the location of the\n" +"supplier in the routing of the assembly operation.\n" +" " +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Action to Launch" +msgstr "" + +#. module: base +#: help:res.users,context_lang:0 +msgid "" +"The default language used in the graphical user interface, when translations " +"are available. To add a new language, you can use the 'Load an Official " +"Translation' wizard available from the 'Administration' menu." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_es +msgid "" +"\n" +"Spanish Charts of Accounts (PGCE 2008).\n" +"=======================================\n" +"\n" +"* Defines the following chart of account templates:\n" +" * Spanish General Chart of Accounts 2008.\n" +" * Spanish General Chart of Accounts 2008 for small and medium " +"companies.\n" +"* Defines templates for sale and purchase VAT.\n" +"* Defines tax code templates.\n" +"\n" +"Note: You should install the l10n_ES_account_balance_report module\n" +"for yearly account reporting (balance, profit & losses).\n" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_sequence_type +msgid "ir.sequence.type" +msgstr "" + +#. module: base +#: selection:base.language.export,format:0 +msgid "CSV File" +msgstr "" + +#. module: base +#: code:addons/base/res/res_company.py:154 +#, python-format +msgid "Phone: " +msgstr "" + +#. module: base +#: field:res.company,account_no:0 +msgid "Account No." +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:187 +#, python-format +msgid "Base Language 'en_US' can not be deleted !" +msgstr "" + +#. module: base +#: selection:ir.model,state:0 +msgid "Base Object" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Dependencies :" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_purchase_analytic_plans +msgid "" +"\n" +"The base module to manage analytic distribution and purchase orders.\n" +"====================================================================\n" +"\n" +"Allows the user to maintain several analysis plans. These let you split\n" +"a line on a supplier purchase order into several accounts and analytic " +"plans.\n" +" " +msgstr "" + +#. module: base +#: field:res.company,vat:0 +msgid "Tax ID" +msgstr "" + +#. module: base +#: field:ir.model.fields,field_description:0 +msgid "Field Label" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,report_rml:0 +msgid "" +"The path to the main report file (depending on Report Type) or NULL if the " +"content is in another data field" +msgstr "" + +#. module: base +#: model:res.country,name:base.dj +msgid "Djibouti" +msgstr "" + +#. module: base +#: field:ir.translation,value:0 +msgid "Translation Value" +msgstr "" + +#. module: base +#: model:res.country,name:base.ag +msgid "Antigua and Barbuda" +msgstr "" + +#. module: base +#: code:addons/orm.py:3669 +#, python-format +msgid "" +"Operation prohibited by access rules, or performed on an already deleted " +"document (Operation: %s, Document type: %s)." +msgstr "" + +#. module: base +#: model:res.country,name:base.zr +msgid "Zaire" +msgstr "" + +#. module: base +#: field:ir.translation,res_id:0 +#: field:workflow.instance,res_id:0 +#: field:workflow.triggers,res_id:0 +msgid "Resource ID" +msgstr "" + +#. module: base +#: view:ir.cron:0 +#: field:ir.model,info:0 +msgid "Information" +msgstr "" + +#. module: base +#: view:res.widget.user:0 +msgid "User Widgets" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "Update Module List" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:755 +#: code:addons/base/res/res_users.py:892 +#: selection:res.partner.address,type:0 +#: view:res.users:0 +#, python-format +msgid "Other" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Reply" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Turkish / Türkçe" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project_long_term +msgid "" +"\n" +"Long Term Project management module that tracks planning, scheduling, " +"resources allocation.\n" +"=============================================================================" +"==============\n" +"\n" +"Features\n" +"--------\n" +" * Manage Big project.\n" +" * Define various Phases of Project.\n" +" * Compute Phase Scheduling: Compute start date and end date of the " +"phases which are in draft,open and pending state of the project given.\n" +" If no project given then all the draft,open and pending state phases " +"will be taken.\n" +" * Compute Task Scheduling: This works same as the scheduler button on " +"project.phase. It takes the project as argument and computes all the " +"open,draft and pending tasks.\n" +" * Schedule Tasks: All the tasks which are in draft,pending and open " +"state are scheduled with taking the phase's start date\n" +" " +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_activity_form +#: model:ir.ui.menu,name:base.menu_workflow_activity +#: view:workflow:0 +#: field:workflow,activities:0 +msgid "Activities" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_product +msgid "Products & Pricelists" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,auto_refresh:0 +msgid "Auto-Refresh" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:74 +#, python-format +msgid "The osv_memory field can only be compared with = and != operator." +msgstr "" + +#. module: base +#: selection:ir.ui.view,type:0 +msgid "Diagram" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_es +msgid "Spanish - Accounting (PGCE 2008)" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_stock_no_autopicking +msgid "Picking Before Manufacturing" +msgstr "" + +#. module: base +#: model:res.country,name:base.wf +msgid "Wallis and Futuna Islands" +msgstr "" + +#. module: base +#: help:multi_company.default,name:0 +msgid "Name it to easily find a record" +msgstr "" + +#. module: base +#: model:res.country,name:base.gr +msgid "Greece" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_calendar +msgid "web calendar" +msgstr "" + +#. module: base +#: field:ir.model.data,name:0 +msgid "External Identifier" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.grant_menu_access +#: model:ir.ui.menu,name:base.menu_grant_menu_access +msgid "Menu Items" +msgstr "" + +#. module: base +#: constraint:ir.rule:0 +msgid "Rules are not supported for osv_memory objects !" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_event +#: model:ir.ui.menu,name:base.menu_event_main +msgid "Events Organisation" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_sequence_actions +#: model:ir.ui.menu,name:base.menu_custom_action +#: model:ir.ui.menu,name:base.menu_ir_sequence_actions +#: model:ir.ui.menu,name:base.next_id_6 +#: view:workflow.activity:0 +msgid "Actions" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_delivery +msgid "Delivery Costs" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_cron.py:293 +#, python-format +msgid "" +"This cron task is currently being executed and may not be modified, please " +"try again in a few minutes" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_product_expiry +msgid "" +"\n" +"Track different dates on products and production lots.\n" +"======================================================\n" +"\n" +"Following dates can be tracked:\n" +" - end of life\n" +" - best before date\n" +" - removal date\n" +" - alert date\n" +"\n" +"Used, for example, in food industries." +msgstr "" + +#. module: base +#: field:ir.exports.line,export_id:0 +msgid "Export" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_nl +msgid "Netherlands - Accounting" +msgstr "" + +#. module: base +#: field:res.bank,bic:0 +#: field:res.partner.bank,bank_bic:0 +msgid "Bank Identifier Code" +msgstr "" + +#. module: base +#: model:res.country,name:base.tm +msgid "Turkmenistan" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_process +msgid "" +"\n" +" OpenERP Web process view.\n" +" " +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_account_chart +msgid "" +"\n" +"Remove minimal account chart.\n" +"=============================\n" +"\n" +"Deactivates minimal chart of accounts.\n" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:653 +#: code:addons/base/ir/ir_actions.py:748 +#: code:addons/base/ir/ir_actions.py:751 +#: code:addons/base/ir/ir_model.py:139 +#: code:addons/base/ir/ir_model.py:236 +#: code:addons/base/ir/ir_model.py:250 +#: code:addons/base/ir/ir_model.py:264 +#: code:addons/base/ir/ir_model.py:282 +#: code:addons/base/ir/ir_model.py:287 +#: code:addons/base/ir/ir_model.py:290 +#: code:addons/base/module/module.py:255 +#: code:addons/base/module/module.py:298 +#: code:addons/base/module/module.py:302 +#: code:addons/base/module/module.py:308 +#: code:addons/base/module/module.py:390 +#: code:addons/base/module/module.py:408 +#: code:addons/base/module/module.py:423 +#: code:addons/base/module/module.py:519 +#: code:addons/base/module/module.py:622 +#: code:addons/base/publisher_warranty/publisher_warranty.py:124 +#: code:addons/base/publisher_warranty/publisher_warranty.py:163 +#: code:addons/base/publisher_warranty/publisher_warranty.py:295 +#: code:addons/base/res/res_currency.py:190 +#: code:addons/base/res/res_users.py:86 +#: code:addons/base/res/res_users.py:95 +#: code:addons/custom.py:555 +#: code:addons/orm.py:791 +#: code:addons/orm.py:3704 +#, python-format +msgid "Error" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_base_crypt +msgid "DB Password Encryption" +msgstr "" + +#. module: base +#: help:workflow.transition,act_to:0 +msgid "The destination activity." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_check_writing +msgid "Check writing" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_sale_layout +msgid "" +"\n" +"This module provides features to improve the layout of the Sales Order.\n" +"=======================================================================\n" +"\n" +"It gives you the possibility to\n" +" * order all the lines of a sales order\n" +" * add titles, comment lines, sub total lines\n" +" * draw horizontal lines and put page breaks\n" +"\n" +" " +msgstr "" + +#. module: base +#: view:base.module.update:0 +#: view:base.module.upgrade:0 +#: view:base.update.translations:0 +msgid "Update" +msgstr "" + +#. module: base +#: model:ir.actions.report.xml,name:base.ir_module_reference_print +msgid "Technical guide" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Address Information" +msgstr "" + +#. module: base +#: model:res.country,name:base.tz +msgid "Tanzania" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Danish / Dansk" +msgstr "" + +#. module: base +#: selection:ir.model.fields,select_level:0 +msgid "Advanced Search (deprecated)" +msgstr "" + +#. module: base +#: model:res.country,name:base.cx +msgid "Christmas Island" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web_livechat +msgid "Live Chat Support" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Other Actions Configuration" +msgstr "" + +#. module: base +#: selection:ir.module.module.dependency,state:0 +msgid "Uninstallable" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_dashboard +msgid "" +"\n" +" OpenERP Web dashboard view.\n" +" " +msgstr "" + +#. module: base +#: view:res.partner:0 +msgid "Supplier Partners" +msgstr "" + +#. module: base +#: view:res.config.installer:0 +msgid "Install Modules" +msgstr "" + +#. module: base +#: view:ir.ui.view:0 +msgid "Extra Info" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_be_hr_payroll +msgid "" +"\n" +"Belgian Payroll Rules\n" +"=====================\n" +"\n" +" * Employee Details\n" +" * Employee Contracts\n" +" * Passport based Contract\n" +" * Allowances / Deductions\n" +" * Allow to configure Basic / Grows / Net Salary\n" +" * Employee Payslip\n" +" * Monthly Payroll Register\n" +" * Integrated with Holiday Management\n" +" * Salary Maj, ONSS, Withholding Tax, Child Allowance, ...\n" +" " +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_partner_wizard_ean_check +msgid "Ean Check" +msgstr "" + +#. module: base +#: view:res.partner:0 +msgid "Customer Partners" +msgstr "" + +#. module: base +#: sql_constraint:res.users:0 +msgid "You can not have two users with the same login !" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_request_history +msgid "res.request.history" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_multi_company_default +msgid "Default multi company" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Send" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_process +msgid "" +"\n" +"This module shows the basic processes involved in the selected modules and " +"in the sequence they occur.\n" +"=============================================================================" +"=========================\n" +"\n" +"Note: This applies to the modules containing modulename_process_xml\n" +"e.g product/process/product_process_xml\n" +"\n" +" " +msgstr "" + +#. module: base +#: field:res.users,menu_tips:0 +msgid "Menu Tips" +msgstr "" + +#. module: base +#: field:ir.translation,src:0 +msgid "Source" +msgstr "" + +#. module: base +#: help:res.partner.address,partner_id:0 +msgid "Keep empty for a private address, not related to partner." +msgstr "" + +#. module: base +#: model:res.country,name:base.vu +msgid "Vanuatu" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Internal Header/Footer" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_crm +msgid "CRM" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:59 +#, python-format +msgid "" +"Save this document to a .tgz file. This archive containt UTF-8 %s files and " +"may be uploaded to launchpad." +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "Start configuration" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "_Export" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_followup +msgid "Followup Management" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_fr +msgid "" +"\n" +"This is the module to manage the accounting chart for France in OpenERP.\n" +"========================================================================\n" +"\n" +"Credits: Sistheo Zeekom CrysaLEAD\n" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Catalan / Català" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Greek / Ελληνικά" +msgstr "" + +#. module: base +#: model:res.country,name:base.do +msgid "Dominican Republic" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Serbian (Cyrillic) / српски" +msgstr "" + +#. module: base +#: code:addons/orm.py:2527 +#, python-format +msgid "" +"Invalid group_by specification: \"%s\".\n" +"A group_by specification must be a list of valid fields." +msgstr "" + +#. module: base +#: selection:ir.mail_server,smtp_encryption:0 +msgid "TLS (STARTTLS)" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,usage:0 +msgid "Used to filter menu and home actions from the user form." +msgstr "" + +#. module: base +#: model:res.country,name:base.sa +msgid "Saudi Arabia" +msgstr "" + +#. module: base +#: help:res.company,rml_header1:0 +msgid "Appears by default on the top right corner of your printed documents." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_fetchmail_crm_claim +msgid "eMail Gateway for CRM Claim" +msgstr "" + +#. module: base +#: help:res.partner,supplier:0 +msgid "" +"Check this box if the partner is a supplier. If it's not checked, purchase " +"people will not see it when encoding a purchase order." +msgstr "" + +#. module: base +#: field:ir.actions.server,trigger_obj_id:0 +#: field:ir.model.fields,relation_field:0 +msgid "Relation Field" +msgstr "" + +#. module: base +#: view:res.partner.event:0 +msgid "Event Logs" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_configuration.py:38 +#, python-format +msgid "System Configuration done" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Create / Write / Copy" +msgstr "" + +#. module: base +#: field:workflow.triggers,instance_id:0 +msgid "Destination Instance" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,multi:0 +#: field:ir.actions.wizard,multi:0 +msgid "Action on Multiple Doc." +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "https://translations.launchpad.net/openobject" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "Export Translations" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_xml:0 +msgid "XML path" +msgstr "" + +#. module: base +#: help:ir.sequence,implementation:0 +msgid "" +"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)." +msgstr "" + +#. module: base +#: model:res.country,name:base.gn +msgid "Guinea" +msgstr "" + +#. module: base +#: model:res.country,name:base.lu +msgid "Luxembourg" +msgstr "" + +#. module: base +#: selection:res.request,priority:0 +msgid "Low" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_ui_menu.py:284 +#, python-format +msgid "Error ! You can not create recursive Menu." +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"3. If user belongs to several groups, the results from step 2 are combined " +"with logical OR operator" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_auth_openid +msgid "Allow users to login through OpenID." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_payment +msgid "Suppliers Payment Management" +msgstr "" + +#. module: base +#: model:res.country,name:base.sv +msgid "El Salvador" +msgstr "" + +#. module: base +#: field:res.bank,phone:0 +#: field:res.company,phone:0 +#: field:res.partner,phone:0 +#: field:res.partner.address,phone:0 +msgid "Phone" +msgstr "" + +#. module: base +#: field:res.groups,menu_access:0 +msgid "Access Menu" +msgstr "" + +#. module: base +#: model:res.country,name:base.th +msgid "Thailand" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_report_creator +msgid "" +"\n" +"This module allows you to create any statistic report on several objects.\n" +"=========================================================================\n" +"\n" +"It's an SQL query builder and browser\n" +"for end-users.\n" +"\n" +"After installing the module, it adds a menu to define a custom report in\n" +"the Administration / Customization / Reporting menu.\n" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_report_designer +msgid "Report Designer" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_address_book +#: model:ir.ui.menu,name:base.menu_config_address_book +#: model:ir.ui.menu,name:base.menu_procurement_management_supplier +msgid "Address Book" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_ma +msgid "" +"\n" +"This is the base module to manage the accounting chart for Maroc.\n" +"=================================================================\n" +"\n" +"Ce Module charge le modèle du plan de comptes standard Marocain et permet " +"de générer les états comptables aux normes marocaines (Bilan, CPC (comptes " +"de produits et charges), balance générale à 6 colonnes, Grand livre " +"cumulatif...). L'intégration comptable a été validé avec l'aide du Cabinet " +"d'expertise comptable Seddik au cours du troisième trimestre 2010" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_calendar +msgid "" +"\n" +" OpenERP Web calendar view.\n" +" " +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_crm_config_lead +msgid "Leads & Opportunities" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Romanian / română" +msgstr "" + +#. module: base +#: view:res.log:0 +msgid "System Logs" +msgstr "" + +#. module: base +#: selection:workflow.activity,join_mode:0 +#: selection:workflow.activity,split_mode:0 +msgid "And" +msgstr "" + +#. module: base +#: help:ir.values,res_id:0 +msgid "" +"Database identifier of the record to which this applies. 0 = for all records" +msgstr "" + +#. module: base +#: field:ir.model.fields,relation:0 +msgid "Object Relation" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_account_voucher +msgid "eInvoicing & Payments" +msgstr "" + +#. module: base +#: view:ir.rule:0 +#: view:res.partner:0 +msgid "General" +msgstr "" + +#. module: base +#: model:res.country,name:base.uz +msgid "Uzbekistan" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_act_window +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.act_window" +msgstr "" + +#. module: base +#: field:ir.rule,perm_create:0 +msgid "Apply For Create" +msgstr "" + +#. module: base +#: model:res.country,name:base.vi +msgid "Virgin Islands (USA)" +msgstr "" + +#. module: base +#: model:res.country,name:base.tw +msgid "Taiwan" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_currency_rate +msgid "Currency Rate" +msgstr "" + +#. module: base +#: field:workflow,osv:0 +#: field:workflow.instance,res_type:0 +msgid "Resource Object" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_crm_helpdesk +msgid "Helpdesk" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.grant_menu_access +msgid "" +"Manage and customize the items available and displayed in your OpenERP " +"system menu. You can delete an item by clicking on the box at the beginning " +"of each line and then delete it through the button that appeared. Items can " +"be assigned to specific groups in order to make them accessible to some " +"users within the system." +msgstr "" + +#. module: base +#: field:ir.ui.view,field_parent:0 +msgid "Child Field" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "Detailed algorithm:" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,usage:0 +#: field:ir.actions.act_window_close,usage:0 +#: field:ir.actions.actions,usage:0 +#: field:ir.actions.client,usage:0 +#: field:ir.actions.report.xml,usage:0 +#: field:ir.actions.server,usage:0 +#: field:ir.actions.wizard,usage:0 +msgid "Action Usage" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_workitem +msgid "workflow.workitem" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_profile_tools +msgid "Miscellaneous Tools" +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_tools +msgid "" +"Lets you install various interesting but non-essential tools like Survey, " +"Lunch and Ideas box." +msgstr "" + +#. module: base +#: selection:ir.module.module,state:0 +msgid "Not Installable" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_product +msgid "" +"\n" +"This is the base module for managing products and pricelists in OpenERP.\n" +"========================================================================\n" +"\n" +"Products support variants, different pricing methods, suppliers\n" +"information, make to stock/order, different unit of measures,\n" +"packaging and properties.\n" +"\n" +"Pricelists support:\n" +" * Multiple-level of discount (by product, category, quantities)\n" +" * Compute price based on different criteria:\n" +" * Other pricelist,\n" +" * Cost price,\n" +" * List price,\n" +" * Supplier price, ...\n" +"\n" +"Pricelists preferences by product and/or partners.\n" +"\n" +"Print product labels with barcode.\n" +" " +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "View :" +msgstr "" + +#. module: base +#: field:ir.model.fields,view_load:0 +msgid "View Auto-Load" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:264 +#, python-format +msgid "You cannot remove the field '%s' !" +msgstr "" + +#. module: base +#: view:res.users:0 +msgid "Allowed Companies" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_de +msgid "Deutschland - Accounting" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_auction +msgid "Auction Houses" +msgstr "" + +#. module: base +#: field:ir.ui.menu,web_icon:0 +msgid "Web Icon File" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +#: model:ir.ui.menu,name:base.menu_view_base_module_upgrade +msgid "Apply Scheduled Upgrades" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_sale_journal +msgid "Invoicing Journals" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Persian / فارس" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "View Ordering" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_upgrade.py:95 +#, python-format +msgid "Unmet dependency !" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "" +"Supported file formats: *.csv (Comma-separated values) or *.po (GetText " +"Portable Objects)" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:534 +#, python-format +msgid "" +"You can not delete this document (%s) ! Be sure your user belongs to one of " +"these groups: %s." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_livechat +msgid "" +"\n" +"Enable live chat support for those who have a maintenance contract.\n" +"===================================================================\n" +"\n" +"Add \"Support\" button in header from where you can access OpenERP Support.\n" +" " +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_module_configuration +msgid "base.module.configuration" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web +msgid "" +"\n" +" OpenERP Web core module.\n" +" This module provides the core of the OpenERP web client.\n" +" " +msgstr "" + +#. module: base +#: sql_constraint:res.country:0 +msgid "The name of the country must be unique !" +msgstr "" + +#. module: base +#: field:base.language.export,name:0 +#: field:ir.attachment,datas_fname:0 +msgid "Filename" +msgstr "" + +#. module: base +#: field:ir.model,access_ids:0 +#: view:ir.model.access:0 +msgid "Access" +msgstr "" + +#. module: base +#: model:res.country,name:base.sk +msgid "Slovak Republic" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.publisher_warranty +msgid "Publisher Warranty" +msgstr "" + +#. module: base +#: model:res.country,name:base.aw +msgid "Aruba" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_import.py:60 +#, python-format +msgid "File is not a zip file!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ar +msgid "Argentina" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_project_issue +msgid "" +"\n" +"This module provides Issues/Bugs Management in Project.\n" +"=======================================================\n" +"\n" +"OpenERP allows you to manage the issues you might face in a project\n" +"like bugs in a system, client complaints or material breakdowns. A\n" +"list view allows the manager to quickly check the issues, assign them\n" +"and decide on their status as they evolve.\n" +" " +msgstr "" + +#. module: base +#: field:res.groups,full_name:0 +msgid "Group Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.bh +msgid "Bahrain" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_web +msgid "web" +msgstr "" + +#. module: base +#: field:res.bank,fax:0 +#: field:res.company,fax:0 +#: field:res.partner.address,fax:0 +msgid "Fax" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_l10n_nl +msgid "" +"\n" +"This is the module to manage the accounting chart for Netherlands in " +"OpenERP.\n" +"=============================================================================" +"\n" +"\n" +"Read changelog in file __openerp__.py for version information.\n" +"Dit is een basismodule om een uitgebreid grootboek- en BTW schema voor " +"Nederlandse bedrijven te installeren in OpenERP versie 5.\n" +"\n" +"De BTW rekeningen zijn waar nodig gekoppeld om de juiste rapportage te " +"genereren, denk b.v. aan intracommunautaire verwervingen\n" +"waarbij u 19% BTW moet opvoeren, maar tegelijkertijd ook 19% als voorheffing " +"weer mag aftrekken.\n" +"\n" +"Na installatie van deze module word de configuratie wizard voor " +"\"Accounting\" aangeroepen.\n" +" * U krijgt een lijst met grootboektemplates aangeboden waarin zich ook " +"het Nederlandse grootboekschema bevind.\n" +"\n" +" * Als de configuratie wizard start, wordt u gevraagd om de naam van uw " +"bedrijf in te voeren, welke grootboekschema te installeren, uit hoeveel " +"cijfers een grootboekrekening mag bestaan, het rekeningnummer van uw bank en " +"de currency om Journalen te creeren.\n" +"\n" +"Let op!! -> De template van het Nederlandse rekeningschema is opgebouwd uit " +"4 cijfers. Dit is het minimale aantal welk u moet invullen, u mag het aantal " +"verhogen. De extra cijfers worden dan achter het rekeningnummer aangevult " +"met \"nullen\"\n" +"\n" +" * Dit is dezelfe configuratie wizard welke aangeroepen kan worden via " +"Financial Management/Configuration/Financial Accounting/Financial " +"Accounts/Generate Chart of Accounts from a Chart Template.\n" +"\n" +" " +msgstr "" + +#. module: base +#: view:res.partner.address:0 +msgid "Search Contact" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: field:ir.attachment,company_id:0 +#: field:ir.default,company_id:0 +#: field:ir.property,company_id:0 +#: field:ir.sequence,company_id:0 +#: field:ir.values,company_id:0 +#: view:res.company:0 +#: field:res.currency,company_id:0 +#: field:res.partner,company_id:0 +#: field:res.partner.address,company_id:0 +#: field:res.partner.bank,company_id:0 +#: view:res.users:0 +#: field:res.users,company_id:0 +msgid "Company" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_report_designer +msgid "Advanced Reporting" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window,target:0 +#: selection:ir.actions.url,target:0 +msgid "New Window" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_model_data +msgid "ir.model.data" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Publisher Warranty Contract" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Bulgarian / български език" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_aftersale +msgid "After-Sale Services" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_fr +msgid "France - Accounting" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Launch" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_caldav +msgid "Share Calendar using CalDAV" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,limit:0 +msgid "Limit" +msgstr "" + +#. module: base +#: help:workflow.transition,group_id:0 +msgid "" +"The group that a user must have to be authorized to validate this transition." +msgstr "" + +#. module: base +#: code:addons/orm.py:791 +#, python-format +msgid "Serialization field `%s` not found for sparse field `%s`!" +msgstr "" + +#. module: base +#: model:res.country,name:base.jm +msgid "Jamaica" +msgstr "" + +#. module: base +#: field:res.partner,color:0 +#: field:res.partner.address,color:0 +msgid "Color Index" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_category_form +msgid "" +"Manage the partner categories in order to better classify them for tracking " +"and analysis purposes. A partner may belong to several categories and " +"categories have a hierarchy structure: a partner belonging to a category " +"also belong to his parent category." +msgstr "" + +#. module: base +#: model:res.country,name:base.az +msgid "Azerbaijan" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_mail_server.py:450 +#: code:addons/base/res/res_partner.py:273 +#, python-format +msgid "Warning" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_edi +msgid "Electronic Data Interchange (EDI)" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_tools +msgid "Extra Tools" +msgstr "" + +#. module: base +#: model:res.country,name:base.vg +msgid "Virgin Islands (British)" +msgstr "" + +#. module: base +#: view:ir.property:0 +#: model:ir.ui.menu,name:base.next_id_15 +msgid "Parameters" +msgstr "" + +#. module: base +#: model:res.country,name:base.pm +msgid "Saint Pierre and Miquelon" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_email_template +msgid "" +"\n" +"Email Templating (simplified version of the original Power Email by " +"Openlabs)\n" +"=============================================================================" +"\n" +"\n" +"Lets you design complete email templates related to any OpenERP document " +"(Sale\n" +"Orders, Invoices and so on), including sender, recipient, subject, body " +"(HTML and\n" +"Text). You may also automatically attach files to your templates, or print " +"and\n" +"attach a report.\n" +"\n" +"For advanced use, the templates may include dynamic attributes of the " +"document\n" +"they are related to. For example, you may use the name of a Partner's " +"country\n" +"when writing to them, also providing a safe default in case the attribute " +"is\n" +"not defined. Each template contains a built-in assistant to help with the\n" +"inclusion of these dynamic values.\n" +"\n" +"If you enable the option, a composition assistant will also appear in the " +"sidebar\n" +"of the OpenERP documents to which the template applies (e.g. Invoices).\n" +"This serves as a quick way to send a new email based on the template, after\n" +"reviewing and adapting the contents, if needed.\n" +"This composition assistant will also turn into a mass mailing system when " +"called\n" +"for multiple documents at once.\n" +"\n" +"These email templates are also at the heart of the marketing campaign " +"system\n" +"(see the ``marketing_campaign`` application), if you need to automate " +"larger\n" +"campaigns on any OpenERP document.\n" +"\n" +"Technical note: only the templating system of the original Power Email by\n" +"Openlabs was kept\n" +"\n" +" " +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Czech / Čeština" +msgstr "" + +#. module: base +#: model:ir.module.category,name:base.module_category_generic_modules +msgid "Generic Modules" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_supplier_form +msgid "" +"You can access all information regarding your suppliers from the supplier " +"form: accounting data, history of emails, meetings, purchases, etc. You can " +"uncheck the 'Suppliers' filter button in order to search in all your " +"partners, including customers and prospects." +msgstr "" + +#. module: base +#: model:res.country,name:base.rw +msgid "Rwanda" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_hr_timesheet +msgid "" +"\n" +"This module implements a timesheet system.\n" +"==========================================\n" +"\n" +"Each employee can encode and track their time spent on the different " +"projects.\n" +"A project is an analytic account and the time spent on a project generates " +"costs on\n" +"the analytic account.\n" +"\n" +"Lots of reporting on time and employee tracking are provided.\n" +"\n" +"It is completely integrated with the cost accounting module. It allows you\n" +"to set up a management by affair.\n" +" " +msgstr "" + +#. module: base +#: help:ir.mail_server,smtp_port:0 +msgid "SMTP Port. Usually 465 for SSL, and 25 or 587 for other cases." +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Day of the week (0:Monday): %(weekday)s" +msgstr "" + +#. module: base +#: model:res.country,name:base.ck +msgid "Cook Islands" +msgstr "" + +#. module: base +#: field:ir.model.data,noupdate:0 +msgid "Non Updatable" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Klingon" +msgstr "" + +#. module: base +#: model:res.country,name:base.sg +msgid "Singapore" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window,target:0 +msgid "Current Window" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_crm +msgid "" +"\n" +"The generic OpenERP Customer Relationship Management.\n" +"=====================================================\n" +"\n" +"This system enables a group of people to intelligently and efficiently " +"manage\n" +"leads, opportunities, meeting, phonecall etc.\n" +"It manages key tasks such as communication, identification, prioritization,\n" +"assignment, resolution and notification.\n" +"\n" +"OpenERP ensures that all cases are successfully tracked by users, customers " +"and\n" +"suppliers. It can automatically send reminders, escalate the request, " +"trigger\n" +"specific methods and lots of other actions based on your own enterprise " +"rules.\n" +"\n" +"The greatest thing about this system is that users don't need to do " +"anything\n" +"special. They can just send email to the request tracker. OpenERP will take\n" +"care of thanking them for their message, automatically routing it to the\n" +"appropriate staff, and make sure all future correspondence gets to the " +"right\n" +"place.\n" +"\n" +"The CRM module has a email gateway for the synchronisation interface\n" +"between mails and OpenERP.\n" +"\n" +"Creates a dashboard for CRM that includes:\n" +" * Opportunities by Categories (graph)\n" +" * Opportunities by Stage (graph)\n" +" * Planned Revenue by Stage and User (graph)\n" +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_accounting_and_finance +msgid "" +"Helps you handle your accounting needs, if you are not an accountant, we " +"suggest you to install only the Invoicing." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_plugin_thunderbird +msgid "Thunderbird Plug-In" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_country +#: field:res.bank,country:0 +#: field:res.company,country_id:0 +#: view:res.country:0 +#: field:res.country.state,country_id:0 +#: field:res.partner,country:0 +#: view:res.partner.address:0 +#: field:res.partner.address,country_id:0 +#: field:res.partner.bank,country_id:0 +msgid "Country" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_project_messages +msgid "In-Project Messaging System" +msgstr "" + +#. module: base +#: model:res.country,name:base.pn +msgid "Pitcairn Island" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_web_tests +msgid "" +"\n" +" OpenERP Web test suite.\n" +" " +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Action Bindings/Defaults" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"1. Global rules are combined together with a logical AND operator, and with " +"the result of the following steps" +msgstr "" + +#. module: base +#: view:res.partner:0 +#: view:res.partner.address:0 +msgid "Change Color" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_15 +msgid "IT sector" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "Select Groups" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%X - Appropriate time representation." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (SV) / Español (SV)" +msgstr "" + +#. module: base +#: help:res.lang,grouping:0 +msgid "" +"The Separator Format should be like [,n] where 0 < n :starting from Unit " +"digit.-1 will end the separation. e.g. [3,2,-1] will represent 106500 to be " +"1,06,500;[1,2,-1] will represent it to be 106,50,0;[3] will represent it as " +"106,500. Provided ',' as the thousand separator in each case." +msgstr "" + +#. module: base +#: field:ir.module.module,auto_install:0 +msgid "Automatic Installation" +msgstr "" + +#. module: base +#: model:res.country,name:base.jp +msgid "Japan" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:357 +#, python-format +msgid "Can only rename one column at a time!" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Wizard Button" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Report/Template" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_marketing_campaign +msgid "" +"\n" +"This module provides leads automation through marketing campaigns (campaigns " +"can in fact be defined on any resource, not just CRM Leads).\n" +"=============================================================================" +"============================================================\n" +"\n" +"The campaigns are dynamic and multi-channels. The process is as follows:\n" +" * Design marketing campaigns like workflows, including email templates " +"to send, reports to print and send by email, custom actions, etc.\n" +" * Define input segments that will select the items that should enter the " +"campaign (e.g leads from certain countries, etc.)\n" +" * Run you campaign in simulation mode to test it real-time or " +"accelerated, and fine-tune it\n" +" * You may also start the real campaign in manual mode, where each action " +"requires manual validation\n" +" * Finally launch your campaign live, and watch the statistics as the " +"campaign does everything fully automatically.\n" +"\n" +"While the campaign runs you can of course continue to fine-tune the " +"parameters, input segments, workflow, etc.\n" +"\n" +"Note: If you need demo data, you can install the marketing_campaign_crm_demo " +"module, but this will also install the CRM application as it depends on CRM " +"Leads.\n" +" " +msgstr "" + +#. module: base +#: selection:ir.actions.act_window.view,view_mode:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Graph" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_server +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.server" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_ca +msgid "Canada - Accounting" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_ir_actions_todo_form +#: field:ir.actions.todo.category,wizards_ids:0 +#: model:ir.model,name:base.model_ir_actions_todo +#: model:ir.ui.menu,name:base.menu_ir_actions_todo_form +#: model:ir.ui.menu,name:base.next_id_11 +msgid "Configuration Wizards" +msgstr "" + +#. module: base +#: field:res.lang,code:0 +msgid "Locale Code" +msgstr "" + +#. module: base +#: field:workflow.activity,split_mode:0 +msgid "Split Mode" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "Note that this operation might take a few minutes." +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_localisation +msgid "Localisation" +msgstr "" + +#. module: base +#: field:ir.sequence,implementation:0 +msgid "Implementation" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_l10n_ve +msgid "Venezuela - Accounting" +msgstr "" + +#. module: base +#: model:res.country,name:base.cl +msgid "Chile" +msgstr "" + +#. module: base +#: view:ir.cron:0 +msgid "Execution" +msgstr "" + +#. module: base +#: field:ir.actions.server,condition:0 +#: view:ir.values:0 +#: field:workflow.transition,condition:0 +msgid "Condition" +msgstr "" + +#. module: base +#: help:res.currency,rate:0 +msgid "The rate of the currency to the currency of rate 1." +msgstr "" + +#. module: base +#: field:ir.ui.view,name:0 +msgid "View Name" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_document_ftp +msgid "Shared Repositories (FTP)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_groups +msgid "Access Groups" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Italian / Italiano" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,attachment:0 +msgid "Save As Attachment Prefix" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "" +"Only one client action will be executed, last client action will be " +"considered in case of multiple client actions." +msgstr "" + +#. module: base +#: model:res.country,name:base.hr +msgid "Croatia" +msgstr "" + +#. module: base +#: field:ir.actions.server,mobile:0 +msgid "Mobile No" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_by_category +#: model:ir.actions.act_window,name:base.action_partner_category_form +#: model:ir.model,name:base.model_res_partner_category +#: model:ir.ui.menu,name:base.menu_partner_category_form +#: view:res.partner.category:0 +msgid "Partner Categories" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "System Update" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Wizard Field" +msgstr "" + +#. module: base +#: help:ir.sequence,prefix:0 +msgid "Prefix value of the record for the sequence" +msgstr "" + +#. module: base +#: model:res.country,name:base.sc +msgid "Seychelles" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_partner_bank_account_form +#: model:ir.model,name:base.model_res_partner_bank +#: model:ir.ui.menu,name:base.menu_action_res_partner_bank_form +#: view:res.company:0 +#: field:res.company,bank_ids:0 +#: view:res.partner.bank:0 +msgid "Bank Accounts" +msgstr "" + +#. module: base +#: field:ir.model,modules:0 +#: field:ir.model.fields,modules:0 +msgid "In modules" +msgstr "" + +#. module: base +#: model:res.country,name:base.sl +msgid "Sierra Leone" +msgstr "" + +#. module: base +#: view:res.company:0 +#: view:res.partner:0 +msgid "General Information" +msgstr "" + +#. module: base +#: model:res.country,name:base.tc +msgid "Turks and Caicos Islands" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_fetchmail_project_issue +msgid "eMail Gateway for Project Issues" +msgstr "" + +#. module: base +#: field:res.partner.bank,partner_id:0 +msgid "Account Owner" +msgstr "" + +#. module: base +#: code:addons/base/res/res_users.py:270 +#, python-format +msgid "Company Switch Warning" +msgstr "" + +#. module: base +#: model:res.country,name:base.ge +msgid "Georgia" +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_manufacturing +msgid "" +"Helps you manage your manufacturing processes and generate reports on those " +"processes." +msgstr "" + +#. module: base +#: help:ir.sequence,number_increment:0 +msgid "The next number of the sequence will be incremented by this number" +msgstr "" + +#. module: base +#: code:addons/orm.py:341 +#, python-format +msgid "Wrong ID for the browse record, got %r, expected an integer." +msgstr "" + +#. module: base +#: field:res.partner.address,function:0 +#: selection:workflow.activity,kind:0 +msgid "Function" +msgstr "" + +#. module: base +#: view:res.widget:0 +msgid "Search Widget" +msgstr "" + +#. module: base +#: model:ir.module.category,description:base.module_category_customer_relationship_management +msgid "" +"Manage relations with prospects and customers using leads, opportunities, " +"requests or issues." +msgstr "" + +#. module: base +#: selection:res.partner.address,type:0 +msgid "Delivery" +msgstr "" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_pvt_ltd +#: model:res.partner.title,shortcut:base.res_partner_title_pvt_ltd +msgid "Corp." +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_purchase_requisition +msgid "Purchase Requisitions" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Months" +msgstr "" + +#. module: base +#: view:workflow.instance:0 +msgid "Workflow Instances" +msgstr "" + +#. module: base +#: code:addons/base/res/res_partner.py:284 +#, python-format +msgid "Partners: " +msgstr "" + +#. module: base +#: field:res.partner.bank,name:0 +msgid "Bank Account" +msgstr "" + +#. module: base +#: model:res.country,name:base.kp +msgid "North Korea" +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Create Object" +msgstr "" + +#. module: base +#: view:ir.filters:0 +#: field:res.log,context:0 +msgid "Context" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_sale_mrp +msgid "Sales and MRP Management" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_sms_send +msgid "Send an SMS" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_1 +msgid "Prospect" +msgstr "" + +#. module: base +#: model:ir.module.module,shortdesc:base.module_stock_invoice_directly +msgid "Invoice Picking Directly" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Polish / Język polski" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_tools +msgid "" +"\n" +"Common base for tools modules.\n" +"==============================\n" +"\n" +"Creates menu link for Tools from where tools like survey, lunch, idea, etc. " +"are accessible if installed.\n" +" " +msgstr "" + +#. module: base +#: field:ir.exports,name:0 +msgid "Export Name" +msgstr "" + +#. module: base +#: help:res.partner.address,type:0 +msgid "" +"Used to select automatically the right address according to the context in " +"sales and purchases documents." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_widget_act_window +#: model:ir.ui.menu,name:base.menu_res_widget_act_window +msgid "Homepage Widgets" +msgstr "" + +#. module: base +#: help:res.company,rml_footer2:0 +msgid "" +"This field is computed automatically based on bank accounts defined, having " +"the display on footer checkbox set." +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_mrp_subproduct +msgid "" +"\n" +"This module allows you to produce several products from one production " +"order.\n" +"=============================================================================" +"\n" +"\n" +"You can configure sub-products in the bill of material.\n" +"\n" +"Without this module:\n" +" A + B + C -> D\n" +"\n" +"With this module:\n" +" A + B + C -> D + E\n" +" " +msgstr "" + +#. module: base +#: model:res.country,name:base.lk +msgid "Sri Lanka" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_base_module_record +msgid "" +"\n" +"This module allows you to create a new module without any development.\n" +"======================================================================\n" +"\n" +"It records all operations on objects during the recording session and\n" +"produce a .ZIP module. So you can create your own module directly from\n" +"the OpenERP client.\n" +"\n" +"This version works for creating and updating existing records. It " +"recomputes\n" +"dependencies and links for all types of widgets (many2one, many2many, ...).\n" +"It also support workflows and demo/update data.\n" +"\n" +"This should help you to easily create reusable and publishable modules\n" +"for custom configurations and demo/testing data.\n" +"\n" +"How to use it:\n" +"Run Administration/Customization/Module Creation/Export Customizations As a " +"Module wizard.\n" +"Select datetime criteria of recording and objects to be recorded and Record " +"module.\n" +" " +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Russian / русский язык" +msgstr "" diff --git a/openerp/addons/base/i18n/et.po b/openerp/addons/base/i18n/et.po index 92461a33610..aac50f06100 100644 --- a/openerp/addons/base/i18n/et.po +++ b/openerp/addons/base/i18n/et.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 16:32+0000\n" -"Last-Translator: Raphael Collet (OpenERP) \n" +"PO-Revision-Date: 2012-08-20 15:46+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:38+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/eu.po b/openerp/addons/base/i18n/eu.po index cac59f27002..792b21b6765 100644 --- a/openerp/addons/base/i18n/eu.po +++ b/openerp/addons/base/i18n/eu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:37+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/fa.po b/openerp/addons/base/i18n/fa.po index 74885636856..066fe2500d8 100644 --- a/openerp/addons/base/i18n/fa.po +++ b/openerp/addons/base/i18n/fa.po @@ -3,14 +3,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 16:23+0000\n" +"PO-Revision-Date: 2012-08-20 15:53+0000\n" "Last-Translator: avion \n" "Language-Team: OpenERP Iran \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:41+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n" +"X-Generator: Launchpad (build 15901)\n" "X-Poedit-Country: IRAN, ISLAMIC REPUBLIC OF\n" "X-Poedit-Language: Persian\n" diff --git a/openerp/addons/base/i18n/fa_AF.po b/openerp/addons/base/i18n/fa_AF.po index 99a346be694..6d1b941729e 100644 --- a/openerp/addons/base/i18n/fa_AF.po +++ b/openerp/addons/base/i18n/fa_AF.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:45+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/fi.po b/openerp/addons/base/i18n/fi.po index c2de09b902d..62d3fff7aa8 100644 --- a/openerp/addons/base/i18n/fi.po +++ b/openerp/addons/base/i18n/fi.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-03-19 09:27+0000\n" -"Last-Translator: Juha Kotamäki \n" +"PO-Revision-Date: 2012-08-20 15:42+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:38+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/fr.po b/openerp/addons/base/i18n/fr.po index 3f755a59d14..02830069df2 100644 --- a/openerp/addons/base/i18n/fr.po +++ b/openerp/addons/base/i18n/fr.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-03-12 08:58+0000\n" -"Last-Translator: Numérigraphe \n" +"PO-Revision-Date: 2012-08-20 15:43+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:38+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -3637,7 +3637,7 @@ msgstr "Vue diagramme OpenERP web" #. module: base #: model:res.groups,name:base.group_hr_user msgid "HR Officer" -msgstr "Responsable RH" +msgstr "Collaborateur RH" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_contract @@ -11676,7 +11676,7 @@ msgstr "" #. module: base #: view:ir.sequence:0 msgid "Current Year with Century: %(year)s" -msgstr "Année en cours avec le siècle : %(année)s" +msgstr "Année en cours avec le siècle : %(year)s" #. module: base #: field:ir.exports,export_fields:0 diff --git a/openerp/addons/base/i18n/gl.po b/openerp/addons/base/i18n/gl.po index 91ac9510620..a1f6dec55ea 100644 --- a/openerp/addons/base/i18n/gl.po +++ b/openerp/addons/base/i18n/gl.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 16:22+0000\n" -"Last-Translator: Raphael Collet (OpenERP) \n" +"PO-Revision-Date: 2012-08-20 15:43+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: Galician \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:39+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/gu.po b/openerp/addons/base/i18n/gu.po index 91597862bf5..7a54b30f5c7 100644 --- a/openerp/addons/base/i18n/gu.po +++ b/openerp/addons/base/i18n/gu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:39+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/he.po b/openerp/addons/base/i18n/he.po index 967b11c89a0..63b5e98ee3e 100644 --- a/openerp/addons/base/i18n/he.po +++ b/openerp/addons/base/i18n/he.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2010-12-10 07:42+0000\n" +"PO-Revision-Date: 2012-08-20 15:27+0000\n" "Last-Translator: OpenERP Administrators \n" "Language-Team: Hebrew \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:39+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/hr.po b/openerp/addons/base/i18n/hr.po index e50c21bd73c..a001f4b9cbe 100644 --- a/openerp/addons/base/i18n/hr.po +++ b/openerp/addons/base/i18n/hr.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-02-08 09:51+0000\n" +"PO-Revision-Date: 2012-08-20 15:48+0000\n" "Last-Translator: Goran Cvijanović \n" "Language-Team: openerp-translators\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:42+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n" +"X-Generator: Launchpad (build 15901)\n" "Language: hr\n" #. module: base diff --git a/openerp/addons/base/i18n/hu.po b/openerp/addons/base/i18n/hu.po index d98ee515473..3a4de493607 100644 --- a/openerp/addons/base/i18n/hu.po +++ b/openerp/addons/base/i18n/hu.po @@ -7,15 +7,15 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 15:49+0000\n" +"PO-Revision-Date: 2012-08-20 15:28+0000\n" "Last-Translator: NOVOTRADE RENDSZERHÁZ ( novotrade.hu ) " "\n" "Language-Team: Hungarian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:40+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/hy.po b/openerp/addons/base/i18n/hy.po index 2c5ed383c32..aa1d7e92777 100644 --- a/openerp/addons/base/i18n/hy.po +++ b/openerp/addons/base/i18n/hy.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:37+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/id.po b/openerp/addons/base/i18n/id.po index de2d31683ee..20884ecd62d 100644 --- a/openerp/addons/base/i18n/id.po +++ b/openerp/addons/base/i18n/id.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:40+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/is.po b/openerp/addons/base/i18n/is.po index bab1f557502..b7d55808fb0 100644 --- a/openerp/addons/base/i18n/is.po +++ b/openerp/addons/base/i18n/is.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2009-11-30 08:27+0000\n" +"PO-Revision-Date: 2012-08-20 15:49+0000\n" "Last-Translator: Fabien (Open ERP) \n" "Language-Team: Icelandic \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:40+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/it.po b/openerp/addons/base/i18n/it.po index e1f369680a2..b73f9844de2 100644 --- a/openerp/addons/base/i18n/it.po +++ b/openerp/addons/base/i18n/it.po @@ -7,15 +7,15 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-08-10 18:42+0000\n" +"PO-Revision-Date: 2012-08-20 15:28+0000\n" "Last-Translator: Leonardo Pistone - Agile BG - Domsense " "\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-11 05:45+0000\n" -"X-Generator: Launchpad (build 15780)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ja.po b/openerp/addons/base/i18n/ja.po index 35382f62daa..f67e49e8630 100644 --- a/openerp/addons/base/i18n/ja.po +++ b/openerp/addons/base/i18n/ja.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-08-02 17:18+0000\n" -"Last-Translator: Akira Hiyama \n" +"PO-Revision-Date: 2012-08-20 15:37+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: Japanese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-03 05:45+0000\n" -"X-Generator: Launchpad (build 15734)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ka.po b/openerp/addons/base/i18n/ka.po index a7a4c233c3c..3a13c7a3c19 100644 --- a/openerp/addons/base/i18n/ka.po +++ b/openerp/addons/base/i18n/ka.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-03-14 15:06+0000\n" -"Last-Translator: FULL NAME \n" +"PO-Revision-Date: 2012-08-20 15:35+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: Georgian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:39+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/kk.po b/openerp/addons/base/i18n/kk.po index 09a985213b8..331db58c6fa 100644 --- a/openerp/addons/base/i18n/kk.po +++ b/openerp/addons/base/i18n/kk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:40+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ko.po b/openerp/addons/base/i18n/ko.po index b66cb25933e..dff6a43c5e1 100644 --- a/openerp/addons/base/i18n/ko.po +++ b/openerp/addons/base/i18n/ko.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2010-12-16 08:15+0000\n" +"PO-Revision-Date: 2012-08-20 15:29+0000\n" "Last-Translator: ekodaq \n" "Language-Team: Korean \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:40+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/lt.po b/openerp/addons/base/i18n/lt.po index eb59a102506..71314ff39ec 100644 --- a/openerp/addons/base/i18n/lt.po +++ b/openerp/addons/base/i18n/lt.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2011-01-16 11:33+0000\n" +"PO-Revision-Date: 2012-08-20 15:52+0000\n" "Last-Translator: Paulius Sladkevičius \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:41+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/lt_LT.po b/openerp/addons/base/i18n/lt_LT.po index 13846af119e..be05dc522d1 100644 --- a/openerp/addons/base/i18n/lt_LT.po +++ b/openerp/addons/base/i18n/lt_LT.po @@ -4533,7 +4533,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/lv.po b/openerp/addons/base/i18n/lv.po index 0a83e177d06..cfc772f32f0 100644 --- a/openerp/addons/base/i18n/lv.po +++ b/openerp/addons/base/i18n/lv.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 15:53+0000\n" +"PO-Revision-Date: 2012-08-20 15:31+0000\n" "Last-Translator: Antony Lesuisse (OpenERP) \n" "Language-Team: Latvian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:41+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/mk.po b/openerp/addons/base/i18n/mk.po index 3414ae7063c..a487c340251 100644 --- a/openerp/addons/base/i18n/mk.po +++ b/openerp/addons/base/i18n/mk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:41+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/mn.po b/openerp/addons/base/i18n/mn.po index c80aa9afb14..273d4002096 100644 --- a/openerp/addons/base/i18n/mn.po +++ b/openerp/addons/base/i18n/mn.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0.0-rc1\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-04-20 10:05+0000\n" +"PO-Revision-Date: 2012-08-20 15:28+0000\n" "Last-Translator: Bayuka \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:41+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -111,7 +111,7 @@ msgstr "Цоорхой үгүй" #. module: base #: selection:base.language.install,lang:0 msgid "Hungarian / Magyar" -msgstr "Унгар хэл / Магяар" +msgstr "Унгар / Magyar" #. module: base #: selection:base.language.install,lang:0 @@ -249,7 +249,7 @@ msgstr "Швецарь" #: code:addons/orm.py:4206 #, python-format msgid "created." -msgstr "" +msgstr "үүсгэгдсэн." #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_tr @@ -2786,7 +2786,7 @@ msgstr "Моделийн Тойм" #. module: base #: model:ir.module.module,shortdesc:base.module_product_margin msgid "Margins by Products" -msgstr "Захалбар Бүтээгдэхүүнээр" +msgstr "Захалбар Бараагаар" #. module: base #: model:ir.ui.menu,name:base.menu_invoiced @@ -4615,7 +4615,7 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_partner_form #: view:res.partner:0 msgid "Customers" -msgstr "Үйлчлүүлэгчид" +msgstr "Захиалагчид" #. module: base #: model:res.country,name:base.au @@ -6458,7 +6458,7 @@ msgstr "Бичих Id" #. module: base #: model:ir.ui.menu,name:base.menu_product msgid "Products" -msgstr "Бүтээгдэхүүн" +msgstr "Бараанууд" #. module: base #: help:res.users,name:0 @@ -8531,16 +8531,16 @@ msgstr "" "===============================\n" "\n" "Ихэнхдээ энэ дараах тохиолдлуудад хэрэглэгдэж болно:\n" -" * Бүтээгдэхүүний үйлдвэрлэх урсгалыг менеж хийх\n" -" * Бүтээгдэхүүнүүдээр анхны байрлалыг менеж хийх\n" +" * Барааны үйлдвэрлэх урсгалыг менеж хийх\n" +" * Бараануудаар анхны байрлалыг менеж хийх\n" " * Бизнес шаардлагын дагуу агуулах дахь маршрутыг тодорхойлох, " "тухайлбал:\n" " - Чанарын Хяналт\n" " - Борлуулалтын Дараах Үйлчилгээ\n" " - Нийлүүлэгчийн Буцаалт\n" "\n" -" * Түрээслэсэн бүтээгдэхүүний автомат буцаалтын хөдөлгөөнөөр түрээсийг " -"менеж хийхэд тусладаг\n" +" * Түрээслэсэн барааны автомат буцаалтын хөдөлгөөнөөр түрээсийг менеж " +"хийхэд тусладаг\n" "\n" "Энэ модулийг нэгэнтээ суулгасан дараагаар барааны форм дээр нэмэлт хавтас " "харагдах бөгөөд энд Чихэх, Татах урсгалуудыг зааж өгнө. CPU1 барааны " @@ -11080,7 +11080,7 @@ msgstr "Дундын бүс" #. module: base #: view:ir.model:0 msgid "Custom" -msgstr "Үйлчлүүлэгч" +msgstr "Өөриймшүүлсэн" #. module: base #: view:res.request:0 @@ -11295,7 +11295,7 @@ msgstr "Гайана" #. module: base #: model:ir.module.module,shortdesc:base.module_product_expiry msgid "Products Expiry Date" -msgstr "Бүтээгдэхүүний Хугацаа Дуусах Огноо" +msgstr "Барааны Хугацаа Дуусах Огноо" #. module: base #: model:ir.module.module,description:base.module_account @@ -13442,7 +13442,7 @@ msgstr "1-р түвшний дэмжлэг" #: field:res.partner.address,is_customer_add:0 #: model:res.partner.category,name:base.res_partner_category_0 msgid "Customer" -msgstr "Үйлчлүүлэгч" +msgstr "Захиалагч" #. module: base #: selection:base.language.install,lang:0 @@ -16845,10 +16845,10 @@ msgstr "" "Энэ модуль нь Асуудал/Бугийн менежментийг төсөлд нэмдэг.\n" "=======================================================\n" "\n" -"OpenERP нь төсөлд учирч болох системийн буг, үйлчлүүлэгчийн гомдол, " -"материалын эвдрэл гэх мэт асуудлыг менеж хийх боломжийг олгодог. Асуудлын " -"жагсаалтыг менежер харж хурдтайгаар шалгах, хариуцагчийг томилох, төлөвийн " -"явцаар нь шийдвэр гаргах зэрэг боломжийг олгоно.\n" +"OpenERP нь төсөлд учирч болох системийн буг, захиалагчийн гомдол, материалын " +"эвдрэл гэх мэт асуудлыг менеж хийх боломжийг олгодог. Асуудлын жагсаалтыг " +"менежер харж хурдтайгаар шалгах, хариуцагчийг томилох, төлөвийн явцаар нь " +"шийдвэр гаргах зэрэг боломжийг олгоно.\n" " " #. module: base diff --git a/openerp/addons/base/i18n/nb.po b/openerp/addons/base/i18n/nb.po index 1542c677529..5a6b76b7e6a 100644 --- a/openerp/addons/base/i18n/nb.po +++ b/openerp/addons/base/i18n/nb.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 16:28+0000\n" +"PO-Revision-Date: 2012-08-20 15:45+0000\n" "Last-Translator: Antony Lesuisse (OpenERP) \n" "Language-Team: Norwegian Bokmal \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:41+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -30,12 +30,12 @@ msgstr "Annen konfigurasjon" #. module: base #: selection:ir.property,type:0 msgid "DateTime" -msgstr "" +msgstr "Dato og klokkeslett" #. module: base #: model:ir.module.module,shortdesc:base.module_project_mailgate msgid "Tasks-Mail Integration" -msgstr "" +msgstr "Integrasjon Oppgaver - E-post" #. module: base #: code:addons/fields.py:582 @@ -44,6 +44,8 @@ msgid "" "The second argument of the many2many field %s must be a SQL table !You used " "%s, which is not a valid SQL table name." msgstr "" +"Det andre argumentet for mange-til-mange-feltet %s må være en SQL tabell! Du " +"anga %s som ikke er et gyldig SQL tabellnavn." #. module: base #: field:ir.ui.view,arch:0 @@ -89,7 +91,7 @@ msgstr "Arbeidsflyt" #. module: base #: selection:ir.sequence,implementation:0 msgid "No gap" -msgstr "" +msgstr "Ingen gap" #. module: base #: selection:base.language.install,lang:0 @@ -107,6 +109,8 @@ msgid "" "Helps you manage your projects and tasks by tracking them, generating " "plannings, etc..." msgstr "" +"Hjelper deg med å håndtere dine prosjekter og oppgaver ved å spore dem, " +"generere planer, osv..." #. module: base #: field:ir.actions.act_window,display_menu_tip:0 @@ -118,6 +122,8 @@ msgstr "Vis menytips" msgid "" "Model name on which the method to be called is located, e.g. 'res.partner'." msgstr "" +"Navn på modell hvor metoden som skal kalles er definert, f.eks. " +"'res.partner'." #. module: base #: view:ir.module.module:0 @@ -143,6 +149,12 @@ msgid "" "\n" "This module allows you to create retro planning for managing your events.\n" msgstr "" +"\n" +"Organisering og administrasjon av arrangementer\n" +"===============================================\n" +"\n" +"Denne modulen gir deg mulighet for baklengs planlegging for å administrere " +"dine arrangementer.\n" #. module: base #: help:ir.model.fields,domain:0 @@ -180,7 +192,7 @@ msgstr "Prosess" #. module: base #: model:ir.module.module,shortdesc:base.module_analytic_journal_billing_rate msgid "Billing Rates on Contracts" -msgstr "" +msgstr "Faktureringsrater på kontrakter" #. module: base #: code:addons/base/res/res_users.py:558 @@ -200,7 +212,7 @@ msgstr "" #: code:addons/osv.py:129 #, python-format msgid "Constraint Error" -msgstr "" +msgstr "Betingelsesfeil" #. module: base #: model:ir.model,name:base.model_ir_ui_view_custom @@ -265,12 +277,12 @@ msgstr "" #: model:ir.module.category,name:base.module_category_sales_management #: model:ir.module.module,shortdesc:base.module_sale msgid "Sales Management" -msgstr "" +msgstr "Salgsadministrasjon" #. module: base #: view:res.partner:0 msgid "Search Partner" -msgstr "" +msgstr "Søk partner" #. module: base #: code:addons/base/module/wizard/base_export_language.py:60 @@ -377,7 +389,7 @@ msgstr "Ekstra" #: code:addons/orm.py:2526 #, python-format msgid "Invalid group_by" -msgstr "" +msgstr "Ugyldig gruppering" #. module: base #: field:ir.module.category,child_ids:0 @@ -2463,7 +2475,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_product_margin msgid "Margins by Products" -msgstr "" +msgstr "Margin pr product" #. module: base #: model:ir.ui.menu,name:base.menu_invoiced @@ -2778,7 +2790,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_stock_planning msgid "Master Procurement Schedule" -msgstr "" +msgstr "Hovedplanlegging av anskaffelser" #. module: base #: model:ir.model,name:base.model_ir_module_category @@ -3143,7 +3155,7 @@ msgstr "Kontakttitler" #. module: base #: model:ir.module.module,shortdesc:base.module_product_manufacturer msgid "Products Manufacturers" -msgstr "" +msgstr "Vareprodusenter" #. module: base #: code:addons/base/ir/ir_mail_server.py:217 @@ -6899,7 +6911,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_report_intrastat msgid "Intrastat Reporting" -msgstr "" +msgstr "Intrastat-rapportering" #. module: base #: code:addons/base/res/res_users.py:222 @@ -9530,7 +9542,7 @@ msgstr "Guyana" #. module: base #: model:ir.module.module,shortdesc:base.module_product_expiry msgid "Products Expiry Date" -msgstr "" +msgstr "Utløpsdato" #. module: base #: model:ir.module.module,description:base.module_account @@ -12332,7 +12344,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_procurement msgid "Procurements" -msgstr "" +msgstr "Anskaffelser" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_payroll_account @@ -13385,7 +13397,7 @@ msgstr "Aktiviteter" #. module: base #: model:ir.module.module,shortdesc:base.module_product msgid "Products & Pricelists" -msgstr "" +msgstr "Produkter & prislister" #. module: base #: field:ir.actions.act_window,auto_refresh:0 @@ -14003,7 +14015,7 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_config_address_book #: model:ir.ui.menu,name:base.menu_procurement_management_supplier msgid "Address Book" -msgstr "" +msgstr "Adressebok" #. module: base #: model:ir.module.module,description:base.module_l10n_ma @@ -14437,7 +14449,7 @@ msgstr "Firma" #. module: base #: model:ir.module.category,name:base.module_category_report_designer msgid "Advanced Reporting" -msgstr "" +msgstr "Avansert rapportering" #. module: base #: selection:ir.actions.act_window,target:0 diff --git a/openerp/addons/base/i18n/nl.po b/openerp/addons/base/i18n/nl.po index 45560f7e363..dbd37e376ac 100644 --- a/openerp/addons/base/i18n/nl.po +++ b/openerp/addons/base/i18n/nl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-08-09 06:15+0000\n" -"Last-Translator: Erwin \n" +"PO-Revision-Date: 2012-08-20 15:53+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-10 04:58+0000\n" -"X-Generator: Launchpad (build 15761)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -921,7 +921,7 @@ msgid "" "The module adds google contact in partner address and add google calendar " "events details in Meeting" msgstr "" -"Deze module voegt Google contact[ersonen in relatie adressen en voegt Google " +"Deze module voegt Google contactersonen in relatie adressen en voegt Google " "agenda items details in OpenERP agenda." #. module: base @@ -942,6 +942,15 @@ msgid "" "delete on objects and can check logs.\n" " " msgstr "" +"\n" +"Met deze module heeft de administrator de mogelijkheid om iedere gebruikers " +"handeling op alle objecten in het systeem te volgen.\n" +"=============================================================================" +"=======================\n" +"\n" +"De administrator kan regels voor lezen, schrijven en verwijderen definiëren " +"en logs hiervan bekijken\n" +" " #. module: base #: model:res.partner.category,name:base.res_partner_category_4 @@ -2482,6 +2491,18 @@ msgid "" "and categorize your interventions with a channel and a priority level.\n" " " msgstr "" +"\n" +"Helpdesk management.\n" +"===================\n" +"\n" +"Net als administratie en verwerking van claims is de Helpdesk en " +"ondersteuning tool, een goed instrument\n" +"om uw acties vast te leggen. Dit menu is meer aangepast aan de mondelinge " +"communicatie,\n" +"die niet noodzakelijkerwijs verband houden met een claim. Selecteer een " +"klant, voeg notities toe\n" +"en deel uw acties in.\n" +" " #. module: base #: sql_constraint:ir.ui.view_sc:0 @@ -2542,6 +2563,11 @@ msgid "" "\n" "Configure servers and trigger synchronization with its database objects.\n" msgstr "" +"\n" +"Synchronisatie van objecten.\n" +"=======================\n" +"Configureer servers and trigger database synchronisatie van de database " +"objecten.\n" #. module: base #: model:res.country,name:base.mg @@ -7548,6 +7574,14 @@ msgid "" "that exceeds minimum amount set by configuration wizard.\n" " " msgstr "" +"\n" +"Dubbele controle voor inkopen, welke een minimum bedrag overstijgen.\n" +"==========================================================\n" +"\n" +"Deze module past de inkoop workflow aan, zodat inkopen, welke een \n" +"minimum bedrag overstijgen moeten worden gecontroleerd. Dit kan worden\n" +"ingesteld in de configuratie wizard.\n" +" " #. module: base #: field:res.currency,rounding:0 @@ -10556,6 +10590,11 @@ msgid "" "\n" "Adds a Claim link to the delivery order.\n" msgstr "" +"\n" +"Maak een claim van een uitgaande levering.\n" +"===================================\n" +"\n" +"Voegt claim link toe aan een uitgaande order.\n" #. module: base #: view:ir.model:0 @@ -11772,6 +11811,13 @@ msgid "" "the invoicing wizard if the delivery is to be invoiced.\n" " " msgstr "" +"\n" +"Factuur wizard bij levering.\n" +"======================\n" +"\n" +"Deze module start de factuur wizard, direct na het verzamelen van een\n" +"inkomende of uitgaande levering en deze levering moet worden gefactureerd.\n" +" " #. module: base #: code:addons/orm.py:1388 @@ -13330,6 +13376,13 @@ msgid "" "marketing_campaign.\n" " " msgstr "" +"\n" +"Demo data voor de module marketing_campaign.\n" +"========================================\n" +"\n" +"maakt demo data aan, zoals leads, campagnes en segmenten voor de module " +"marketing_campaign.\n" +" " #. module: base #: selection:ir.actions.act_window.view,view_mode:0 @@ -13962,6 +14015,17 @@ msgid "" "\n" "Used, for example, in food industries." msgstr "" +"\n" +"Traceer verschillende datums van producten and productie partijen.\n" +"=======================================================\n" +"\n" +"de volgende datums kunnen worden getraceerd:\n" +" - THT datum\n" +" - Te gebruiken voor datum\n" +" - verwijder datum\n" +" - waarschuwing datum\n" +"\n" +"Wordt bijvoorbeeld gebruikt in de voedingsmiddelen industrie." #. module: base #: field:ir.exports.line,export_id:0 diff --git a/openerp/addons/base/i18n/nl_BE.po b/openerp/addons/base/i18n/nl_BE.po index cf2cc84f2fd..bf6b8deabaf 100644 --- a/openerp/addons/base/i18n/nl_BE.po +++ b/openerp/addons/base/i18n/nl_BE.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:44+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/nl_NL.po b/openerp/addons/base/i18n/nl_NL.po index bfb371faf05..267b058bfef 100644 --- a/openerp/addons/base/i18n/nl_NL.po +++ b/openerp/addons/base/i18n/nl_NL.po @@ -4711,7 +4711,7 @@ msgstr "html" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "BTW" #. module: base diff --git a/openerp/addons/base/i18n/pl.po b/openerp/addons/base/i18n/pl.po index b0e489d3b03..77e41253840 100644 --- a/openerp/addons/base/i18n/pl.po +++ b/openerp/addons/base/i18n/pl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 16:15+0000\n" +"PO-Revision-Date: 2012-08-20 15:42+0000\n" "Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:42+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -98,7 +98,7 @@ msgstr "Węgierski" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (PY) / Español (PY)" -msgstr "" +msgstr "Hiszpański (PY) / Español (PY)" #. module: base #: model:ir.module.category,description:base.module_category_project_management diff --git a/openerp/addons/base/i18n/pt.po b/openerp/addons/base/i18n/pt.po index b60b9b98d76..5029fad58ed 100644 --- a/openerp/addons/base/i18n/pt.po +++ b/openerp/addons/base/i18n/pt.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-06-05 10:01+0000\n" +"PO-Revision-Date: 2012-08-20 15:49+0000\n" "Last-Translator: Tiago Rodrigues \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:42+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/pt_BR.po b/openerp/addons/base/i18n/pt_BR.po index 97cbcce0eb6..3a7516a9dc2 100644 --- a/openerp/addons/base/i18n/pt_BR.po +++ b/openerp/addons/base/i18n/pt_BR.po @@ -7,15 +7,15 @@ msgstr "" "Project-Id-Version: pt_BR\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-02-15 19:18+0000\n" +"PO-Revision-Date: 2012-08-20 15:33+0000\n" "Last-Translator: Renato Lima - http://www.akretion.com " "\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:44+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -2095,6 +2095,13 @@ msgid "" " ============================================================\n" " " msgstr "" +"\n" +" Adicionar dados província chinesa\n" +" Assunto gráfico tipo \\ de contas templates \\ IVA \\ auxiliar de " +"contabilidade categoria \\ gestão certificado livro de contabilidade \\ " +"livro certificado de Contabilidade Financeira\n" +" ============================================================\n" +" " #. module: base #: model:ir.model,name:base.model_ir_model_access @@ -3163,7 +3170,7 @@ msgstr "Bangladesh" #. module: base #: model:ir.module.module,shortdesc:base.module_project_retro_planning msgid "Project Retro-planning" -msgstr "" +msgstr "Projeto de retro-planejamento" #. module: base #: model:ir.module.module,shortdesc:base.module_stock_planning @@ -3465,7 +3472,7 @@ msgstr "" #. module: base #: model:res.groups,name:base.group_survey_user msgid "Survey / User" -msgstr "" +msgstr "Pesquisa / Usuário" #. module: base #: view:ir.module.module:0 @@ -3864,7 +3871,7 @@ msgstr "Formato do separador" #. module: base #: constraint:res.partner.bank:0 msgid "The RIB and/or IBAN is not valid" -msgstr "" +msgstr "A RIB e/ ou IBAN não é válido." #. module: base #: model:ir.module.module,shortdesc:base.module_report_webkit @@ -7609,7 +7616,7 @@ msgstr "Honduras - contabilidade" #. module: base #: model:ir.module.module,shortdesc:base.module_report_intrastat msgid "Intrastat Reporting" -msgstr "" +msgstr "Relatórios Intrastat" #. module: base #: code:addons/base/res/res_users.py:222 @@ -8866,7 +8873,7 @@ msgstr "Rotas Avançadas" #. module: base #: model:ir.module.module,shortdesc:base.module_pad msgid "Collaborative Pads" -msgstr "" +msgstr "Pads Colaborativos" #. module: base #: model:ir.module.module,shortdesc:base.module_account_anglo_saxon diff --git a/openerp/addons/base/i18n/ro.po b/openerp/addons/base/i18n/ro.po index f079b8bd10a..2f82536f1ab 100644 --- a/openerp/addons/base/i18n/ro.po +++ b/openerp/addons/base/i18n/ro.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 15:46+0000\n" +"PO-Revision-Date: 2012-08-20 15:27+0000\n" "Last-Translator: Dorin \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:42+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/ru.po b/openerp/addons/base/i18n/ru.po index c3ba2f63acd..92d742a292b 100644 --- a/openerp/addons/base/i18n/ru.po +++ b/openerp/addons/base/i18n/ru.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-07-26 16:30+0000\n" -"Last-Translator: Rinat Karimov \n" +"PO-Revision-Date: 2012-09-10 14:37+0000\n" +"Last-Translator: Chertykov Denis \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-27 05:22+0000\n" -"X-Generator: Launchpad (build 15694)\n" +"X-Launchpad-Export-Date: 2012-09-11 04:50+0000\n" +"X-Generator: Launchpad (build 15924)\n" #. module: base #: model:res.country,name:base.sh @@ -187,7 +187,7 @@ msgstr "Ссылка" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_be_invoice_bba msgid "Belgium - Structured Communication" -msgstr "" +msgstr "Бельгия - Структурированные коммуникации" #. module: base #: field:ir.actions.act_window,target:0 @@ -604,7 +604,7 @@ msgstr "Испанский (VE) / Español (VE)" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_timesheet_invoice msgid "Invoice on Timesheets" -msgstr "" +msgstr "Счет по затратам времени" #. module: base #: view:base.module.upgrade:0 @@ -1269,7 +1269,7 @@ msgstr "Порт SMTP" #. module: base #: model:ir.module.module,shortdesc:base.module_import_sugarcrm msgid "SugarCRM Import" -msgstr "" +msgstr "Импорт SugarCRM" #. module: base #: view:res.lang:0 @@ -1374,7 +1374,7 @@ msgstr "Система управления документами" #. module: base #: model:ir.module.module,shortdesc:base.module_crm_claim msgid "Claims Management" -msgstr "" +msgstr "Управление претензиями" #. module: base #: model:ir.ui.menu,name:base.menu_purchase_root @@ -1602,7 +1602,7 @@ msgstr "Логин" #: model:ir.actions.act_window,name:base.action_wizard_update_translations #: model:ir.ui.menu,name:base.menu_wizard_update_translations msgid "Synchronize Terms" -msgstr "" +msgstr "Синхронизация терминов" #. module: base #: view:ir.actions.server:0 @@ -1749,6 +1749,12 @@ msgid "" " Apply Different Category for the product.\n" " " msgstr "" +"\n" +" Базовый модуль управления ланчами\n" +"\n" +" Отслеживание заказов, движения средств, кассы, продукции.\n" +" Возможность разнесения продукции по категориям.\n" +" " #. module: base #: model:res.country,name:base.kg @@ -1862,7 +1868,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_html_view msgid "Html View" -msgstr "" +msgstr "Просмотр HTML" #. module: base #: field:res.currency,position:0 @@ -2365,7 +2371,7 @@ msgstr "Управление виджетами домашней страниц #. module: base #: field:res.company,rml_header1:0 msgid "Report Header / Company Slogan" -msgstr "" +msgstr "Заголовок отчетов / Девиз компании" #. module: base #: model:res.country,name:base.pl @@ -2533,7 +2539,7 @@ msgstr "Идеи" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_crm msgid "Opportunity to Quotation" -msgstr "" +msgstr "Предложение в Запрос цен" #. module: base #: model:ir.module.module,description:base.module_sale_analytic_plans @@ -2767,7 +2773,7 @@ msgstr "Словения" #. module: base #: help:res.currency,name:0 msgid "Currency Code (ISO 4217)" -msgstr "" +msgstr "Код валюты (ISO 4217)" #. module: base #: model:ir.actions.act_window,name:base.res_log_act_window @@ -3267,7 +3273,7 @@ msgstr "Режим SMTP-over-SSL недоступен" #. module: base #: model:ir.module.module,shortdesc:base.module_survey msgid "Survey" -msgstr "" +msgstr "Опрос" #. module: base #: view:base.language.import:0 @@ -3315,7 +3321,7 @@ msgstr "Уругвай" #. module: base #: model:ir.module.module,shortdesc:base.module_fetchmail_crm msgid "eMail Gateway for Leads" -msgstr "" +msgstr "Шлюз эл.почты для кандидатов" #. module: base #: selection:base.language.install,lang:0 @@ -3530,7 +3536,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_report_webkit msgid "Webkit Report Engine" -msgstr "" +msgstr "Инструмент создания отчетов Webkit" #. module: base #: selection:publisher_warranty.contract,state:0 @@ -3557,7 +3563,7 @@ msgstr "Майотта" #. module: base #: model:ir.module.module,shortdesc:base.module_crm_todo msgid "Tasks on CRM" -msgstr "" +msgstr "Задачи по CRM" #. module: base #: model:ir.module.category,name:base.module_category_generic_modules_accounting @@ -3683,12 +3689,12 @@ msgstr "Обнаружена рекурсия." #. module: base #: model:ir.module.module,shortdesc:base.module_report_webkit_sample msgid "Webkit Report Samples" -msgstr "" +msgstr "Примеры отчетов Webkit" #. module: base #: model:ir.module.module,shortdesc:base.module_point_of_sale msgid "Point Of Sale" -msgstr "" +msgstr "Точка продажи" #. module: base #: code:addons/base/module/module.py:302 @@ -3812,7 +3818,7 @@ msgstr "Проверка кода Ean" #. module: base #: field:res.partner,vat:0 msgid "VAT" -msgstr "ИНН" +msgstr "НДС" #. module: base #: field:res.users,new_password:0 @@ -3945,7 +3951,7 @@ msgstr "Поддержка iCal" #. module: base #: model:ir.module.module,shortdesc:base.module_fetchmail msgid "Email Gateway" -msgstr "" +msgstr "Шлюз эл.почты" #. module: base #: code:addons/base/ir/ir_mail_server.py:439 @@ -4069,7 +4075,7 @@ msgstr "Португалия" #. module: base #: model:ir.module.module,shortdesc:base.module_share msgid "Share any Document" -msgstr "" +msgstr "Совместный доступ r любым документам" #. module: base #: field:ir.module.module,certificate:0 @@ -4407,7 +4413,7 @@ msgstr "Код должен быть уникальным" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_expense msgid "Expenses Management" -msgstr "" +msgstr "Управление расходами" #. module: base #: view:workflow.activity:0 @@ -4418,7 +4424,7 @@ msgstr "Входящие переходы" #. module: base #: field:ir.values,value_unpickle:0 msgid "Default value or action reference" -msgstr "" +msgstr "Значение по умолчанию или ссылка на действие" #. module: base #: model:res.country,name:base.sr @@ -4558,7 +4564,7 @@ msgstr "Экваториальная Гвинея" #. module: base #: model:ir.module.module,shortdesc:base.module_warning msgid "Warning Messages and Alerts" -msgstr "" +msgstr "Предупреждающие сообщения и оповещения" #. module: base #: view:base.module.import:0 @@ -4750,7 +4756,7 @@ msgstr "Кения" #: model:ir.actions.act_window,name:base.action_translation #: model:ir.ui.menu,name:base.menu_action_translation msgid "Translated Terms" -msgstr "" +msgstr "Перевод терминов" #. module: base #: view:res.partner.event:0 @@ -4870,7 +4876,7 @@ msgstr "Договор уже зарегистрирован в системе." #: model:ir.actions.act_window,name:base.action_res_partner_bank_type_form #: model:ir.ui.menu,name:base.menu_action_res_partner_bank_typeform msgid "Bank Account Types" -msgstr "" +msgstr "Типы банковского счета" #. module: base #: help:ir.sequence,suffix:0 @@ -4880,7 +4886,7 @@ msgstr "Суффикс записи для нумерации" #. module: base #: help:ir.mail_server,smtp_user:0 msgid "Optional username for SMTP authentication" -msgstr "" +msgstr "Необязательное имя пользователя для аутентификации SMTP" #. module: base #: model:ir.model,name:base.model_ir_actions_actions @@ -4935,7 +4941,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_web_chat msgid "Web Chat" -msgstr "" +msgstr "Веб-чат" #. module: base #: field:res.company,rml_footer2:0 @@ -4966,7 +4972,7 @@ msgstr "Права доступа" #: code:addons/base/ir/ir_model.py:311 #, python-format msgid "Changing the storing system for field \"%s\" is not allowed." -msgstr "" +msgstr "Изменение системы хранения для поля \"%s\" не допускается." #. module: base #: help:res.partner.bank,company_id:0 @@ -6584,7 +6590,7 @@ msgstr "Рабочие дни" #. module: base #: model:ir.module.module,shortdesc:base.module_multi_company msgid "Multi-Company" -msgstr "" +msgstr "Холдинг" #. module: base #: field:ir.actions.report.xml,report_rml_content:0 diff --git a/openerp/addons/base/i18n/sk.po b/openerp/addons/base/i18n/sk.po index 94ee24e819d..d6f64ab0e58 100644 --- a/openerp/addons/base/i18n/sk.po +++ b/openerp/addons/base/i18n/sk.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 16:57+0000\n" +"PO-Revision-Date: 2012-08-20 15:39+0000\n" "Last-Translator: Peter Kohaut \n" "Language-Team: Slovak \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:42+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/sl.po b/openerp/addons/base/i18n/sl.po index f9eeb1456c2..7fb3aa56052 100644 --- a/openerp/addons/base/i18n/sl.po +++ b/openerp/addons/base/i18n/sl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 15:48+0000\n" +"PO-Revision-Date: 2012-08-20 15:52+0000\n" "Last-Translator: Mustufa Rangwala (Open ERP) \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:43+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/sq.po b/openerp/addons/base/i18n/sq.po index b1f0478ed8a..d7e31006f9a 100644 --- a/openerp/addons/base/i18n/sq.po +++ b/openerp/addons/base/i18n/sq.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:36+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/sr.po b/openerp/addons/base/i18n/sr.po index e8c74060cc3..b409d0c1fa1 100644 --- a/openerp/addons/base/i18n/sr.po +++ b/openerp/addons/base/i18n/sr.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 15:52+0000\n" +"PO-Revision-Date: 2012-08-20 15:30+0000\n" "Last-Translator: Antony Lesuisse (OpenERP) \n" "Language-Team: Serbian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:42+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/sr@latin.po b/openerp/addons/base/i18n/sr@latin.po index 5c187aeec8b..28f5c4fcf97 100644 --- a/openerp/addons/base/i18n/sr@latin.po +++ b/openerp/addons/base/i18n/sr@latin.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-02-15 22:07+0000\n" -"Last-Translator: zmmaj \n" +"PO-Revision-Date: 2012-08-20 15:35+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: Serbian latin \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:46+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/sv.po b/openerp/addons/base/i18n/sv.po index 2e9ff2e0539..70905626277 100644 --- a/openerp/addons/base/i18n/sv.po +++ b/openerp/addons/base/i18n/sv.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-06-18 22:03+0000\n" +"PO-Revision-Date: 2012-08-20 15:27+0000\n" "Last-Translator: Fabien (Open ERP) \n" "Language-Team: <>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:43+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -873,7 +873,7 @@ msgstr "Kambodja (kungariket)" #: field:base.language.import,overwrite:0 #: field:base.language.install,overwrite:0 msgid "Overwrite Existing Terms" -msgstr "Skriv över existerande villkor" +msgstr "Skriv över nuvarande fraser" #. module: base #: model:ir.model,name:base.model_base_language_import @@ -7241,7 +7241,7 @@ msgstr "" #. module: base #: view:res.widget.wizard:0 msgid "Widget Wizard" -msgstr "Widget Wizard" +msgstr "Komponentguide" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_hn @@ -10676,7 +10676,7 @@ msgstr "" #. module: base #: view:ir.actions.todo.category:0 msgid "Wizard Category" -msgstr "" +msgstr "Guidekategori" #. module: base #: model:ir.module.module,description:base.module_account_cancel @@ -10995,7 +10995,7 @@ msgstr "" #. module: base #: model:ir.model,name:base.model_ir_actions_todo_category msgid "Configuration Wizard Category" -msgstr "" +msgstr "Konfigurationsguidekategori" #. module: base #: view:base.module.update:0 diff --git a/openerp/addons/base/i18n/th.po b/openerp/addons/base/i18n/th.po index df20f7a2adc..95cbf8b8e7e 100644 --- a/openerp/addons/base/i18n/th.po +++ b/openerp/addons/base/i18n/th.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:43+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/tlh.po b/openerp/addons/base/i18n/tlh.po index 805035cf850..a01448bde57 100644 --- a/openerp/addons/base/i18n/tlh.po +++ b/openerp/addons/base/i18n/tlh.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:43+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/tr.po b/openerp/addons/base/i18n/tr.po index b6670894b5c..c3827b43537 100644 --- a/openerp/addons/base/i18n/tr.po +++ b/openerp/addons/base/i18n/tr.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-02-09 21:13+0000\n" -"Last-Translator: Ahmet Altınışık \n" +"PO-Revision-Date: 2012-08-20 15:34+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:43+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -50,7 +50,7 @@ msgstr "" #: field:ir.ui.view,arch:0 #: field:ir.ui.view.custom,arch:0 msgid "View Architecture" -msgstr "Mimari Görüntüleme" +msgstr "Görünüm Yapısı" #. module: base #: model:ir.module.module,description:base.module_project diff --git a/openerp/addons/base/i18n/uk.po b/openerp/addons/base/i18n/uk.po index 79d5db6ef59..fb53900b256 100644 --- a/openerp/addons/base/i18n/uk.po +++ b/openerp/addons/base/i18n/uk.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 16:43+0000\n" +"PO-Revision-Date: 2012-08-20 15:49+0000\n" "Last-Translator: Antony Lesuisse (OpenERP) \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:43+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/uk_UA.po b/openerp/addons/base/i18n/uk_UA.po index 8263fde5c5e..8a8f1d3613f 100644 --- a/openerp/addons/base/i18n/uk_UA.po +++ b/openerp/addons/base/i18n/uk_UA.po @@ -4551,7 +4551,7 @@ msgstr "html" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "ПДВ" #. module: base diff --git a/openerp/addons/base/i18n/ur.po b/openerp/addons/base/i18n/ur.po index 4239bc2adf3..5942b9e11a0 100644 --- a/openerp/addons/base/i18n/ur.po +++ b/openerp/addons/base/i18n/ur.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:44+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/vi.po b/openerp/addons/base/i18n/vi.po index 0255aaf2f57..fbf09c542a4 100644 --- a/openerp/addons/base/i18n/vi.po +++ b/openerp/addons/base/i18n/vi.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2011-11-05 03:38+0000\n" -"Last-Translator: Vuong Kien Hung \n" +"PO-Revision-Date: 2012-08-20 15:37+0000\n" +"Last-Translator: OpenERP Administrators \n" "Language-Team: Vietnamese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:44+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/zh_CN.po b/openerp/addons/base/i18n/zh_CN.po index ee0f43d8372..c80e08c3c03 100644 --- a/openerp/addons/base/i18n/zh_CN.po +++ b/openerp/addons/base/i18n/zh_CN.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-03-11 06:21+0000\n" +"PO-Revision-Date: 2012-08-20 15:29+0000\n" "Last-Translator: Wei \"oldrev\" Li \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:45+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh @@ -10216,6 +10216,9 @@ msgid "" " OpenERP Web example module.\n" " " msgstr "" +"\n" +" OpenERP Web 示例模块。\n" +" " #. module: base #: model:res.country,name:base.gy @@ -11508,7 +11511,7 @@ msgstr "阿尔巴尼亚" msgid "" "Level of difficulty of module. Easy: intuitive and easy to use for everyone. " "Normal: easy to use for business experts. Expert: requires technical skills." -msgstr "" +msgstr "模块难度。简单:直观、易于使用。普通:对商务专家来说易于使用。专家:需要技术能力。" #. module: base #: code:addons/base/res/res_lang.py:191 @@ -11973,7 +11976,7 @@ msgid "" "This wizard helps you to import a new module to your OpenERP system. After " "importing a new module you can install it by clicking on the button " "\"Install\" from the form view." -msgstr "" +msgstr "此向导帮助您向 OpenERP 系统中导入一个新模块。模块导入后,您可以通过点击表单视图上的\"安装\"按钮进行安装。" #. module: base #: model:res.country,name:base.ch @@ -12953,7 +12956,7 @@ msgstr "哥斯达黎加" #. module: base #: model:ir.module.module,shortdesc:base.module_base_module_doc_rst msgid "Generate Docs of Modules" -msgstr "" +msgstr "生成模块文档" #. module: base #: model:res.company,overdue_msg:base.main_company @@ -12969,7 +12972,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_users_ldap msgid "Authentication via LDAP" -msgstr "" +msgstr "使用 LDAP 认证" #. module: base #: view:workflow.activity:0 @@ -13160,7 +13163,7 @@ msgstr "" #. module: base #: field:res.country,address_format:0 msgid "Address Format" -msgstr "" +msgstr "地址格式" #. module: base #: model:ir.model,name:base.model_ir_values diff --git a/openerp/addons/base/i18n/zh_HK.po b/openerp/addons/base/i18n/zh_HK.po index 96313cd3e58..f29b2edd59e 100644 --- a/openerp/addons/base/i18n/zh_HK.po +++ b/openerp/addons/base/i18n/zh_HK.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:44+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/i18n/zh_TW.po b/openerp/addons/base/i18n/zh_TW.po index a4804f29e56..9886f689f96 100644 --- a/openerp/addons/base/i18n/zh_TW.po +++ b/openerp/addons/base/i18n/zh_TW.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-01-31 16:14+0000\n" +"PO-Revision-Date: 2012-08-20 15:41+0000\n" "Last-Translator: Walter Cheuk \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-07-19 04:45+0000\n" -"X-Generator: Launchpad (build 15637)\n" +"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n" +"X-Generator: Launchpad (build 15901)\n" #. module: base #: model:res.country,name:base.sh diff --git a/openerp/addons/base/ir/ir.xml b/openerp/addons/base/ir/ir.xml index fac2946e204..29bb681981a 100644 --- a/openerp/addons/base/ir/ir.xml +++ b/openerp/addons/base/ir/ir.xml @@ -556,30 +556,6 @@ - - - ir.needaction_users_rel.tree - ir.needaction_users_rel - 10 - - - - - - - - - - - Need action relationships - ir.needaction_users_rel - form - tree,form - - - - - ir.ui.view @@ -600,8 +576,15 @@ - - + + + + + + + + + @@ -1174,6 +1157,7 @@ + @@ -1186,6 +1170,9 @@ ir.translation
+
+ +
@@ -1211,12 +1198,12 @@ Translations ir.translation - - + + - - - + + + diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index a5d04d7f1bc..383f78181e9 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -35,6 +35,7 @@ from tools.config import config from tools.safe_eval import safe_eval as eval from tools.translate import _ from socket import gethostname +from openerp import SUPERUSER_ID _logger = logging.getLogger(__name__) @@ -43,7 +44,7 @@ class actions(osv.osv): _table = 'ir_actions' _order = 'name' _columns = { - 'name': fields.char('Action Name', required=True, size=64), + 'name': fields.char('Name', size=64, required=True), 'type': fields.char('Action Type', required=True, size=32,readonly=True), 'usage': fields.char('Action Usage', size=32), } @@ -271,7 +272,7 @@ class act_window(osv.osv): :return: A read() view of the ir.actions.act_window """ dataobj = self.pool.get('ir.model.data') - data_id = dataobj._get_id (cr, 1, module, xml_id) + data_id = dataobj._get_id (cr, SUPERUSER_ID, module, xml_id) res_id = dataobj.browse(cr, uid, data_id, context).res_id return self.read(cr, uid, res_id, [], context) @@ -860,11 +861,10 @@ class act_client(osv.osv): _order = 'name' def _get_params(self, cr, uid, ids, field_name, arg, context): - return dict([ - ((record.id, ast.literal_eval(record.params_store)) - if record.params_store else (record.id, False)) - for record in self.browse(cr, uid, ids, context=context) - ]) + result = {} + for record in self.browse(cr, uid, ids, context=context): + result[record.id] = record.params_store and eval(record.params_store, {'uid': uid}) or False + return result def _set_params(self, cr, uid, id, field_name, field_value, arg, context): if isinstance(field_value, dict): @@ -873,10 +873,15 @@ class act_client(osv.osv): self.write(cr, uid, id, {'params_store': field_value}, context=context) _columns = { + 'name': fields.char('Action Name', required=True, size=64, translate=True), 'tag': fields.char('Client action tag', size=64, required=True, help="An arbitrary string, interpreted by the client" " according to its own needs and wishes. There " "is no central tag repository across clients."), + 'res_model': fields.char('Destination Model', size=64, + help="Optional model, mostly used for needactions."), + 'context': fields.char('Context Value', size=250, required=True, + help="Context dictionary as Python expression, empty by default (Default: {})"), 'params': fields.function(_get_params, fnct_inv=_set_params, type='binary', string="Supplementary arguments", @@ -886,6 +891,7 @@ class act_client(osv.osv): } _defaults = { 'type': 'ir.actions.client', + 'context': '{}', } act_client() diff --git a/openerp/addons/base/ir/ir_config_parameter.py b/openerp/addons/base/ir/ir_config_parameter.py index f21c2db8d0a..120fcfca554 100644 --- a/openerp/addons/base/ir/ir_config_parameter.py +++ b/openerp/addons/base/ir/ir_config_parameter.py @@ -26,6 +26,7 @@ from osv import osv,fields import uuid import datetime from tools import misc, config +from openerp import SUPERUSER_ID """ A dictionary holding some configuration parameters to be initialized when the database is created. @@ -55,9 +56,9 @@ class ir_config_parameter(osv.osv): Initializes the parameters listed in _default_parameters. """ for key, func in _default_parameters.iteritems(): - ids = self.search(cr, 1, [('key','=',key)]) + ids = self.search(cr, SUPERUSER_ID, [('key','=',key)]) if not ids: - self.set_param(cr, 1, key, func()) + self.set_param(cr, SUPERUSER_ID, key, func()) def get_param(self, cr, uid, key, default=False, context=None): """Retrieve the value for a given key. diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index e777b390aa8..46ab8841deb 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -183,7 +183,6 @@ class ir_model(osv.osv): res = super(ir_model,self).create(cr, user, vals, context) if vals.get('state','base')=='manual': self.instanciate(cr, user, vals['model'], context) - self.pool.get(vals['model']).__init__(self.pool, cr) ctx = dict(context, field_name=vals['name'], field_state='manual', @@ -198,7 +197,9 @@ class ir_model(osv.osv): x_custom_model._name = model x_custom_model._module = False a = x_custom_model.create_instance(self.pool, cr) - if (not a._columns) or ('x_name' in a._columns.keys()): + if not a._columns: + x_name = 'id' + elif 'x_name' in a._columns.keys(): x_name = 'x_name' else: x_name = a._columns.keys()[0] @@ -931,6 +932,9 @@ class ir_model_data(osv.osv): ir_model_relation = self.pool.get('ir.model.relation') relation_ids = ir_model_relation.search(cr, uid, [('module', 'in', modules_to_remove)]) + ir_module_module = self.pool.get('ir.module.module') + modules_to_remove_ids = ir_module_module.search(cr, uid, [('name', 'in', modules_to_remove)]) + relation_ids = ir_model_relation.search(cr, uid, [('module', 'in', modules_to_remove_ids)]) ir_model_relation._module_data_uninstall(cr, uid, relation_ids, context) unlink_if_refcount((model, res_id) for model, res_id in to_unlink diff --git a/openerp/addons/base/ir/ir_model_constraint.py b/openerp/addons/base/ir/ir_model_constraint.py index 4a69bc2f0a7..a3099339131 100644 --- a/openerp/addons/base/ir/ir_model_constraint.py +++ b/openerp/addons/base/ir/ir_model_constraint.py @@ -45,7 +45,6 @@ class ir_model_constraint(Model): ids_set = set(ids) ids.sort() ids.reverse() - to_unlink = [] for data in self.browse(cr, uid, ids, context): model = data.model.model model_obj = self.pool.get(model) @@ -75,5 +74,4 @@ class ir_model_constraint(Model): cr.execute('ALTER TABLE "%s" DROP CONSTRAINT "%s"' % (model_obj._table, name),) _logger.info('Dropped CONSTRAINT %s@%s', name, model) - to_unlink.append(data.id) - self.unlink(cr, uid, to_unlink, context) + self.unlink(cr, uid, ids, context) diff --git a/openerp/addons/base/ir/ir_model_relation.py b/openerp/addons/base/ir/ir_model_relation.py index eede6eae44f..fc6dae2ca52 100644 --- a/openerp/addons/base/ir/ir_model_relation.py +++ b/openerp/addons/base/ir/ir_model_relation.py @@ -36,7 +36,6 @@ class ir_model_relation(Model): to_drop_table = [] ids.sort() ids.reverse() - to_unlink = [] for data in self.browse(cr, uid, ids, context): model = data.model model_obj = self.pool.get(model) @@ -53,9 +52,7 @@ class ir_model_relation(Model): if cr.fetchone() and not name in to_drop_table: to_drop_table.append(name) - to_unlink.append(data.id) - - self.unlink(cr, uid, to_unlink, context) + self.unlink(cr, uid, ids, context) # drop m2m relation tables for table in to_drop_table: diff --git a/openerp/addons/base/ir/ir_needaction.py b/openerp/addons/base/ir/ir_needaction.py index 0f28c33ded9..db133ad9904 100644 --- a/openerp/addons/base/ir/ir_needaction.py +++ b/openerp/addons/base/ir/ir_needaction.py @@ -19,180 +19,45 @@ # ############################################################################## -import openerp.pooler as pooler -from operator import itemgetter -from osv import osv, fields -from tools.translate import _ +from osv import osv -class ir_needaction_users_rel(osv.Model): - ''' ir_needaction_users_rel holds data related to the needaction - mechanism inside OpenERP. A row in this model is characterized - by: - - res_model: model of the record requiring an action - - res_id: ID of the record requiring an action - - user_id: foreign key to the res.users table, to the user that has to - perform the action - This model can be seen as a many2many, linking (res_model, res_id) to users - (those whose attention is required on the record). ''' - - _name = 'ir.needaction_users_rel' - _description = 'Needaction relationship table' - _rec_name = 'id' - _order = 'id desc' - _columns = { - 'res_model': fields.char('Related Document Model', size=128, - select=1, required=True), - 'res_id': fields.integer('Related Document ID', - select=1, required=True), - 'user_id': fields.many2one('res.users', string='Related User', - ondelete='cascade', select=1, required=True), - } - - def _get_users(self, cr, uid, res_ids, res_model, context=None): - """Given res_ids of res_model, get user_ids present in table""" - rel_ids = self.search(cr, uid, [('res_model', '=', res_model), ('res_id', 'in', res_ids)], context=context) - return list(set(map(itemgetter('user_id'), self.read(cr, uid, rel_ids, ['user_id'], context=context)))) - - def create_users(self, cr, uid, res_ids, res_model, user_ids, context=None): - """Given res_ids of res_model, add user_ids to the relationship table""" - for res_id in res_ids: - for user_id in user_ids: - self.create(cr, uid, {'res_model': res_model, 'res_id': res_id, 'user_id': user_id}, context=context) - return True - - def unlink_users(self, cr, uid, res_ids, res_model, context=None): - """Given res_ids of res_model, delete all entries in the relationship table""" - to_del_ids = self.search(cr, uid, [('res_model', '=', res_model), ('res_id', 'in', res_ids)], context=context) - return self.unlink(cr, uid, to_del_ids, context=context) - - def update_users(self, cr, uid, res_ids, res_model, user_ids, context=None): - """Given res_ids of res_model, update their entries in the relationship table to user_ids""" - # read current records - cur_users = self._get_users(cr, uid, res_ids, res_model, context=context) - if len(cur_users) == len(user_ids) and all(cur_user in user_ids for cur_user in cur_users): - return True - # unlink old records - self.unlink_users(cr, uid, res_ids, res_model, context=context) - # link new records - self.create_users(cr, uid, res_ids, res_model, user_ids, context=context) - return True - - -class ir_needaction_mixin(osv.Model): +class ir_needaction_mixin(osv.AbstractModel): '''Mixin class for objects using the need action feature. - - Need action feature can be used by objects having to be able to - signal that an action is required on a particular record. If in - the business logic an action must be performed by somebody, for - instance validation by a manager, this mechanism allows to set a + + Need action feature can be used by models that have to be able to + signal that an action is required on a particular record. If in + the business logic an action must be performed by somebody, for + instance validation by a manager, this mechanism allows to set a list of users asked to perform an action. - - This class wraps a class (ir.ir_needaction_users_rel) that - behaves like a many2many field. This class handles the low-level - considerations of updating relationships. Every change made on - the record calls a method that updates the relationships. - - Objects using the 'need_action' feature should override the - ``get_needaction_user_ids`` method. This methods returns a - dictionary whose keys are record ids, and values a list of user - ids, like in a many2many relationship. Therefore by defining - only one method, you can specify if an action is required by - defining the users that have to do it, in every possible - situation. - - This class also offers several global services: - - ``needaction_get_record_ids``: for the current model and uid, get - all record ids that ask this user to perform an action. This - mechanism is used for instance to display the number of pending - actions in menus, such as Leads (12) - - ``needaction_get_action_count``: as ``needaction_get_record_ids`` - but returns only the number of action, not the ids (performs a - search with count=True) - The ``ir_needaction_mixin`` class adds a calculated field - ``needaction_pending``. This function field allows to state - whether a given record has a needaction for the current user. - This is usefull if you want to customize views according to the - needaction feature. For example, you may want to set records in - bold in a list view if the current user has an action to perform - on the record. ''' - + Models using the 'need_action' feature should override the + ``_needaction_domain_get`` method. This method returns a + domain to filter records requiring an action for a specific user. + + This class also offers several global services: + - ``_needaction_count``: returns the number of actions uid has to perform + ''' + _name = 'ir.needaction_mixin' - _description = 'Need action mixin' - - def get_needaction_pending(self, cr, uid, ids, name, arg, context=None): - res = {} - needaction_user_ids = self.get_needaction_user_ids(cr, uid, ids, context=context) - for id in ids: - res[id] = uid in needaction_user_ids[id] - return res + _needaction = True - def search_needaction_pending(self, cr, uid, self_again, field_name, criterion, context=None): - ids = self.needaction_get_record_ids( - cr, uid, uid, limit=1024, context=context) - return [('id', 'in', ids)] - - _columns = { - 'needaction_pending': fields.function( - get_needaction_pending, type='boolean', - fnct_search=search_needaction_pending, - string='Need action pending', - help="If True, this field states that users have to perform an " \ - "action This field comes from the ir.needaction_mixin class."), - } - #------------------------------------------------------ - # Addon API + # Addons API #------------------------------------------------------ - - def get_needaction_user_ids(self, cr, uid, ids, context=None): - """ Returns the user_ids that have to perform an action - :return: dict { record_id: [user_ids], } + + def _needaction_domain_get(self, cr, uid, context=None): + """ Returns the domain to filter records that require an action + :return: domain or False is no action """ - return dict((id,list()) for id in ids) - - def create(self, cr, uid, values, context=None): - rel_obj = self.pool.get('ir.needaction_users_rel') - # perform create - obj_id = super(ir_needaction_mixin, self).create(cr, uid, values, context=context) - # link user_ids - needaction_user_ids = self.get_needaction_user_ids(cr, uid, [obj_id], context=context) - rel_obj.create_users(cr, uid, [obj_id], self._name, needaction_user_ids[obj_id], context=context) - return obj_id - - def write(self, cr, uid, ids, values, context=None): - rel_obj = self.pool.get('ir.needaction_users_rel') - # perform write - write_res = super(ir_needaction_mixin, self).write(cr, uid, ids, values, context=context) - # get and update user_ids - needaction_user_ids = self.get_needaction_user_ids(cr, uid, ids, context=context) - for id in ids: - rel_obj.update_users(cr, uid, [id], self._name, needaction_user_ids[id], context=context) - return write_res - - def unlink(self, cr, uid, ids, context=None): - # unlink user_ids - rel_obj = self.pool.get('ir.needaction_users_rel') - rel_obj.unlink_users(cr, uid, ids, self._name, context=context) - # perform unlink - return super(ir_needaction_mixin, self).unlink(cr, uid, ids, context=context) - + return False + #------------------------------------------------------ # "Need action" API #------------------------------------------------------ - - def needaction_get_record_ids(self, cr, uid, user_id, limit=80, context=None): - """Given the current model and a user_id - return the record ids that require the user to perform an - action""" - rel_obj = self.pool.get('ir.needaction_users_rel') - rel_ids = rel_obj.search(cr, uid, [('res_model', '=', self._name), ('user_id', '=', user_id)], limit=limit, context=context) - return map(itemgetter('res_id'), rel_obj.read(cr, uid, rel_ids, ['res_id'], context=context)) - - def needaction_get_action_count(self, cr, uid, user_id, limit=80, context=None): - """Given the current model and a user_id - get the number of actions it has to perform""" - rel_obj = self.pool.get('ir.needaction_users_rel') - return rel_obj.search(cr, uid, [('res_model', '=', self._name), ('user_id', '=', user_id)], limit=limit, count=True, context=context) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + def _needaction_count(self, cr, uid, domain=[], context=None): + """ Get the number of actions uid has to perform. """ + dom = self._needaction_domain_get(cr, uid, context=context) + if not dom: + return 0 + return self.search(cr, uid, (domain or []) +dom, context=context, count=True) diff --git a/openerp/addons/base/ir/ir_rule.py b/openerp/addons/base/ir/ir_rule.py index 2b864a7f8c6..75882051e6b 100644 --- a/openerp/addons/base/ir/ir_rule.py +++ b/openerp/addons/base/ir/ir_rule.py @@ -44,7 +44,7 @@ class ir_rule(osv.osv): def _eval_context(self, cr, uid): """Returns a dictionary to use as evaluation context for ir.rule domains.""" - return {'user': self.pool.get('res.users').browse(cr, 1, uid), + return {'user': self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid), 'time':time} def _domain_force_get(self, cr, uid, ids, field_name, arg, context=None): @@ -152,7 +152,7 @@ class ir_rule(osv.osv): # involve objects on which the real uid has no acces rights. # This means also there is no implicit restriction (e.g. an object # references another object the user can't see). - query = self.pool.get(model_name)._where_calc(cr, 1, dom, active_test=False) + query = self.pool.get(model_name)._where_calc(cr, SUPERUSER_ID, dom, active_test=False) return query.where_clause, query.where_clause_params, query.tables return [], [], ['"'+self.pool.get(model_name)._table+'"'] diff --git a/openerp/addons/base/ir/ir_sequence.py b/openerp/addons/base/ir/ir_sequence.py index e3136b92b6e..8b03cd3f3b3 100644 --- a/openerp/addons/base/ir/ir_sequence.py +++ b/openerp/addons/base/ir/ir_sequence.py @@ -210,7 +210,7 @@ class ir_sequence(openerp.osv.osv.osv): def next_by_id(self, cr, uid, sequence_id, context=None): """ Draw an interpolated string using the specified sequence.""" - self.check_read(cr, uid) + self.check_access_rights(cr, uid, 'read') company_ids = self.pool.get('res.company').search(cr, uid, [], order='company_id', context=context) + [False] ids = self.search(cr, uid, ['&',('id','=', sequence_id),('company_id','in',company_ids)]) return self._next(cr, uid, ids, context) @@ -227,7 +227,7 @@ class ir_sequence(openerp.osv.osv.osv): sequence selection. A matching sequence for that specific company will get higher priority. """ - self.check_read(cr, uid) + self.check_access_rights(cr, uid, 'read') company_ids = self.pool.get('res.company').search(cr, uid, [], order='company_id', context=context) + [False] ids = self.search(cr, uid, ['&',('code','=', sequence_code),('company_id','in',company_ids)]) return self._next(cr, uid, ids, context) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index cd6fa271852..68b413344b2 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -74,17 +74,14 @@ class ir_translation_import_cursor(object): imd_name VARCHAR(128) ) INHERITS (%s) ''' % (self._table_name, self._parent_table)) - def push(self, ddict): + def push(self, trans_dict): """Feed a translation, as a dictionary, into the cursor """ - - self._cr.execute("INSERT INTO " + self._table_name \ - + """(name, lang, res_id, src, type, - imd_model, module, imd_name, value) - VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)""", - (ddict['name'], ddict['lang'], ddict.get('res_id'), ddict['src'], ddict['type'], - ddict.get('imd_model'), ddict.get('module'), ddict.get('imd_name'), - ddict['value'])) + params = dict(trans_dict, + state="translated" if trans_dict['value'] else "to_translate") + self._cr.execute("""INSERT INTO %s (name, lang, res_id, src, type, imd_model, module, imd_name, value, state) + VALUES (%(name)s, %(lang)s, %(res_id)s, %(src)s, %(type)s, %(imd_model)s, %(module)s, %(imd_name)s, %(value)s, %(state)s)""", + params) def finish(self): """ Transfer the data from the temp table to ir.translation @@ -125,15 +122,16 @@ class ir_translation_import_cursor(object): # Step 2: update existing (matching) translations if self._overwrite: cr.execute("""UPDATE ONLY %s AS irt - SET value = ti.value + SET value = ti.value, + state = 'translated' FROM %s AS ti WHERE %s AND ti.value IS NOT NULL AND ti.value != '' """ % (self._parent_table, self._table_name, find_expr)) # Step 3: insert new translations - cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value, module) - SELECT name, lang, res_id, src, type, value, module + cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value, module, state) + SELECT name, lang, res_id, src, type, value, module, state FROM %s AS ti WHERE NOT EXISTS(SELECT 1 FROM ONLY %s AS irt WHERE %s); """ % (self._parent_table, self._table_name, self._parent_table, find_expr)) @@ -168,6 +166,13 @@ class ir_translation(osv.osv): 'src': fields.text('Source'), 'value': fields.text('Translation Value'), 'module': fields.char('Module Name', size=128), + 'state': fields.selection([('to_translate','To Translate'), + ('inprogress','Translation in Progress'), + ('translated','Translated')]) + } + + _defaults = { + 'state':'to_translate', } _sql_constraints = [ ('lang_fkey_res_lang', 'FOREIGN KEY(lang) REFERENCES res_lang(code)', @@ -302,6 +307,10 @@ class ir_translation(osv.osv): context = {} if isinstance(ids, (int, long)): ids = [ids] + if vals.get('src') or ('value' in vals and not(vals.get('value'))): + result = vals.update({'state':'to_translate'}) + if vals.get('value'): + result = vals.update({'state':'translated'}) result = super(ir_translation, self).write(cursor, user, ids, vals, context=context) for trans_obj in self.read(cursor, user, ids, ['name','type','res_id','src','lang'], context=context): self._get_source.clear_cache(self, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], trans_obj['src']) @@ -319,6 +328,52 @@ class ir_translation(osv.osv): result = super(ir_translation, self).unlink(cursor, user, ids, context=context) return result + def translate_fields(self, cr, uid, model, id, field=None, context=None): + trans_model = self.pool.get(model) + domain = ['&', ('res_id', '=', id), ('name', '=like', model + ',%')] + langs_ids = self.pool.get('res.lang').search(cr, uid, [('code', '!=', 'en_US')], context=context) + langs = [lg.code for lg in self.pool.get('res.lang').browse(cr, uid, langs_ids, context=context)] + main_lang = 'en_US' + translatable_fields = [] + for f, info in trans_model._all_columns.items(): + if info.column.translate: + if info.parent_model: + parent_id = trans_model.read(cr, uid, [id], [info.parent_column], context=context)[0][info.parent_column][0] + translatable_fields.append({ 'name': f, 'id': parent_id, 'model': info.parent_model }) + domain.insert(0, '|') + domain.extend(['&', ('res_id', '=', parent_id), ('name', '=', "%s,%s" % (info.parent_model, f))]) + else: + translatable_fields.append({ 'name': f, 'id': id, 'model': model }) + if len(langs): + fields = [f.get('name') for f in translatable_fields] + record = trans_model.read(cr, uid, [id], fields, context={ 'lang': main_lang })[0] + for lg in langs: + for f in translatable_fields: + # Check if record exists, else create it (at once) + sql = """INSERT INTO ir_translation (lang, src, name, type, res_id, value) + SELECT %s, %s, %s, 'model', %s, %s WHERE NOT EXISTS + (SELECT 1 FROM ir_translation WHERE lang=%s AND name=%s AND res_id=%s AND type='model'); + UPDATE ir_translation SET src = %s WHERE lang=%s AND name=%s AND res_id=%s AND type='model'; + """ + src = record[f['name']] or None + name = "%s,%s" % (f['model'], f['name']) + cr.execute(sql, (lg, src , name, f['id'], src, lg, name, f['id'], src, lg, name, id)) + + action = { + 'name': 'Translate', + 'res_model': 'ir.translation', + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'tree,form', + 'domain': domain, + } + if field: + info = trans_model._all_columns[field] + action['context'] = { + 'search_default_name': "%s,%s" % (info.parent_model or model, field) + } + return action + def _get_import_cursor(self, cr, uid, context=None): """ Return a cursor-like object for fast inserting translations """ diff --git a/openerp/addons/base/ir/ir_ui_menu.py b/openerp/addons/base/ir/ir_ui_menu.py index 77c0c4d738a..51aee886390 100644 --- a/openerp/addons/base/ir/ir_ui_menu.py +++ b/openerp/addons/base/ir/ir_ui_menu.py @@ -23,11 +23,12 @@ import base64 import re import threading - +from tools.safe_eval import safe_eval as eval import tools import openerp.modules from osv import fields, osv from tools.translate import _ +from openerp import SUPERUSER_ID def one_in(setA, setB): """Check the presence of an element of setA in setB @@ -59,7 +60,7 @@ class ir_ui_menu(osv.osv): """ with self.cache_lock: modelaccess = self.pool.get('ir.model.access') - user_groups = set(self.pool.get('res.users').read(cr, 1, uid, ['groups_id'])['groups_id']) + user_groups = set(self.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['groups_id'])['groups_id']) result = [] for menu in self.browse(cr, uid, ids, context=context): # this key works because user access rights are all based on user's groups (cfr ir_model_access.check) @@ -255,23 +256,24 @@ class ir_ui_menu(osv.osv): return res - def _get_needaction_info(self, cr, uid, id, domain=[], context={}): - return [False, 0] - def _get_needaction(self, cr, uid, ids, field_names, args, context=None): - if context is None: - context = {} res = {} for menu in self.browse(cr, uid, ids, context=context): - res[menu.id] = {} - if menu.action and menu.action.type == 'ir.actions.act_window' and menu.action.res_model: - menu_needaction_res = self.pool.get(menu.action.res_model)._get_needaction_info(cr, uid, uid, domain=menu.action.domain, context=context) - else: - menu_needaction_res = [False, 0] - res[menu.id]['needaction_enabled'] = menu_needaction_res[0] - res[menu.id]['needaction_counter'] = menu_needaction_res[1] + res[menu.id] = { + 'needaction_enabled': False, + 'needaction_counter': False, + } + if menu.action and menu.action.type in ('ir.actions.act_window','ir.actions.client') and menu.action.res_model: + obj = self.pool.get(menu.action.res_model) + if obj._needaction: + if menu.action.type=='ir.actions.act_window': + dom = menu.action.domain and eval(menu.action.domain, {'uid': uid}) or [] + else: + dom = eval(menu.action.params_store or '{}', {'uid': uid}).get('domain') + res[menu.id]['needaction_enabled'] = obj._needaction + res[menu.id]['needaction_counter'] = obj._needaction_count(cr, uid, dom, context=context) return res - + _columns = { 'name': fields.char('Menu', size=64, required=True, translate=True), 'sequence': fields.integer('Sequence'), diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index b2805884f18..bad2c3d85af 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -78,6 +78,8 @@ class view(osv.osv): 'field_parent': fields.char('Child Field',size=64), 'xml_id': fields.function(osv.osv.get_xml_id, type='char', size=128, string="External ID", help="ID of the view defined in xml file"), + 'groups_id': fields.many2many('res.groups', 'ir_ui_view_group_rel', 'view_id', 'group_id', + string='Groups', help="If this field is empty, the view applies to all users. Otherwise, the view applies to the users of those groups only."), } _defaults = { 'arch': '\n\n\t\n', @@ -167,20 +169,25 @@ class view(osv.osv): :rtype: list of tuples :return: [(view_arch,view_id), ...] """ + user_groups = frozenset(self.pool.get('res.users').browse(cr, 1, uid, context).groups_id) if self.pool._init: # Module init currently in progress, only consider views from modules whose code was already loaded - query = """SELECT v.arch, v.id FROM ir_ui_view v LEFT JOIN ir_model_data md ON (md.model = 'ir.ui.view' AND md.res_id = v.id) + query = """SELECT v.id FROM ir_ui_view v LEFT JOIN ir_model_data md ON (md.model = 'ir.ui.view' AND md.res_id = v.id) WHERE v.inherit_id=%s AND v.model=%s AND md.module in %s ORDER BY priority""" query_params = (view_id, model, tuple(self.pool._init_modules)) else: # Modules fully loaded, consider all views - query = """SELECT v.arch, v.id FROM ir_ui_view v + query = """SELECT v.id FROM ir_ui_view v WHERE v.inherit_id=%s AND v.model=%s ORDER BY priority""" query_params = (view_id, model) cr.execute(query, query_params) - return cr.fetchall() + view_ids = [v[0] for v in cr.fetchall()] + # filter views based on user groups + return [(view.arch, view.id) + for view in self.browse(cr, 1, view_ids, context) + if not (view.groups_id and user_groups.isdisjoint(view.groups_id))] def write(self, cr, uid, ids, vals, context=None): if not isinstance(ids, (list, tuple)): diff --git a/openerp/addons/base/ir/workflow/workflow_view.xml b/openerp/addons/base/ir/workflow/workflow_view.xml index 44dbc54c718..d174928556f 100644 --- a/openerp/addons/base/ir/workflow/workflow_view.xml +++ b/openerp/addons/base/ir/workflow/workflow_view.xml @@ -52,6 +52,7 @@ + diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index fb10d78e5fe..04b1fed9b2b 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -18,12 +18,14 @@ # along with this program. If not, see . # ############################################################################## + +import base64 +from docutils.core import publish_string import imp import logging import re import urllib import zipimport -import base64 from openerp import modules, pooler, release, tools, addons from openerp.tools.parse_version import parse_version @@ -94,6 +96,14 @@ class module(osv.osv): 'module %s', name, exc_info=True) return info + def _get_desc(self, cr, uid, ids, field_name=None, arg=None, context=None): + res = dict.fromkeys(ids, '') + for module in self.browse(cr, uid, ids, context=context): + overrides = dict(embed_stylesheet=False, doctitle_xform=False, output_encoding='unicode') + output = publish_string(source=module.description, writer_name='html', settings_overrides=overrides) + res[module.id] = output + return res + def _get_latest_version(self, cr, uid, ids, field_name=None, arg=None, context=None): res = dict.fromkeys(ids, '') for m in self.browse(cr, uid, ids): @@ -183,6 +193,7 @@ class module(osv.osv): 'shortdesc': fields.char('Module Name', size=64, readonly=True, translate=True), 'summary': fields.char('Summary', size=64, readonly=True, translate=True), 'description': fields.text("Description", readonly=True, translate=True), + 'description_html': fields.function(_get_desc, string='Description HTML', type='html', method=True, readonly=True), 'author': fields.char("Author", size=128, readonly=True), 'maintainer': fields.char('Maintainer', size=128, readonly=True), 'contributors': fields.text('Contributors', readonly=True), @@ -222,7 +233,7 @@ class module(osv.osv): ('AGPL-3', 'Affero GPL-3'), ('Other OSI approved licence', 'Other OSI Approved Licence'), ('Other proprietary', 'Other Proprietary') - ], string='License', readonly=True), + ], string='License', readonly=True), 'menus_by_module': fields.function(_get_views, string='Menus', type='text', multi="meta", store=True), 'reports_by_module': fields.function(_get_views, string='Reports', type='text', multi="meta", store=True), 'views_by_module': fields.function(_get_views, string='Views', type='text', multi="meta", store=True), @@ -371,7 +382,8 @@ class module(osv.osv): ir_model_data = self.pool.get('ir.model.data') ir_model_constraint = self.pool.get('ir.model.constraint') modules_to_remove = [m.name for m in self.browse(cr, uid, ids, context)] - constraint_ids = ir_model_constraint.search(cr, uid, [('module', 'in', modules_to_remove)]) + modules_to_remove_ids = [m.id for m in self.browse(cr, uid, ids, context)] + constraint_ids = ir_model_constraint.search(cr, uid, [('module', 'in', modules_to_remove_ids)]) ir_model_constraint._module_data_uninstall(cr, uid, constraint_ids, context) ir_model_data._module_data_uninstall(cr, uid, modules_to_remove, context) self.write(cr, uid, ids, {'state': 'uninstalled'}) diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index 19f9dbdaa44..729d3ef7b4c 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -38,7 +38,7 @@ ir.module.module - @@ -69,7 +69,7 @@
-

+


@@ -133,7 +133,7 @@ - + diff --git a/openerp/addons/base/module/wizard/base_update_translations_view.xml b/openerp/addons/base/module/wizard/base_update_translations_view.xml index 1fe52511ebb..4a20ef30bee 100644 --- a/openerp/addons/base/module/wizard/base_update_translations_view.xml +++ b/openerp/addons/base/module/wizard/base_update_translations_view.xml @@ -10,7 +10,9 @@

-
diff --git a/openerp/addons/base/publisher_warranty/__init__.py b/openerp/addons/base/publisher_warranty/__init__.py deleted file mode 100644 index 6b60ddf3ca1..00000000000 --- a/openerp/addons/base/publisher_warranty/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -import publisher_warranty - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/openerp/addons/base/publisher_warranty/publisher_warranty.py b/openerp/addons/base/publisher_warranty/publisher_warranty.py deleted file mode 100644 index 897210ce817..00000000000 --- a/openerp/addons/base/publisher_warranty/publisher_warranty.py +++ /dev/null @@ -1,354 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 OpenERP S.A. (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -""" -Module to handle publisher warranty contracts as well as notifications from -OpenERP. -""" - -import datetime -import logging -import sys -import urllib -import urllib2 - -import pooler -import release -from osv import osv, fields -from tools.translate import _ -from tools.safe_eval import safe_eval -from tools.config import config -from tools import misc - -_logger = logging.getLogger(__name__) - -""" -Time interval that will be used to determine up to which date we will -check the logs to see if a message we just received was already logged. -@type: datetime.timedelta -""" -_PREVIOUS_LOG_CHECK = datetime.timedelta(days=365) - -class publisher_warranty_contract(osv.osv): - """ - Osv representing a publisher warranty contract. - """ - _name = "publisher_warranty.contract" - - def _get_valid_contracts(self, cr, uid): - """ - Return the list of the valid contracts encoded in the system. - - @return: A list of contracts - @rtype: list of publisher_warranty.contract browse records - """ - return [contract for contract in self.browse(cr, uid, self.search(cr, uid, [])) - if contract.state == 'valid'] - - def status(self, cr, uid): - """ Method called by the client to check availability of publisher warranty contract. """ - - contracts = self._get_valid_contracts(cr, uid) - return { - 'status': "full" if contracts else "none" , - 'uncovered_modules': list(), - } - - def send(self, cr, uid, tb, explanations, remarks=None, issue_name=None): - """ Method called by the client to send a problem to the publisher warranty server. """ - - if not remarks: - remarks = "" - - valid_contracts = self._get_valid_contracts(cr, uid) - valid_contract = valid_contracts[0] - - try: - origin = 'client' - dbuuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid') - db_create_date = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date') - user = self.pool.get("res.users").browse(cr, uid, uid) - user_name = user.name - email = user.email - - msg = {'contract_name': valid_contract.name, - 'tb': tb, - 'explanations': explanations, - 'remarks': remarks, - 'origin': origin, - 'dbname': cr.dbname, - 'dbuuid': dbuuid, - 'db_create_date': db_create_date, - 'issue_name': issue_name, - 'email': email, - 'user_name': user_name, - } - - - add_arg = {"timeout":30} if sys.version_info >= (2,6) else {} - uo = urllib2.urlopen(config.get("publisher_warranty_url"), - urllib.urlencode({'arg0': msg, "action": "send",}),**add_arg) - try: - submit_result = uo.read() - finally: - uo.close() - - result = safe_eval(submit_result) - - crm_case_id = result - - if not crm_case_id: - return False - - except osv.except_osv: - raise - except Exception: - _logger.warning("Error sending problem report", exc_info=1) - raise osv.except_osv(_("Error"), - _("Error during communication with the publisher warranty server.")) - - return True - - def check_validity(self, cr, uid, ids, context=None): - """ - Check the validity of a publisher warranty contract. This method just call get_logs() but checks - some more things, so it can be called from a user interface. - """ - contract_id = ids[0] - contract = self.browse(cr, uid, contract_id) - state = contract.state - validated = state != "unvalidated" - - self.get_logs(cr, uid, ids, cron_mode=False, context=context) - - contract = self.browse(cr, uid, contract_id) - validated2 = contract.state != "unvalidated" - if not validated and not validated2: - raise osv.except_osv(_("Contract validation error"), - _("Please verify your publisher warranty serial number and validity.")) - return True - - def get_logs(self, cr, uid, ids, cron_mode=True, context=None): - """ - Send a message to OpenERP's publisher warranty server to check the validity of - the contracts, get notifications, etc... - - @param cron_mode: If true, catch all exceptions (appropriate for usage in a cron). - @type cron_mode: boolean - """ - try: - try: - result = get_sys_logs(cr, uid) - except Exception: - if cron_mode: # we don't want to see any stack trace in cron - return False - _logger.debug("Exception while sending a get logs messages", exc_info=1) - raise osv.except_osv(_("Error"), _("Error during communication with the publisher warranty server.")) - - contracts = result["contracts"] - for contract in contracts: - c_id = self.search(cr, uid, [("name","=",contract)])[0] - # for backward compatibility - if type(contracts[contract]) == tuple: - self.write(cr, uid, c_id, { - "date_start": contracts[contract][0], - "date_stop": contracts[contract][1], - "state": contracts[contract][2], - "check_support": False, - "check_opw": False, - "kind": "", - }) - else: - self.write(cr, uid, c_id, { - "date_start": contracts[contract]["date_from"], - "date_stop": contracts[contract]["date_to"], - "state": contracts[contract]["state"], - "check_support": contracts[contract]["check_support"], - "check_opw": contracts[contract]["check_opw"], - "kind": contracts[contract]["kind"], - }) - - - limit_date = (datetime.datetime.now() - _PREVIOUS_LOG_CHECK).strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT) - - # old behavior based on res.log; now on mail.message, that is not necessarily installed - mail_message_obj = self.pool.get('mail.message') - if mail_message_obj: - for message in result["messages"]: - ids = mail_message_obj.search(cr, uid, [("model", "=", "publisher_warranty.contract"), - ("create_date", ">=", limit_date), - ("body_text", "=", message)]) - if ids: - continue - mail_message_obj.create(cr, uid, { - 'name': message, - 'model': "publisher_warranty.contract", - 'user_id': False, - }, context=context) - except Exception: - if cron_mode: - return False # we don't want to see any stack trace in cron - else: - raise - return True - - def get_last_user_messages(self, cr, uid, limit, context=None): - """ - Get the messages to be written in the web client. - @return: A list of html messages with ids, can be False or empty. - @rtype: list of tuples(int,string) - """ - if not self.pool.get('mail.message'): - return [] - ids = self.pool.get('mail.message').search(cr, uid, [("model", "=", "publisher_warranty.contract")] - , order="create_date desc", limit=limit, context=context) - if not ids: - return [] - messages = [(x.id, x.name) for x in self.pool.get('mail.message').browse(cr, uid, ids, context=context)] - return messages - - _columns = { - 'name' : fields.char('Serial Key', size=384, required=True, help="Your OpenERP Publisher's Warranty Contract unique key, also called serial number."), - 'date_start' : fields.date('Starting Date', readonly=True), - 'date_stop' : fields.date('Ending Date', readonly=True), - 'state' : fields.selection([('unvalidated', 'Unvalidated'), ('valid', 'Valid') - , ('terminated', 'Terminated'), ('canceled', 'Canceled')], string="State", readonly=True), - 'kind' : fields.char('Contract Category', size=64, readonly=True), - "check_support": fields.boolean("Support Level 1", readonly=True), - "check_opw": fields.boolean("OPW", readonly=True, help="Checked if this is an OpenERP Publisher's Warranty contract (versus older contract types"), - } - - _defaults = { - 'state': 'unvalidated', - } - - _sql_constraints = [ - ('uniq_name', 'unique(name)', "That contract is already registered in the system.") - ] - -publisher_warranty_contract() - -class maintenance_contract(osv.osv_memory): - """ Old osv we only keep for compatibility with the clients. """ - - _name = "maintenance.contract" - - def status(self, cr, uid): - return self.pool.get("publisher_warranty.contract").status(cr, uid) - - def send(self, cr, uid, tb, explanations, remarks=None, issue_name=None): - return self.pool.get("publisher_warranty.contract").send(cr, uid, tb, - explanations, remarks, issue_name) - -maintenance_contract() - -class publisher_warranty_contract_wizard(osv.osv_memory): - """ - A wizard osv to help people entering a publisher warranty contract. - """ - _name = 'publisher_warranty.contract.wizard' - _inherit = "ir.wizard.screen" - - _columns = { - 'name' : fields.char('Serial Key', size=256, required=True, help="Your OpenERP Publisher's Warranty Contract unique key, also called serial number."), - 'state' : fields.selection([("draft", "Draft"), ("finished", "Finished")]) - } - - _defaults = { - "state": "draft", - } - - def action_validate(self, cr, uid, ids, context=None): - if not ids: - return False - - wiz = self.browse(cr, uid, ids[0]) - c_name = wiz.name - - contract_osv = self.pool.get("publisher_warranty.contract") - contracts = contract_osv.search(cr, uid, [("name","=",c_name)]) - if contracts: - raise osv.except_osv(_("Error"), _("That contract is already registered in the system.")) - - contract_id = contract_osv.create(cr, uid, { - "name": c_name, - "state": "unvalidated", - }) - - contract_osv.check_validity(cr, uid, [contract_id]) - - self.write(cr, uid, ids, {"state": "finished"}) - - # We should return an action ? - return True - - -publisher_warranty_contract_wizard() - -def get_sys_logs(cr, uid): - """ - Utility method to send a publisher warranty get logs messages. - """ - pool = pooler.get_pool(cr.dbname) - - dbuuid = pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid') - db_create_date = pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date') - limit_date = datetime.datetime.now() - limit_date = limit_date - datetime.timedelta(15) - limit_date_str = limit_date.strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT) - nbr_users = pool.get("res.users").search(cr, uid, [], count=True) - nbr_active_users = pool.get("res.users").search(cr, uid, [("date", ">=", limit_date_str)], count=True) - nbr_share_users = False - nbr_active_share_users = False - if "share" in pool.get("res.users")._all_columns: - nbr_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True)], count=True) - nbr_active_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True), ("date", ">=", limit_date_str)], count=True) - contractosv = pool.get('publisher_warranty.contract') - contracts = contractosv.browse(cr, uid, contractosv.search(cr, uid, [])) - user = pool.get("res.users").browse(cr, uid, uid) - msg = { - "dbuuid": dbuuid, - "nbr_users": nbr_users, - "nbr_active_users": nbr_active_users, - "nbr_share_users": nbr_share_users, - "nbr_active_share_users": nbr_active_share_users, - "dbname": cr.dbname, - "db_create_date": db_create_date, - "version": release.version, - "contracts": [c.name for c in contracts], - "language": user.lang, - } - - add_arg = {"timeout":30} if sys.version_info >= (2,6) else {} - arguments = {'arg0': msg, "action": "update",} - arguments_raw = urllib.urlencode(arguments) - url = config.get("publisher_warranty_url") - uo = urllib2.urlopen(url, arguments_raw, **add_arg) - try: - submit_result = uo.read() - finally: - uo.close() - - result = safe_eval(submit_result) if submit_result else {} - - return result - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/openerp/addons/base/publisher_warranty/publisher_warranty_data.xml b/openerp/addons/base/publisher_warranty/publisher_warranty_data.xml deleted file mode 100644 index 68594e5d88f..00000000000 --- a/openerp/addons/base/publisher_warranty/publisher_warranty_data.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - Update System Logs - - - 1 - weeks - -1 - - - - - 1000 - - - - \ No newline at end of file diff --git a/openerp/addons/base/publisher_warranty/publisher_warranty_view.xml b/openerp/addons/base/publisher_warranty/publisher_warranty_view.xml deleted file mode 100644 index f4c196db672..00000000000 --- a/openerp/addons/base/publisher_warranty/publisher_warranty_view.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - publisher_warranty.contract.tree - publisher_warranty.contract - - - - - - - - - - - - publisher_warranty.contract.form - publisher_warranty.contract - -
-
-
- - - - - - - - - - - - - - - - - -
-
-
- - - publisher_warranty.contract.search - publisher_warranty.contract - - - - - - - - - - - publisher_warranty.contract.calendar - publisher_warranty.contract - - - - - - - - - - Contracts - ir.actions.act_window - publisher_warranty.contract - form - tree,form,calendar - - - - - - - publisher_warranty.contract.add.wizard - publisher_warranty.contract.wizard - -
- - - - - - -
-
- -
-
- - - Register a Contract - ir.actions.act_window - publisher_warranty.contract.wizard - form - form - new - - - -
-
diff --git a/openerp/addons/base/report/corporate_defaults.xml b/openerp/addons/base/report/corporate_defaults.xml index 12e8bb5eeea..751693e7e89 100644 --- a/openerp/addons/base/report/corporate_defaults.xml +++ b/openerp/addons/base/report/corporate_defaults.xml @@ -2,8 +2,7 @@ - - + <name type="field" name="partner_id.name"/> <street type="field" name="street"/> diff --git a/openerp/addons/base/report/corporate_defaults.xsl b/openerp/addons/base/report/corporate_defaults.xsl index e0f6918ec59..9e976381e48 100644 --- a/openerp/addons/base/report/corporate_defaults.xsl +++ b/openerp/addons/base/report/corporate_defaults.xsl @@ -39,8 +39,7 @@ <!--page bottom--> <lines>1.5cm 2.2cm 19.9cm 2.2cm</lines> - <drawCentredString x="10.5cm" y="1.7cm"><xsl:value-of select="//corporate-header/corporation/rml_footer1"/></drawCentredString> - <drawCentredString x="10.5cm" y="1.25cm"><xsl:value-of select="//corporate-header/corporation/rml_footer2"/></drawCentredString> + <drawCentredString x="10.5cm" y="1.7cm"><xsl:value-of select="//corporate-header/corporation/rml_footer"/></drawCentredString> <drawCentredString x="10.5cm" y="0.8cm">Your contact : <xsl:value-of select="//corporate-header/user/name"/></drawCentredString> </xsl:template> @@ -73,8 +72,7 @@ <!--page bottom--> <lines>1.5cm 1.2cm 19.9cm 1.2cm</lines> - <drawCentredString x="10.5cm" y="1.7cm"><xsl:value-of select="//corporate-header/corporation/rml_footer1"/></drawCentredString> - <drawCentredString x="10.5cm" y="1.25cm"><xsl:value-of select="//corporate-header/corporation/rml_footer2"/></drawCentredString> + <drawCentredString x="10.5cm" y="1.7cm"><xsl:value-of select="//corporate-header/corporation/rml_footer"/></drawCentredString> <!-- <drawCentredString x="10.5cm" y="0.8cm">Your contact : <xsl:value-of select="//corporate-header/user/name"/></drawCentredString>--> </xsl:template> diff --git a/openerp/addons/base/report/corporate_sxw_header.xml b/openerp/addons/base/report/corporate_sxw_header.xml index d752ffa91a5..6cd8e5a218f 100644 --- a/openerp/addons/base/report/corporate_sxw_header.xml +++ b/openerp/addons/base/report/corporate_sxw_header.xml @@ -233,8 +233,7 @@ <table:table-column table:style-name="Table1.A"/> <table:table-row> <table:table-cell table:style-name="Table1.A1" table:value-type="string"> - <text:p text:style-name="P7">[[ company.rml_footer1 ]]</text:p> - <text:p text:style-name="P7">[[ company.rml_footer2 ]]</text:p> + <text:p text:style-name="P7">[[ company.rml_footer ]]</text:p> <text:p text:style-name="P7">Contact : [[ user.name ]]</text:p> </table:table-cell> </table:table-row> diff --git a/openerp/addons/base/report/mako_footer.html b/openerp/addons/base/report/mako_footer.html index 7c2d5b67a08..9f8990998a7 100644 --- a/openerp/addons/base/report/mako_footer.html +++ b/openerp/addons/base/report/mako_footer.html @@ -7,15 +7,8 @@ </tr> <tr> <td> - % if company['rml_footer1']: - <p align = "center"><small><b>${company.rml_footer1}</b></small></br></p> - %endif - </td> - </tr> - <tr> - <td> - % if company['rml_footer2']: - <p align = "center"><small><b>${company.rml_footer2}</b></small></br></p> + % if company['rml_footer']: + <p align="center"><small><b>${company.rml_footer}</b></small></p> %endif </td> </tr> diff --git a/openerp/addons/base/res/res_bank.py b/openerp/addons/base/res/res_bank.py index c5c05c1807c..a839afc10e4 100644 --- a/openerp/addons/base/res/res_bank.py +++ b/openerp/addons/base/res/res_bank.py @@ -109,7 +109,7 @@ class res_partner_bank(osv.osv): if not context.get('address'): return value - for address in self.pool.get('res.partner').resolve_o2m_commands_to_record_dicts( + for address in self.pool.get('res.partner').resolve_2many_commands( cursor, user, 'address', context['address'], ['type', field], context=context): if address.get('type') == 'default': diff --git a/openerp/addons/base/res/res_bank_view.xml b/openerp/addons/base/res/res_bank_view.xml index 0c88ceeff7c..8a8fa0e2922 100644 --- a/openerp/addons/base/res/res_bank_view.xml +++ b/openerp/addons/base/res/res_bank_view.xml @@ -91,8 +91,9 @@ <group col="4"> <field name="state"/> <field name="acc_number"/> - <field name="company_id" on_change="onchange_company_id(company_id)" invisible="context.get('company_hide', True)" widget="selection"/> - <field name="footer" attrs="{'invisible': [('company_id','=',False)]}"/> + <field name="company_id" on_change="onchange_company_id(company_id)" + invisible="context.get('company_hide', True)" widget="selection"/> + <field name="footer" invisible="context.get('footer_hide', True)"/> </group> <group> <group name="owner" string="Bank Account Owner"> @@ -128,7 +129,7 @@ <field name="acc_number"/> <field name="bank_name"/> <field name="company_id" invisible="context.get('company_hide', True)"/> - <field name="footer" invisible="context.get('company_hide', True)"/> + <field name="footer" invisible="context.get('footer_hide', True)"/> <field name="partner_id"/> </tree> </field> diff --git a/openerp/addons/base/res/res_company.py b/openerp/addons/base/res/res_company.py index 526ad0e0bad..83b24b55a93 100644 --- a/openerp/addons/base/res/res_company.py +++ b/openerp/addons/base/res/res_company.py @@ -24,6 +24,7 @@ from osv import fields import os import tools import openerp +from openerp import SUPERUSER_ID from tools.translate import _ from tools.safe_eval import safe_eval as eval @@ -88,7 +89,6 @@ class res_company(osv.osv): result[company.id][field] = address[field] or False return result - def _set_address_data(self, cr, uid, company_id, name, value, arg, context=None): """ Write the 'address' functional fields. """ company = self.browse(cr, uid, company_id, context=context) @@ -102,18 +102,18 @@ class res_company(osv.osv): part_obj.create(cr, uid, {name: value or False, 'parent_id': company.partner_id.id}, context=context) return True - _columns = { 'name': fields.related('partner_id', 'name', string='Company Name', size=128, required=True, store=True, type='char'), 'parent_id': fields.many2one('res.company', 'Parent Company', select=True), 'child_ids': fields.one2many('res.company', 'parent_id', 'Child Companies'), 'partner_id': fields.many2one('res.partner', 'Partner', required=True), - 'rml_header1': fields.char('Company Slogan', size=200, help="Appears by default on the top right corner of your printed documents (report header)."), - 'rml_footer1': fields.char('General Information Footer', size=200), - 'rml_footer2': fields.char('Bank Accounts Footer', size=250, help="Write here your bank accounts for customer payments."), 'rml_header': fields.text('RML Header', required=True), + 'rml_header1': fields.char('Company Slogan', size=200, help="Appears by default on the top right corner of your printed documents (report header)."), 'rml_header2': fields.text('RML Internal Header', required=True), 'rml_header3': fields.text('RML Internal Header for Landscape Reports', required=True), + 'rml_footer': fields.text('Report Footer', help="Footer text displayed at the bottom of all reports. Automatically set based on company details, "\ + "but may also be customized by directly editing it."), + 'custom_footer': fields.boolean('Custom Footer', help="Check this to define the report footer manually. Otherwise it will be filled in automatically."), 'logo': fields.related('partner_id', 'image', string="Logo", type="binary"), 'currency_id': fields.many2one('res.currency', 'Currency', required=True), 'currency_ids': fields.one2many('res.currency', 'company_id', 'Currency'), @@ -137,15 +137,43 @@ class res_company(osv.osv): _sql_constraints = [ ('name_uniq', 'unique (name)', 'The company name must be unique !') ] - def on_change_header(self, cr, uid, ids, phone, email, fax, website, vat, reg=False, context=None): - val = [] - if phone: val.append(_('Phone: ')+phone) - if fax: val.append(_('Fax: ')+fax) - if website: val.append(_('Website: ')+website) - if vat: val.append(_('VAT: ')+vat) - if reg: val.append(_('Reg: ')+reg) - return {'value': {'rml_footer1':' | '.join(val)}} + def onchange_footer(self, cr, uid, ids, context=None): + # when touched, the footer becomes custom + return {'value': {'custom_footer': True}} + + def set_auto_footer(self, cr, uid, ids, context=None): + # unset the flag 'custom_footer'; this will automatically compute the footer + return self.write(cr, uid, ids, {'custom_footer': False}, context=context) + + def compute_footer(self, cr, uid, ids, context=None): + res_partner_bank = self.pool.get('res.partner.bank') + for company in self.browse(cr, uid, ids, context): + if not company.custom_footer: + # first line (notice that missing elements are filtered out before the join) + res = ' | '.join(filter(bool, [ + company.phone and '%s: %s' % (_('Phone'), company.phone), + company.fax and '%s: %s' % (_('Fax'), company.fax), + company.email and '%s: %s' % (_('Email'), company.email), + company.website and '%s: %s' % (_('Website'), company.website), + company.vat and '%s: %s' % (_('TIN'), company.vat), + company.company_registry and '%s: %s' % (_('Reg'), company.company_registry), + ])) + # second line: bank accounts + account_ids = [acc.id for acc in company.bank_ids if acc.footer] + account_names = res_partner_bank.name_get(cr, uid, account_ids, context=context) + if account_names: + title = _('Bank Accounts') if len(account_names) > 1 else _('Bank Account') + res += '\n%s: %s' % (title, ', '.join(name for id, name in account_names)) + # update footer + self.write(cr, uid, [company.id], {'rml_footer': res}, context=context) + return True + + def on_change_country(self, cr, uid, ids, country_id, context=None): + currency_id = self._get_euro(cr, uid, context=context) + if country_id: + currency_id = self.pool.get('res.country').browse(cr, uid, country_id, context=context).currency_id.id + return {'value': {'currency_id': currency_id}} def _search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None): @@ -156,7 +184,7 @@ class res_company(osv.osv): # select only the currently visible companies (according to rules, # which are probably to allow to see the child companies) even if # she belongs to some other companies. - user = self.pool.get('res.users').browse(cr, 1, uid, context=context) + user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context) cmp_ids = list(set([user.company_id.id] + [cmp.id for cmp in user.company_ids])) return cmp_ids return super(res_company, self)._search(cr, uid, args, offset=offset, limit=limit, order=order, @@ -220,17 +248,22 @@ class res_company(osv.osv): self.cache_restart(cr) company_id = super(res_company, self).create(cr, uid, vals, context=context) obj_partner.write(cr, uid, partner_id, {'company_id': company_id}, context=context) + self.compute_footer(cr, uid, [company_id], context=context) return company_id - def write(self, cr, *args, **argv): + def write(self, cr, uid, ids, values, context=None): self.cache_restart(cr) - return super(res_company, self).write(cr, *args, **argv) + if isinstance(ids, (int, long)): + ids = [ids] + super(res_company, self).write(cr, uid, ids, values, context=context) + if 'rml_footer' not in values: + self.compute_footer(cr, uid, ids, context=context) + return True def _get_euro(self, cr, uid, context=None): - try: - return self.pool.get('res.currency').search(cr, uid, [])[0] - except: - return False + rate_obj = self.pool.get('res.currency.rate') + rate_id = rate_obj.search(cr, uid, [('rate', '=', 1)], context=context) + return rate_id and rate_obj.browse(cr, uid, rate_id[0], context=context).currency_id.id or False def _get_logo(self, cr, uid, ids): return open(os.path.join( tools.config['root_path'], 'addons', 'base', 'res', 'res_company_logo.png'), 'rb') .read().encode('base64') @@ -267,20 +300,22 @@ class res_company(osv.osv): return self._header_a4 _header_main = """ - <header> +<header> <pageTemplate> - <frame id="first" x1="1.3cm" y1="2.5cm" height="%s" width="19.0cm"/> + <frame id="first" x1="1.3cm" y1="3.0cm" height="%s" width="19.0cm"/> + <stylesheet> + <paraStyle name="main_footer" fontName="DejaVu Sans" fontSize="8.0" alignment="CENTER"/> + </stylesheet> <pageGraphics> <!-- You Logo - Change X,Y,Width and Height --> <image x="1.3cm" y="%s" height="40.0" >[[ company.logo or removeParentNode('image') ]]</image> <setFont name="DejaVu Sans" size="8"/> <fill color="black"/> <stroke color="black"/> + + <!-- page header --> <lines>1.3cm %s 20cm %s</lines> - <drawRightString x="20cm" y="%s">[[ company.rml_header1 ]]</drawRightString> - - <drawString x="1.3cm" y="%s">[[ company.partner_id.name ]]</drawString> <drawString x="1.3cm" y="%s">[[ company.partner_id.street or '' ]]</drawString> <drawString x="1.3cm" y="%s">[[ company.partner_id.city or '' ]] - [[ company.partner_id.country_id and company.partner_id.country_id.name or '']]</drawString> @@ -290,13 +325,19 @@ class res_company(osv.osv): <drawRightString x="7cm" y="%s">[[ company.partner_id.email or '' ]]</drawRightString> <lines>1.3cm %s 7cm %s</lines> + <!-- left margin --> + <rotate degrees="90"/> + <fill color="grey"/> + <drawString x="2.65cm" y="-0.4cm">produced by OpenERP.com</drawString> + <fill color="black"/> + <rotate degrees="-90"/> + <!--page bottom--> - - <lines>1.2cm 2.15cm 19.9cm 2.15cm</lines> - - <drawCentredString x="10.5cm" y="1.7cm">[[ company.rml_footer1 ]]</drawCentredString> - <drawCentredString x="10.5cm" y="1.25cm">[[ company.rml_footer2 ]]</drawCentredString> - <drawCentredString x="10.5cm" y="0.8cm">Contact : [[ user.name ]] - Page: <pageNumber/></drawCentredString> + <lines>1.2cm 2.65cm 19.9cm 2.65cm</lines> + <place x="1.3cm" y="0cm" height="2.55cm" width="19.0cm"> + <para style="main_footer">[[ company.rml_footer ]]</para> + <para style="main_footer">Contact : [[ user.name ]] - Page: <pageNumber/></para> + </place> </pageGraphics> </pageTemplate> </header>""" diff --git a/openerp/addons/base/res/res_company_view.xml b/openerp/addons/base/res/res_company_view.xml index 1cf32c03753..b92cfba19b6 100644 --- a/openerp/addons/base/res/res_company_view.xml +++ b/openerp/addons/base/res/res_company_view.xml @@ -31,19 +31,15 @@ <h1> <field name="name" class="oe_inline"/> </h1> - <label for="rml_header1" class="oe_edit_only"/> - <div> - <field name="rml_header1" placeholder="e.g. Global Business Solutions"/> - </div> </div> <group col="4"> - <field name="partner_id" readonly="1" required="0" groups="base.group_no_one"/> <field name="parent_id" groups="base.group_multi_company"/> </group> <notebook colspan="4"> <page string="General Information"> <group> <group> + <field name="partner_id" readonly="1" required="0" groups="base.group_no_one"/> <label for="street" string="Address"/> <div> <field name="street" placeholder="Street..."/> @@ -53,32 +49,38 @@ <field name="state_id" class="oe_no_button" placeholder="State" style="width: 24%%" options='{"no_open": true}'/> <field name="zip" placeholder="ZIP" style="width: 34%%"/> </div> - <field name="country_id" placeholder="Country" class="oe_no_button" options='{"no_open": true}'/> + <field name="country_id" placeholder="Country" class="oe_no_button" options='{"no_open": true}' on_change="on_change_country(country_id)"/> + </div> + <label for="rml_header1"/> + <div> + <field name="rml_header1" placeholder="e.g. Global Business Solutions"/> </div> <field name="website" widget="url" placeholder="e.g. www.openerp.com"/> </group> <group> - <field name="phone" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/> - <field name="fax" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/> - <field name="email" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/> - <field name="vat" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/> - <field name="company_registry" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/> + <field name="phone"/> + <field name="fax"/> + <field name="email"/> + <field name="vat"/> + <field name="company_registry"/> </group> </group> <group string="Bank Accounts"> - <field name="bank_ids" colspan="4" nolabel="1"/> - <label for="rml_footer2"/> - <div name="bank_acc"> - <field name="rml_footer2"/> - <!--<button name="%(bank_account_update)d" string="Set Bank Accounts" type="action" icon="gtk-go-forward" class="oe_inline"/>--> + <field name="bank_ids" nolabel="1" + context="{'default_company_id': active_id, 'footer_hide': False}"/> + </group> + <group string="Report Footer Configuration"> + <field name="paper_format" on_change="onchange_paper_format(paper_format)"/> + <field name="custom_footer" invisible="1"/> + <label for="rml_footer"/> + <div> + <field name="rml_footer" on_change="onchange_footer()"/> + <button string="Set Automatic Footer" type="object" name="set_auto_footer" + attrs="{'invisible': [('custom_footer','=',False)]}" class="oe_edit_only"/> </div> </group> </page> <page string="Header/Footer" groups="base.group_no_one"> - <group> - <field name="paper_format" on_change="onchange_paper_format(paper_format)"/> - <field name="rml_footer1"/> - </group> <label for="rml_header"/> <field name="rml_header"/> <label for="rml_header2"/> @@ -162,7 +164,7 @@ <field name="sequence"/> </group> </group> - </sheet> + </sheet> </form> </field> </record> @@ -190,4 +192,3 @@ </data> </openerp> - diff --git a/openerp/addons/base/res/res_config.xml b/openerp/addons/base/res/res_config.xml index bdfd6ab329c..342aeaa6e0f 100644 --- a/openerp/addons/base/res/res_config.xml +++ b/openerp/addons/base/res/res_config.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <openerp> <data> + <record id="res_config_view_base" model="ir.ui.view"> <field name="name">res.config.view.base</field> <field name="model">res.config</field> diff --git a/openerp/addons/base/res/res_country.py b/openerp/addons/base/res/res_country.py index 32980428068..29e72cf82e4 100644 --- a/openerp/addons/base/res/res_country.py +++ b/openerp/addons/base/res/res_country.py @@ -55,6 +55,7 @@ addresses belonging to this country.\n\nYou can use the python-style string pate \n%(state_code)s: the code of the state \n%(country_name)s: the name of the country \n%(country_code)s: the code of the country"""), + 'currency_id': fields.many2one('res.currency', 'Currency'), } _sql_constraints = [ ('name_uniq', 'unique (name)', @@ -63,7 +64,7 @@ addresses belonging to this country.\n\nYou can use the python-style string pate 'The code of the country must be unique !') ] _defaults = { - 'address_format': "%(company_name)s\n%(street)s\n%(street2)s\n%(city)s,%(state_code)s %(zip)s\n%(country_name)s", + 'address_format': "%(street)s\n%(street2)s\n%(city)s %(state_code)s %(zip)s\n%(country_name)s", } _order='name' diff --git a/openerp/addons/base/res/res_country_view.xml b/openerp/addons/base/res/res_country_view.xml index 3bead7a506c..c8046d34eb2 100644 --- a/openerp/addons/base/res/res_country_view.xml +++ b/openerp/addons/base/res/res_country_view.xml @@ -22,11 +22,17 @@ <field name="model">res.country</field> <field name="arch" type="xml"> <form string="Country" version="7.0"> - <group col="4"> - <field name="name"/> - <field name="code"/> - <field name="address_format" colspan="4" groups="base.group_no_one"/> + <group> + <group> + <field name="name"/> + <field name="currency_id"/> + </group> + <group> + <field name="code"/> + </group> </group> + <label for="address_format" string="Address Format"/> + <field name="address_format" colspan="4" groups="base.group_no_one"/> </form> </field> </record> diff --git a/openerp/addons/base/res/res_currency.py b/openerp/addons/base/res/res_currency.py index ac8ce1758cf..10a0b56b68c 100644 --- a/openerp/addons/base/res/res_currency.py +++ b/openerp/addons/base/res/res_currency.py @@ -56,7 +56,7 @@ class res_currency(osv.osv): _columns = { # Note: 'code' column was removed as of v6.0, the 'name' should now hold the ISO code. 'name': fields.char('Currency', size=32, required=True, help="Currency Code (ISO 4217)"), - 'symbol': fields.char('Symbol', size=3, help="Currency sign, to be used when printing amounts."), + 'symbol': fields.char('Symbol', size=4, help="Currency sign, to be used when printing amounts."), 'rate': fields.function(_current_rate, string='Current Rate', digits=(12,6), help='The rate of the currency to the currency of rate 1.'), 'rate_ids': fields.one2many('res.currency.rate', 'currency_id', 'Rates'), @@ -98,7 +98,10 @@ class res_currency(osv.osv): def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'): res = super(res_currency, self).read(cr, user, ids, fields, context, load) currency_rate_obj = self.pool.get('res.currency.rate') - for r in res: + values = res + if not isinstance(values, (list)): + values = [values] + for r in values: if r.__contains__('rate_ids'): rates=r['rate_ids'] if rates: diff --git a/openerp/addons/base/res/res_partner.py b/openerp/addons/base/res/res_partner.py index 4376cb694d3..c5dbd53a15e 100644 --- a/openerp/addons/base/res/res_partner.py +++ b/openerp/addons/base/res/res_partner.py @@ -21,7 +21,6 @@ import math import openerp -import os from osv import osv, fields import re import tools @@ -58,20 +57,20 @@ class res_partner_category(osv.osv): return super(res_partner_category, self).name_get(cr, uid, ids, context=context) if isinstance(ids, (int, long)): ids = [ids] - reads = self.read(cr, uid, ids, ['name','parent_id'], context=context) + reads = self.read(cr, uid, ids, ['name', 'parent_id'], context=context) res = [] for record in reads: name = record['name'] if record['parent_id']: - name = record['parent_id'][1]+' / '+name + name = record['parent_id'][1] + ' / ' + name res.append((record['id'], name)) return res def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: - args=[] + args = [] if not context: - context={} + context = {} if name: # Be sure name_search is symetric to name_get name = name.split(' / ')[-1] @@ -85,23 +84,23 @@ class res_partner_category(osv.osv): res = self.name_get(cr, uid, ids, context=context) return dict(res) - _description='Partner Categories' + _description = 'Partner Categories' _name = 'res.partner.category' _columns = { 'name': fields.char('Category Name', required=True, size=64, translate=True), 'parent_id': fields.many2one('res.partner.category', 'Parent Category', select=True, ondelete='cascade'), 'complete_name': fields.function(_name_get_fnc, type="char", string='Full Name'), 'child_ids': fields.one2many('res.partner.category', 'parent_id', 'Child Categories'), - 'active' : fields.boolean('Active', help="The active field allows you to hide the category without removing it."), - 'parent_left' : fields.integer('Left parent', select=True), - 'parent_right' : fields.integer('Right parent', select=True), + 'active': fields.boolean('Active', help="The active field allows you to hide the category without removing it."), + 'parent_left': fields.integer('Left parent', select=True), + 'parent_right': fields.integer('Right parent', select=True), 'partner_ids': fields.many2many('res.partner', id1='category_id', id2='partner_id', string='Partners'), } _constraints = [ (osv.osv._check_recursion, 'Error ! You can not create recursive categories.', ['parent_id']) ] _defaults = { - 'active' : lambda *a: 1, + 'active': lambda *a: 1, } _parent_store = True _parent_order = 'name' @@ -113,7 +112,7 @@ class res_partner_title(osv.osv): _columns = { 'name': fields.char('Title', required=True, size=46, translate=True), 'shortcut': fields.char('Abbreviation', size=16, translate=True), - 'domain': fields.selection([('partner','Partner'),('contact','Contact')], 'Domain', required=True, size=24) + 'domain': fields.selection([('partner', 'Partner'), ('contact', 'Contact')], 'Domain', required=True, size=24) } _defaults = { 'domain': 'contact', @@ -129,13 +128,13 @@ POSTAL_ADDRESS_FIELDS = ('street', 'street2', 'zip', 'city', 'state_id', 'countr ADDRESS_FIELDS = POSTAL_ADDRESS_FIELDS + ('email', 'phone', 'fax', 'mobile', 'website', 'ref', 'lang') class res_partner(osv.osv): - _description='Partner' + _description = 'Partner' _name = "res.partner" def _address_display(self, cr, uid, ids, name, args, context=None): - res={} + res = {} for partner in self.browse(cr, uid, ids, context=context): - res[partner.id] =self._display_address(cr, uid, partner, context=context) + res[partner.id] = self._display_address(cr, uid, partner, context=context) return res def _get_image(self, cr, uid, ids, name, args, context=None): @@ -143,7 +142,7 @@ class res_partner(osv.osv): for obj in self.browse(cr, uid, ids, context=context): result[obj.id] = tools.image_get_resized_images(obj.image) return result - + def _set_image(self, cr, uid, id, name, value, args, context=None): return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context) @@ -151,7 +150,7 @@ class res_partner(osv.osv): _columns = { 'name': fields.char('Name', size=128, required=True, select=True), 'date': fields.date('Date', select=1), - 'title': fields.many2one('res.partner.title','Title'), + 'title': fields.many2one('res.partner.title', 'Title'), 'parent_id': fields.many2one('res.partner', 'Owned by'), 'child_ids': fields.one2many('res.partner', 'parent_id', 'Contacts'), 'ref': fields.char('Reference', size=64, select=1), @@ -162,9 +161,9 @@ class res_partner(osv.osv): "It is important to set a value for this field. You should use the same timezone " "that is otherwise used to pick and render date and time values: your computer's timezone."), 'user_id': fields.many2one('res.users', 'Salesperson', help='The internal user that is in charge of communicating with this partner if any.'), - 'vat': fields.char('VAT',size=32 ,help="Value Added Tax number. Check the box if the partner is subjected to the VAT. Used by the VAT legal statement."), + 'vat': fields.char('TIN', size=32, help="Tax Identification Number. Check the box if the partner is subjected to taxes. Used by the some of the legal statements."), 'bank_ids': fields.one2many('res.partner.bank', 'partner_id', 'Banks'), - 'website': fields.char('Website',size=64, help="Website of Partner or Company"), + 'website': fields.char('Website', size=64, help="Website of Partner or Company"), 'comment': fields.text('Notes'), 'address': fields.one2many('res.partner.address', 'partner_id', 'Contacts'), # should be removed in version 7, but kept until then for backward compatibility 'category_id': fields.many2many('res.partner.category', id1='partner_id', id2='category_id', string='Tags'), @@ -175,8 +174,8 @@ class res_partner(osv.osv): 'supplier': fields.boolean('Supplier', help="Check this box if the partner is a supplier. If it's not checked, purchase people will not see it when encoding a purchase order."), 'employee': fields.boolean('Employee', help="Check this box if the partner is an Employee."), 'function': fields.char('Job Position', size=128), - 'type': fields.selection( [('default','Default'), ('invoice','Invoice'), - ('delivery','Delivery'), ('contact','Contact'), + 'type': fields.selection([('default', 'Default'), ('invoice', 'Invoice'), + ('delivery', 'Delivery'), ('contact', 'Contact'), ('other', 'Other')], 'Address Type', help="Used to select automatically the right address according to the context in sales and purchases documents."), 'street': fields.char('Street', size=128), @@ -193,28 +192,28 @@ class res_partner(osv.osv): 'birthdate': fields.char('Birthdate', size=64), 'is_company': fields.boolean('Company', help="Check if the contact is a company, otherwise it is a person"), 'use_parent_address': fields.boolean('Use Company Address', help="Select this if you want to set company's address information for this contact"), + # image: all image fields are base64 encoded and PIL-supported 'image': fields.binary("Image", - help="This field holds the image used as avatar for the "\ - "partner. The image is base64 encoded, and PIL-supported. "\ - "It is limited to a 1024x1024 px image."), + help="This field holds the image used as avatar for the partner, limited to 1024x1024px"), 'image_medium': fields.function(_get_image, fnct_inv=_set_image, string="Medium-sized image", type="binary", multi="_get_image", - store = { + store={ 'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10), }, help="Medium-sized image of the partner. It is automatically "\ - "resized as a 180x180 px image, with aspect ratio preserved. "\ + "resized as a 128x128px image, with aspect ratio preserved. "\ "Use this field in form views or some kanban views."), 'image_small': fields.function(_get_image, fnct_inv=_set_image, string="Small-sized image", type="binary", multi="_get_image", - store = { + store={ 'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10), }, help="Small-sized image of the partner. It is automatically "\ - "resized as a 50x50 px image, with aspect ratio preserved. "\ + "resized as a 64x64px image, with aspect ratio preserved. "\ "Use this field anywhere a small image is required."), 'company_id': fields.many2one('res.company', 'Company', select=1), 'color': fields.integer('Color Index'), + 'user_ids': fields.one2many('res.users', 'partner_id', 'Users'), 'contact_address': fields.function(_address_display, type='char', string='Complete Address'), } @@ -225,34 +224,32 @@ class res_partner(osv.osv): return [context['category_id']] return False - def _get_default_image(self, cr, uid, is_company, context=None): + def _get_default_image(self, cr, uid, is_company, context=None, colorize=False): if is_company: - image_path = openerp.modules.get_module_resource('base', 'static/src/img', 'company_image.png') + image = open(openerp.modules.get_module_resource('base', 'static/src/img', 'company_image.png')).read() else: - image_path = openerp.modules.get_module_resource('base', 'static/src/img', 'partner_image.png') - return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64')) + image = tools.image_colorize(open(openerp.modules.get_module_resource('base', 'static/src/img', 'avatar.png')).read()) + return tools.image_resize_image_big(image.encode('base64')) _defaults = { 'active': True, - 'lang': lambda self, cr, uid, context: context.get('lang', 'en_US'), - 'tz': lambda self, cr, uid, context: context.get('tz', False), + 'lang': lambda self, cr, uid, ctx: ctx.get('lang', 'en_US'), + 'tz': lambda self, cr, uid, ctx: ctx.get('tz', False), 'customer': True, 'category_id': _default_category, - 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner', context=c), + 'company_id': lambda self, cr, uid, ctx: self.pool.get('res.company')._company_default_get(cr, uid, 'res.partner', context=ctx), 'color': 0, 'is_company': False, 'type': 'default', 'use_parent_address': True, - 'image': lambda self, cr, uid, context: self._get_default_image(cr, uid, False, context), - 'image_small': lambda self, cr, uid, context: self._get_default_image(cr, uid, False, context), - 'image_medium': lambda self, cr, uid, context: self._get_default_image(cr, uid, False, context), + 'image': lambda self, cr, uid, ctx: self._get_default_image(cr, uid, ctx.get('default_is_company', False), ctx), } def copy(self, cr, uid, id, default=None, context=None): if default is None: default = {} name = self.read(cr, uid, [id], ['name'], context)[0]['name'] - default.update({'name': _('%s (copy)')%(name)}) + default.update({'name': _('%s (copy)') % (name)}) return super(res_partner, self).copy(cr, uid, id, default, context) def onchange_type(self, cr, uid, ids, is_company, context=None): @@ -323,9 +320,6 @@ class res_partner(osv.osv): domain_siblings = [('parent_id', '=', vals['parent_id']), ('use_parent_address', '=', True)] update_ids = [vals['parent_id']] + self.search(cr, uid, domain_siblings, context=context) self.update_address(cr, uid, update_ids, vals, context) - if 'image' not in vals : - image_value = self._get_default_image(cr, uid, vals.get('is_company', False) or context.get('default_is_company'), context) - vals.update(tools.image_get_resized_images(image_value, return_big=True)) return super(res_partner,self).create(cr, uid, vals, context=context) def update_address(self, cr, uid, ids, vals, context=None): @@ -350,37 +344,34 @@ class res_partner(osv.osv): res.append((record.id, name)) return res + def _parse_partner_name(self, text, context=None): + """ Supported syntax: + - 'Raoul <raoul@grosbedon.fr>': will find name and email address + - otherwise: default, everything is set as the name """ + match = re.search(r'([^\s,<@]+@[^>\s,]+)', text) + if match: + email = match.group(1) + name = text[:text.index(email)].replace('"','').replace('<','').strip() + else: + name, email = text, '' + return name, email + def name_create(self, cr, uid, name, context=None): """ Override of orm's name_create method for partners. The purpose is to handle some basic formats to create partners using the name_create. - Supported syntax: - - 'raoul@grosbedon.fr': create a partner with name raoul@grosbedon.fr - and sets its email to raoul@grosbedon.fr - - 'Raoul Grosbedon <raoul@grosbedon.fr>': create a partner with name - Raoul Grosbedon, and set its email to raoul@grosbedon.fr - - anything else: fall back on the default name_create - Regex : - - ([a-zA-Z0-9._%-]+@[a-zA-Z0-9_-]+\.[a-zA-Z0-9._]{1,8}): raoul@grosbedon.fr - - ([\w\s.\\-]+)[\<]([a-zA-Z0-9._%-]+@[a-zA-Z0-9_-]+\.[a-zA-Z0-9._]{1,8})[\>]: - Raoul Grosbedon, raoul@grosbedon.fr - """ - contact_regex = re.compile('([\w\s.\\-]+)[\<]([a-zA-Z0-9._%-]+@[a-zA-Z0-9_-]+\.[a-zA-Z0-9._]{1,8})[\>]') - email_regex = re.compile('([a-zA-Z0-9._%-]+@[a-zA-Z0-9_-]+\.[a-zA-Z0-9._]{1,8})') - contact_regex_res = contact_regex.findall(name) - email_regex_res = email_regex.findall(name) - if contact_regex_res: - name = contact_regex_res[0][0].rstrip(' ') # remove extra spaces on the right - email = contact_regex_res[0][1] - rec_id = self.create(cr, uid, {self._rec_name: name, 'email': email}, context); - return self.name_get(cr, uid, [rec_id], context)[0] - elif email_regex_res: - email = '%s' % (email_regex_res[0]) - rec_id = self.create(cr, uid, {self._rec_name: email, 'email': email}, context); - return self.name_get(cr, uid, [rec_id], context)[0] - else: - rec_id = super(res_partner, self).create(cr, uid, {self._rec_name: name}, context) - return self.name_get(cr, uid, [rec_id], context)[0] + If only an email address is received and that the regex cannot find + a name, the name will have the email value. + If 'force_email' key in context: must find the email address. """ + if context is None: + context = {} + name, email = self._parse_partner_name(name, context=context) + if context.get('force_email') and not email: + raise osv.except_osv(_('Warning'), _("Couldn't create contact without email address !")) + if not name and email: + name = email + rec_id = self.create(cr, uid, {self._rec_name: name or email, 'email': email or False}, context=context) + return self.name_get(cr, uid, [rec_id], context)[0] def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: @@ -404,6 +395,21 @@ class res_partner(osv.osv): return self.name_get(cr, uid, ids, context) return super(res_partner,self).name_search(cr, uid, name, args, operator=operator, context=context, limit=limit) + def find_or_create(self, cr, uid, email, context=None): + """ Find a partner with the given ``email`` or use :py:method:`~.name_create` + to create one + + :param str email: email-like string, which should contain at least one email, + e.g. ``"Raoul Grosbedon <r.g@grosbedon.fr>"``""" + assert email, 'an email is required for find_or_create to work' + emails = tools.email_split(email) + if emails: + email = emails[0] + ids = self.search(cr, uid, [('email','ilike',email)], context=context) + if not ids: + return self.name_create(cr, uid, email, context=context)[0] + return ids[0] + def _email_send(self, cr, uid, ids, email_from, subject, body, on_error=None): partners = self.browse(cr, uid, ids) for partner in partners: @@ -492,7 +498,7 @@ class res_partner(osv.osv): # get the information that will be injected into the display format # get the address format address_format = address.country_id and address.country_id.address_format or \ - '%(company_name)s\n%(street)s\n%(street2)s\n%(city)s,%(state_code)s %(zip)s' + "%(street)s\n%(street2)s\n%(city)s %(state_code)s %(zip)s\n%(country_name)s" args = { 'state_code': address.state_id and address.state_id.code or '', 'state_name': address.state_id and address.state_id.name or '', @@ -505,10 +511,10 @@ class res_partner(osv.osv): args[field] = getattr(address, field) or '' if without_company: args['company_name'] = '' + elif address.parent_id: + address_format = '%(company_name)s\n' + address_format return address_format % args - - # res.partner.address is deprecated; it is still there for backward compability only and will be removed in next version class res_partner_address(osv.osv): _table = "res_partner" diff --git a/openerp/addons/base/res/res_partner_demo.xml b/openerp/addons/base/res/res_partner_demo.xml index 1e635820f4c..eed67483358 100644 --- a/openerp/addons/base/res/res_partner_demo.xml +++ b/openerp/addons/base/res/res_partner_demo.xml @@ -77,7 +77,7 @@ <field name="is_company">1</field> <field name="city">Taipei</field> <field name="zip">106</field> - <field model="res.country" name="country_id" search="[('name','=','Taiwan')]"/> + <field name="country_id" ref="base.tw"/> <field name="street">31 Hong Kong street</field> <field name="email">info@asustek.com</field> <field name="phone">(+886) (02) 4162 2023</field> @@ -90,7 +90,7 @@ <field name="is_company">1</field> <field name="city">Wavre</field> <field name="zip">1300</field> - <field model="res.country" name="country_id" search="[('name','=','Belgium')]"/> + <field name="country_id" ref="base.be"/> <field name="street">69 rue de Chimay</field> <field name="email">info@agrolait.com</field> <field name="phone">+32 10 588 558</field> @@ -105,6 +105,7 @@ <field name="city">Shanghai</field> <field name="zip">200000</field> <field model="res.country" name="country_id" search="[('name','=','China')]"/> + <field name="country_id" ref="base.cn"/> <field name="street">52 Chop Suey street</field> <field name="email">info@chinaexport.com</field> <field name="phone">+86 21 6484 5671</field> @@ -120,7 +121,7 @@ <field name="is_company">1</field> <field name="city">Fremont</field> <field name="zip">CA 94538</field> - <field model="res.country" name="country_id" search="[('code','ilike','us')]"/> + <field name="country_id" ref="base.us"/> <field model="res.country.state" name="state_id" search="[('code','ilike','ca')]"/> <field name="street">3661 Station Street</field> <field name="email">info@deltapc.com</field> @@ -134,7 +135,7 @@ <field eval="[(6, 0, [ref('res_partner_category_2')])]" name="category_id"/> <field name="is_company">1</field> <field eval="0" name="customer"/> - <field model="res.country" name="country_id" search="[('code','=','us')]"/> + <field name="country_id" ref="base.us"/> <field model="res.country.state" name="state_id" search="[('code','ilike','il')]"/> <field name="zip">60610</field> <field name="city">Chicago</field> @@ -152,7 +153,7 @@ <field name="is_company">1</field> <field name="city">Chicago</field> <field name="zip">IL 60623</field> - <field model="res.country" name="country_id" search="[('code','ilike','us')]"/> + <field name="country_id" ref="base.us"/> <field model="res.country.state" name="state_id" search="[('code','ilike','il')]"/> <field name="street">23 Rockwell Lane</field> <field name="email">info@elecimport.com</field> @@ -169,7 +170,7 @@ <field name="street">81 Academy Avenue</field> <field name="city">Birmingham</field> <field name="zip">B46 3AG</field> - <field model="res.country" name="country_id" search="[('code','ilike','gb')]"/> + <field name="country_id" ref="base.uk"/> <field name="phone">+44 121 690 4596</field> <field name="email">email@wealthyandsons.com</field> <field name="website">www.wealthyandsons.com/</field> @@ -185,7 +186,7 @@ <field name="city">Munich</field> <field name="street">Luckenwalder Strasse</field> <field name="zip">80352</field> - <field model="res.country" name="country_id" search="[('name','=','Germany')]"/> + <field name="country_id" ref="base.de"/> <field name="phone">+49 8932 450203 </field> <field name="image">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</field> </record> @@ -197,7 +198,7 @@ <field name="is_company">1</field> <field name="street">203, Systems Plaza</field> <field name="city">Mumbai</field> - <field model="res.country" name="country_id" search="[('name','=','India')]"/> + <field name="country_id" ref="base.in"/> <field name="email">info@bestdesigners.in</field> <field name="phone">+91 22 3445 0349</field> <field name="website">www.bestdesigners.com</field> @@ -210,7 +211,7 @@ <field name="is_company">1</field> <field name="city">Miami</field> <field name="zip">FL 33169</field> - <field model="res.country" name="country_id" search="[('code','=','US')]"/> + <field name="country_id" ref="base.us"/> <field model="res.country.state" name="state_id" search="[('code','=','FL')]"/> <field name="email">contact@jackson.com</field> <field name="phone">+1 786 525 0724</field> @@ -226,6 +227,7 @@ <field name="is_company">1</field> <field name="street">Constitución, 80</field> <field model="res.country" name="country_id" search="[('code','ilike','es')]"/> + <field name="country_id" ref="base.es"/> <field name="city">Barcelona</field> <field name="zip">08078</field> <field name="phone">+34 934 340 230</field> @@ -242,7 +244,7 @@ <field name="city">Le Bourget du Lac</field> <field name="zip">73377</field> <field name="phone">+33 4 49 23 44 54</field> - <field model="res.country" name="country_id" search="[('name','=','France')]"/> + <field name="country_id" ref="base.fr"/> <field name="street">93, Press Avenue</field> <field name="email">info@c2c.com</field> <field name="website">www.camptocamp.com</field> @@ -256,7 +258,7 @@ <field name="is_company">1</field> <field name="city">Champs sur Marne</field> <field name="zip">77420</field> - <field model="res.country" name="country_id" search="[('name','=','France')]"/> + <field name="country_id" ref="base.fr"/> <field name="email">info@axelor.com</field> <field name="phone">+33 1 64 61 04 01</field> <field name="street">12 rue Albert Einstein</field> @@ -273,7 +275,7 @@ <field name="is_company">1</field> <field name="city">Detroit</field> <field name="zip">MI 48212</field> - <field model="res.country" name="country_id" search="[('code','ilike','us')]"/> + <field name="country_id" ref="base.us"/> <field model="res.country.state" name="state_id" search="[('code','ilike','mi')]"/> <field name="street">60, Rosewood Court</field> <field name="email">info@chamberworks.com</field> @@ -289,7 +291,7 @@ <field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/> <field name="is_company">1</field> <field name="street">89 Lingfield Tower</field> - <field model="res.country" name="country_id" search="[('code','ilike','gb')]"/> + <field name="country_id" ref="base.uk"/> <field name="city">London</field> <field name="phone">+44 20 1294 2193</field> <field name="image">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HDEKDY7SWXhz0F+zagmEcrZHvc9xc717LKpabuu1ZYyd1kBqvfL7hfuS1wLR029CpeiUuy9hS2hswHb8mc+qy/Vrh8zGRHDkoaNHur4TI14XRy2p3jwXHpysDgQPgTsd/ot3pGhbxmFZSuFhex7tuR242J3/AIkrbouqz0Kzs6za1AQQ3b6RM/MqGtf1q9MsqGZM9YhERFcLiRY2PoU8fXZXpVoq8LGhjGRtADWjyA+H+pWSiIqcz3CjO38zxHuQ5PHth1XVhhrMdz7xOYGjd55fg7y381o9UfZ8NqtpC7grOPp5fFQ04cqHczYLngtaDKNmk8+4PmOoI32263+i53WtN3Ef6ZV1S1++pEbHRHpxhobnzwB1yufM9wX19e1Hq6OhqTDY/AarvtsXyBI+0ImPkc1gHKG9efr7w32A32333OouDWcoZ7T+b4c6ogw1nD41mMbHbrCRrog57nP32O5cXkkFvmSQQrqRY+lp/wC+Vk9oL0xkQBEbRBwG5HPAA9lQp4O6yrcJstouDK6fuWMxm33rVizA/ZkThGOZmw92QGPfy297YEbbrd6h4RZCfTPD/BY3LQSR6Xux2LE1ouDpg0gkMAB2677AnoNhuVb6LP0tP9lq7XrwkGRxLuA4kR/xU7xN4M/p1xAvZzI2ajaEuENGs3dxmhshxcyXbbbYE+W/Ub+q+8Lw41kNXaD1Bm8zi559NVJqlp8XOXWGOY9jSOZvnyuAJPfcq30Wfp2bt3+81oNauxSFKRtAIGOAILT8g56Ln/h5wa1rpTM15xPomaD709smtvoOlvRsJHMyKVzPd6DoOnVxPdSfhdwzzmF4m6g19qO/jBcyXPDHTxcbmQchLf6Rwd15jyA7depJJJKtlFhltTbEclvca7d1w/dHiEEgCYmUREXQqZERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERf/2Q==</field> @@ -304,7 +306,7 @@ <field name="zip">01060-324</field> <field name="street">Rua Dom Carlos, 1073</field> <field name="phone">+55 11 2402 2045</field> - <field model="res.country" name="country_id" search="[('code','ilike','br')]"/> + <field name="country_id" ref="base.br"/> <field name="is_company">1</field> <field name="image">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</field> </record> @@ -319,7 +321,7 @@ <field name="street">34 Westwood Avenue</field> <field name="street2">Capital Federal</field> <field name="phone">+54 341 324 9459 </field> - <field model="res.country" name="country_id" search="[('name','=','Argentina')]"/> + <field name="country_id" ref="base.ar"/> <field eval="[(6, 0, [ref('res_partner_category_4')])]" name="category_id"/> <field name="image">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</field> </record> @@ -332,7 +334,7 @@ <field name="zip">MA 02203</field> <field name="email">info@thinkbig.com</field> <field name="phone">+1 857 349 3049</field> - <field model="res.country" name="country_id" search="[('name','=','United States')]"/> + <field name="country_id" ref="base.us"/> <field name="street">One Lincoln Street</field> <field name="website">www.think-big.com</field> <field name="image">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</field> @@ -346,7 +348,7 @@ <field name="is_company">1</field> <field name="city">Cupertino</field> <field name="zip">CA 95014</field> - <field model="res.country" name="country_id" search="[('name','=','United States')]"/> + <field name="country_id" ref="base.us"/> <field model="res.country.state" name="state_id" search="[('code','ilike','ca')]"/> <field name="street">10200 S. De Anza Blvd</field> <field name="email">info@seagate.com</field> @@ -374,7 +376,7 @@ <field name="type">default</field> <field name="street">Union Road</field> <field name="city">Liverpool</field> - <field model="res.country" name="country_id" search="[('code','ilike','gb')]"/> + <field name="country_id" ref="base.uk"/> <field name="zip">L25 4RL</field> <field name="image">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</field> </record> @@ -390,7 +392,7 @@ <field name="city">Leicester</field> <field name="zip">LE4 2BN</field> <field name="phone">+44 20 1294 2193</field> - <field model="res.country" name="country_id" search="[('code','ilike','gb')]"/> + <field name="country_id" ref="base.uk"/> <field name="website">www.vicking-direct.com</field> <field name="image">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</field> </record> diff --git a/openerp/addons/base/res/res_partner_demo.yml b/openerp/addons/base/res/res_partner_demo.yml index 18d7025878b..ebbaacb319c 100644 --- a/openerp/addons/base/res/res_partner_demo.yml +++ b/openerp/addons/base/res/res_partner_demo.yml @@ -5,6 +5,7 @@ use_parent_address: True function: Service Manager email: tang@asustek.com + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_2}: name: Joseph Walters @@ -12,6 +13,7 @@ use_parent_address: True function: Store Manager email: joseph.walters@asustek.com + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_3}: name: Thomas Passot @@ -26,6 +28,7 @@ use_parent_address: True function: Analyst email: m.fletcher@agrolait.com + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_5}: name: Chao Wang @@ -33,6 +36,7 @@ use_parent_address: True function: Marketing Manager email: chao_wang@chinaexport.com + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_6}: name: Zhi Ch'ang @@ -46,7 +50,7 @@ parent_id: base.res_partner_4 use_parent_address: True function: Production Supervisor - email: + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_8}: name: Paul Williams @@ -68,6 +72,7 @@ use_parent_address: True function: Senior Consultant email: david.s@tech.info + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_11}: name: John M. Brown @@ -75,13 +80,13 @@ use_parent_address: True function: Director email: john.b@tech.info + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_12}: name: James Miller parent_id: base.res_partner_6 use_parent_address: True function: Electrical Supervisor - email: - !record {model: 'res.partner', id: base.res_partner_address_13}: name: Charlie Bernard @@ -89,6 +94,7 @@ use_parent_address: True function: Senior Associate email: charlie.bernard@wealthyandsons.com + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_14}: name: Jessica Dupont @@ -96,20 +102,21 @@ use_parent_address: True function: Analyst email: jessica.dupont@wealthyandsons.com + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_15}: name: Phillipp Miller parent_id: base.res_partner_8 use_parent_address: True function: Creative Director - email: + image: /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCABOAHgDASIAAhEBAxEB/8QAHQAAAgICAwEAAAAAAAAAAAAABgcEBQAIAQIDCf/EADsQAAEDAwMCBAQEAwYHAAAAAAECAwQABREGEiEHMQgTQVEUImG1MkJxdiNygRUoM1KRoRgkJTiio7H/xAAcAQABBQEBAQAAAAAAAAAAAAAAAQIEBQYDBwj/xAAwEQABBAECAwYDCQAAAAAAAAABAAIDEQQFIRIxQQYTFFFhcYGRsQcVMlKhwdHw8f/aAAwDAQACEQMRAD8A0O8VLePFJ1iV76/1D9xfpcMoSvhXf0poeKhG7xQ9YP37qD7i/S4js9sd80JwK7Ij1KYZ+YVJZjKVUtMHGDQlXk1FSedvevRUXGCPWpCGNv5q9EMocdQ2pezdkgnvj1xSEhospQC40FCMfmuRH5qY/LebW41AtqHGm0glSm/MWse+78or3tUu5R3G3zHYkxXMBbSkpUFJPqD6GuByAOi7jHcearvhx/lrhUdQ5CaJ77Z2YKmJMRQMeUne0kgpKc8447/rVQpn1A/8a6seJBxBcnxuYeEqsXH3jO3tUZ+KoDITV0Y/H+HXg9HVinpioXGcpxUF9rHG2r2TH45TVa8wlPehCqXG6ypLyayhMTV8UaN3ig6v/v3UH3B+l7GZ5H60x/FAn+8/1f8A37qD7g/QNEa3FP6UJwVhEYShAURkkcVKMZ1aUlIxmvWBHCgEL7DmrpmEFkbP6UJRuqVEZ31ByOKhQ30LvTiZQBRkMBP09f8AejE29QQtQTykE/7UGaegMzr+3GW+htK1krWezYKsfN7DPrUbIcA3dSsZhc8UthulVl0o5cIzFzMZQlthuQ0VAlG4cjHfJGDzxnbV31V6OvdJ4KdVf2XDnackueTDukZaSEqIylDgHY5qTN6FL0b0id1nOu0KJcoKviLc5AYZLhc8xBbX8RjzSPQpJKfpW18LQDnWTSWldXKmNWq+JtMZYntxYyy1vwtS0IdbUnkgglIT3z+WsuJOCTjYSbW2GMZMcse0AijfuvnJeLoxc7Q2kpVtQ6VtILaQdijklJ/N9R6UPPwVJVuCNueK2h8Y/h+f0fqW2aps0hw2+dF33xMRkBtp5tSU/EeWnhAXlIWRwCkkd6RUy0JVuca5Secjsf0rQYEwlYa/xZTUsd0DwHfPzQd8ItpeFD5Vc12kQR5e9vke1XqoacbA3zUcsFolC08E1YAKsQpNi4TnbVHLa2rNGtwiqRkfkUM0MzWNiik9s0qah19v1rKlSkgKIFZQkpM3xPf9z/V/9+3/AO4P0G20ZwPejDxOq/vQdX/37qD7g/QfbnFfLQgIkiMElKQrA9aIoERS3UpSMpRwD9apraSQkntRbaACtITnk0J45K1jWBD8dTL2f4qChSR659f6UrF2VGmdXG2N7tgJZaU5+F0YKxj65zT2traEpHmnkjAT70tuqvTq+S5i9T6cAdLCA84xnC0lJ/Egfm47+1cZmcbaUiCTunWmui/M6q0U3oq6XqXDgJdbQiQ0FKUyOFJwlIUo8j0FbmdBndK6R07C0/btWzrwtUSPGAmOyAtDbaSNyGnUJxuzj5f8qc1p14ZemXUvVz7N9i2K4RbJICVm4SyWozmeCEE/M4f5Bx71vfIsMyw6HkXCxWq8X1URtTq4cd1v4h9QAOxvz3Egkk5B3DA9DWRma5jyxgtbzGmY6MPkNHl8EsfFX1RsuntMTenTCy9fdRMBZSloYYg7k7ipf4SVlKkJQOSkKNaaJtwWws7WzsA3YPp6d6Y3iItHVST1H0fe9b6dh6bXeIMhliCxKE2WpuOtLikynSkNhZS8DsaBSlKcFR70PxNPiAkiOylIVySB+L6k+prQaawtj4W169VltXcXzW8Gum1bIDmWtLWSUZ57+1U1xioQfMHA7E0yLtbQEk4AV7j0oTuccltTbozjgH3q0VKUFXFpCWstL3e4oTuKUqUpKhgjkUdT2UttqbSjBA70HXNKQSVd6ExDElPP9Kyu8v1rKEI58UTuzxRdX/39qD7i/QfbH05Tn1NE3iodx4pOsI9tfah+4v0CW2Tgg+xoSApiWmQnIT9aMbO+lDgCVJ3HtS4tcxsEE+vNF1rvduiPo+MdDIUAvzPL3lKRwcJ9cn1PApkkjYml7uQUnExpMuVsEQtxTUtLqEx1SZT6WkNjKlKV8uKBOpvWK1w7dI0/ptr4qTIaUy7IUjCEIVkHaO5z7qwPUZqtvs96a24h6DdVscKjrQ+UIWjH5diRlf0SSMdqXaY0p+4oVEtwZDjvkSElC1JSTjBUDzz6E1Wt1DvgeAUFqJOz/gK75wLvTcD+fovpN4DdfOv6Km6X1XLD8HT6I7FtU8glaGfKIU0D2ITtykDnKlU3bFqqxaxMm6aC6qyZS3FLWtn4dDLqUZ4/hLRhxCR8ueScdxSK8N8J/pTpGdM1YhiJEu0M3Jt9TgASUhWAoH1xgD+ahPwzdT7TY7Zdrb1LZSLrp95N1t7z6QXJsdTuNox+N5C1AcfkcAP4Kz0srGuqx1PqrzTtPny4jKxpNUOVizyHunJ19tUCFonT7F0bgybsLsqVHeYjqZwpLaw8tKStRRlLiEkBW3ngYpKyYRlZYbahoUP4hW48hkqI4wCo7ePYc1Z6z17rrqtfU6lt+kpEyMN8aLHiPoT8KEqCthPJKyOVKA74FVMY3WAl+RqrRslpCsJbQ+48ztx3IWEgc+xBrOZOdOzI8RjuLWigD/bXsmidncI6T926kxsj3EuLSBsTVUdtwANw4b7Dkhy86dloZW/HWxMDeU/8vIQ4dw7jaDk4+gNLu9oCQopKgQSlQUCDn6g8imu5c7I7DuMxWlnWo7bqvKdTOdGSEDjcUlK/6JBFVOr7RH1HpReoGnYsJ5ljz2WpVwDkhxSeS2hITvIUDhO8bcg4NaXTe075Hthymjc1Y2+YoD6ey887SfZdFBC/L0t5HCCeB1G63IaQSb22BBvz6pFXJYTuSrjvzQddXEZPIq9u05GDhWR+mKD7lL3KPzVtF4kqya53rKhTHuKyhNtHHitO3xS9Y/3/AKh+4v0uIknGBu7UwvFgR/xTdY/3/qH7i/SvbXgihIi+BcdhHzetFNlu9xbmJXAeDHy4W/hA2A+61fhFLZiQsYwavLdOe3Jb4WkfMUq7EevHv9aj5TOOEhWekT9xmMeUcXvc5HXMm3xmQhlO5sMy0POJ5wUAbux+Y8cVF0dCaZ1RAeiS3ZHmyGworZ2jO4bCfm/mquRd4MlDTUO2/O6VDzJLhcI/oMJ/1BNG3SW2M3LUluhvR22y1LSVuIUSSC4MJAPAAIyKpA3u2ELcZsomBePIV8dvoSvoR4gLNapXRNmc86I3wkmAlx1qL5pKEnaNqdye5Kcncce1awQV2C+NRIN7irt4tCn2WJcJnzH5u9YJLq1OpwEf4adnJSDmtk+ql5VK8P2ohJjNviNCafShwqSkqadSocoII7e9aoP3i2SbUh9vR9g84xi5mQw8/ngKPK3TjnPIGfrWb1CNveNeTViuS9B7FTudgyMDSS15dzAH4RsedjrVc6RnDtukEsj+zdTssNgkhEi2vNc/q35lWlsfnwW/Os3UG2oUsqSQme9Gzj0w6hIpfac1Hpybai+rSa2Gnm/NAiXFxBRkZwEupdB/1FY7f9Fpt8ZajqKMouFB2qjvDnnttRVScYOeQ2ufS/3W9Go1C1z7qrohpH6AIqauurGTcUt67gCRJwl3/rieCtSsbgeD8iRjbXSXM02rIvWp7hcpLiQHDGjbgCAEYLr6gVjAH4U49jS4j3HT0gzp0SfdVPLX/DafiN7FhJ2DcpLgKeM8AHvVoNWQ2woJ0dZiofIStUlRP/tH/wAqRJjcJAPvvZ3UCHUWuHFH6jYAbdOaQl8nBmQ80CQG1qQN2M8HHOKF5crcMVaa6kY1RdktMtspVKcUEN52oCznAyScDOOSTQtIfJJB75r1GJ/GxrvMBfJ2XF4ad8P5XEfI0uJL+44rKiLVWV0UZf/Z - !record {model: 'res.partner', id: base.res_partner_address_16}: name: Ayaan Agarwal parent_id: base.res_partner_9 use_parent_address: True function: Director - email: + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_17}: name: Daniel Jackson @@ -117,6 +124,7 @@ use_parent_address: True function: Managing Partner email: daniel@jackson.com + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_18}: name: William Thomas @@ -124,6 +132,7 @@ use_parent_address: True function: Senior Consultant email: william@jackson.com + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_19}: name: Sergio Pérez @@ -144,14 +153,12 @@ parent_id: base.res_partner_12 use_parent_address: True function: Director - email: - !record {model: 'res.partner', id: base.res_partner_address_22}: name: Laith Jubair parent_id: base.res_partner_13 use_parent_address: True function: Director - email: - !record {model: 'res.partner', id: base.res_partner_address_23}: name: Angel Cook @@ -166,13 +173,14 @@ use_parent_address: True function: System Analyst email: robert.anderson@chamberworks.com + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_25}: name: Jacob Taylor parent_id: base.res_partner_15 use_parent_address: True function: Order Clerk - email: + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_26}: name: Arthur Gomez @@ -186,14 +194,15 @@ parent_id: base.res_partner_16 use_parent_address: True function: Technical Director - email: + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_28}: name: Benjamin Flores parent_id: base.res_partner_17 use_parent_address: True function: Business Executive - email: ben@nebula.ar + email: ben@nebula.ar + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_29}: name: George Wilson @@ -208,6 +217,7 @@ use_parent_address: True function: Functional Consultant email: jones@thinkbig.com + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_31}: name: Edward Foster @@ -221,21 +231,21 @@ parent_id: base.res_partner_21 use_parent_address: True function: Sales Manager - email: + image: /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCACCAFcDASIAAhEBAxEB/8QAHQAAAAcBAQEAAAAAAAAAAAAAAAQFBgcICQMCAf/EAEIQAAEDAgUBBgMFBAYLAAAAAAECAwQFEQAGBxIhMQgTIkFRYRQycRUjQoGRFiRioTNScpKisQkYJUSCsrPBwtHh/8QAGgEAAgMBAQAAAAAAAAAAAAAAAwQAAQUCBv/EACsRAAICAgEDAgUEAwAAAAAAAAECAAMEESESEzEFQRQiUXGBMmGR8KHB0f/aAAwDAQACEQMRAD8A46iZi1xn6yajM0nXnPdNjQM11ZEOHHzLMbYZZRLdCGkthwJSgJASABYAADCZ/rGatR1IpMrU7OIfaUEOL+3JNyRwed+PWrK4cXWzUZw1L4dxeZqqCN1t3725xiNf2OqlSmOTo4WtBO4KPUnHlnymZyCSIIts6k4nXjPbUVKnNVc3F1wC3+3JVgf7+ODus2qbbXxI1YzaQry+3ZVrf38RSnLWZqk2adTKPIlSUC1mgLDz3EnhIHmSRhBq9Pm0uQin1jVTLLT5UkLYhuvy0sgjkLcbbKQQeCLkD1OCL1upIJh66bH5Ubk+U/W7UtxlQOp+b1rPAP23JP8A54MRNW9X23Q67qbm1SL3AVWZJB/x4hyhfH0imtVZuowqpBcUpIkxnSpsKSbEFRAtz5EDDnjV5idHKkEJUnyUeb4Rve0fLs/zChDW2mGjLm6I9pKoVtyLl3NUq622LfGrfWpxduPGFHk+p64mvN9Xj1ehLFHzI9GcsFIdiyihQ9jtN8ZcKrCPiUpMh1hbd9qkLKSPpbD/AMn6i5gjNpjx8zyVDdyHV7iR9ThC7OysdGVTsH6nx9jHKu1YR1jUufCmZvp1OU+/m2fJWBuBXLWq4H1OIyzjq7nNt5TcXMdSYKTx3UtxI/kcIlF1Cr9UpSYDElUl1fhDbaLqPvcYTZ1LnT3FRX4brcpR5S4ghQwri+oXXqAxP8x+zERV+WOSh9oPUiEyY6ai5MH9aRucV/ePOBj1lzKooMTvZUZK1OdT0I9MDDw778qW19zC10oFHVrf4lS+0RkVEbWnOtdlz1kPZpqbyWUmybGU4ef1wj5czrMRIagsxf3Y2Tu3DhI6m/Xpf9MeNccwSpuv+orVSUVtRc11ZhgeSQmY6Bx9BgpRJE+JR669EW3HWilyRGeLdyhwoABHpwVcjocaq9t7uk8nc8sidw8n3nZFUzhrVLGUcjKFPprygJElawhCkJPjUFWvydvJ8iQmwxY7S7sNaZ0KlxJ+aEitVFAC3CkqQ2k+g8z+eIZ7J2Y6ZHguUthCFBpXfqJHiQALXPqcWMka0Znp8yPTMqUqG8kbH3mXD3s11lSvmCAoJaSRyCokkeQway3VrVn9InrcfFAx1ZPJ+sduYtBcgRaQ9Iy5Q6ZSpS2i0pDTobRNRblpYVxyeigLgjFN6/SDlquyIcdLhZbWbJcTZY/hUD8pHQ288W4zHkuuaj12m5ty/VGY+2MWZgkMd47Gd/hC/CCAQb2uenliNu2Bp8zl+h0jPtHeLstK26ZVSEAB0qSS04Up4vuStJPukemFctOurqXwIpmUcAnlhKy1OoPGSFpjFYFrqGHhl2oQG6aXVeBy3S9sRq3mksvBmQySFm17dD7+uF8Od7ELrK02WN1k8YyHrW6v9pmsO2eRLXdiSsQ65qbUaVNs6UQS5HBN7EKuT+mLf5+yTT5bKcww4Tfx0FNyUp5W15g+pHljLTRzVyXo5n6Bnamt978MVMy4u6wkR1fOi/kq3KT+WNTtLdV8nav5RjZpypOS7HeTZ1hagHGHLcoWnyPlhv0b4NUsxrNBidgn7D3/ANSzbYOl18D/ALIsqRVLAW3G3sgAbwOuBhRzFU4tDqtQo8aOVNB/vGLjw7TyR+XTAw/j+p9tOhl3qaD4JuPWp8zPDtBZakStZ9QKhTZLe9Ga6stbauL/AL27fCNRc5Up2kP0upo2PhlcdxJPi2EEKCfXi9vyw59ZaA5K1p1Eeg1Nxla811jc3uJG4zHfLEVVnKK49RR49zr3iLg4Cj5E++Agdlz99zzaFQf3j80hy5WdMMwRqjIfp0ui1UFhK21LLrPAKCq6Ui9rA23C9uTc4vBkisZImIbqsWhxEzH9oed2JKyQOLqtc28sUApOrFd01pKqBXKG3mGjhJEdtb5bXH8jtWE32D0v7dMTDpRq/T3KYxOD5YjyU32qWCppzzSfoeMdWWOCbeJ7fDuxcutaqyd68H2Pv+JP9eNKy5nh6q1LM1QcgzClyHRKeT3j8gOJc32SQu4KdoN+72kgg4PanOQs5aZ1lVVpj8NtcRx8NSSkOILQ7xKuDYcpGGhTc+afVaWiXV58REpCQlbgO1a0jy3Dmx5498c9T86RM1adV2lZOYdjRIcYLefA4LQWkLQk9b23c+Yxx1i2sr9Y3koFTkEkefpqUjz9MpcOWl6lhPhHBHTDPGosyMpKAQU9ODiTJ2mUvNQXCocd12W5uCdqvCT7+gHr1wbY7CmrdVqkOFSmEyJD60qdSUlLaEnkkK88ZdeRhY7DHtYBj4HufxPN5CNd86jzI3ZqNYzEUmnU+Q8FqCFrbQVJRz1JA4xo92BMgtZYolQMt5apMl5K/l4tbyOHz2XezPA0qyYvLeY6XHcm94r4hS0BaXgrkdRzbE00/KuXcmLckwGm4bKjuWEnakfkMLjHOaUtKarVt88Hj3IkVaqAUB25EJ5+ydT5bLc+O0kPtrtyeCCOcDAzPnKmzoyYdMeDrhVuOxNwLYGN57cQse34/aVVZcqAEzJzWfMs5vtE6iw2rpSM6VZAP0mOjCJmWspQ4IRcQl8tlSCfL6YMa4ymk9ofUd9J291nWtlX/DNeBxE2a8xLdzCrvnPCAlKFdLcYIxLWHf1mXbjGshjF+JnAonO0mvpDiVGza+vHQYdWnOdqBlHNQpVfaDWW3x3alLb3JYeJ3d9YchNjZXlax64jnKeUKrmaa5mCouri0SKuxlKB++cAv3LY6qV6kcJTz1wpVGoUBm4W7HjzHCdzAcupa/YW5H0xo4vpiXKz2DQYf0w1GQ+JYtlXkS87GlmRavFi5hoAaksupS6lTDgW26LX8JH/AHwbz640jTfMNEy9Tno0tyjTQlbQ+VQjq2FJ633Ae/OKW6eanZx0wmpcyvVVIiFY7+C4N8Z4ee5s9D/EOcXX0R1LyzrTFqMdqP8ABVSNFBlw1rJTscJSHULPJTclJ/Ek2ucI3+m3YjddfK/5/M9Rjer05qGq3hj7e0rL2Yu1xVNOYyUZ2yZAzXSGkl+Q0uOG56AgEkpcFys8fKoEetsaHaf9tzs652y1T8xxZ0+i9+jmJNpikvMEK2rQru9yTa3UEjzBxnP2t9JKdp/nekU/JNMep/7RQlyqm40QGy6HLKCE+W8E3A46jzwzsj5xGXXmslZnjqpy33CqFJDgUzKJ+ZHqhfoD5Y3KMTHtXvisBj5OhvieXyFaqw1b3qbb5ZzflbOtFTXco1qJVYKiUJejObrKHVCuhQseaVAEdMNLND9VrHeUtjhBO1RSCARjNXRTXKtaBaqw6m9OfVluruNwq/FuShxhagEPgdA42oAhXUpBSTY2xqey1CbSmTHUl5LiQtC0nhaSLgj2OKysaq1DW68GCrLKdgxuUDJjUBkF5Xjtz9cDDgdW898pKB9cDAasemlQiLwIYsxOyZi1rVMab7SGqsKYqwXniuFB9jPewkytN6PUnW6lXquiNDbIV3Dax8TJT1sL3CBfjcR04APXB3tOxPg+0DqZVAiyhnOskG1/9+dxGTdfqC5plLlOqKl3F1G49PyGBYuMltxdvAMLk2arVCOZKFbr32i21AisMxYEVruIsZi4Q03/AFRf+ZPJPJ5w3JDClOqfQpKXT0URzx74JR6opxF3bJXa/scdkTEuDggeeN3Y1oRDc6NyEbksSWgh5XIAPhc9x/6w6dOtSs0aW5hTW8sVmZCDo7mSI6wkSGjY7FhaVJKSQOClV+ORhmvwmpyVBwlaSbkX6H1GC5MuAe7mb34yuj9ty0eyh1WPccjzxwVBGjICQdiTzqH2oqVqnEp8fOeSJFJrNMcSlqelTbkSY2oi6HEoKlNLCtqklIIHPy4jDPVHazZFkUp5JCWACF2F0vfhP5ADn1wgNSGgO7kMtvx1i23dfg87knocO2kyGZ1ITOMjxXU09vBJC08eI+9sSmtUBVfE7tua0hm8j+8xjZNzyt506c6gulMhv7qBNcPKwRYNrJ9QBY/ljVvsXazKzvpI3lvNM0OZjyYtFKlb1eJ6KB+7Pe90DYT6oPrjI3WbLwlU/wC2ovdrXHSQVNnxDnr6++JL7K2vFcySadmxt5yUYSRS61HJ5mwd3h+riPnSo83BT0wK5SVOvIl1kFgDNiahnJhHhj+LnrgYjXLFZpeaYDNUplQRIjyW0usuAghxKhcH9DgYxPiLG5mr8OglFNcdI89Zm1k1JMfKU55mTm2rux3EoG1aFTHSkj2IIOKz1XL8/Ldfn0arRFxZcKSqO606PEhSbcW9742rreXWDmarSi4AXJz67bBwS4o4zc7e+RE5L1qXmNlKUMZopseU3tbUN7zQLb3J4v4Wyfc408evtsde8z737ig/SV3USEgBINvVR4x4XLdigOuHwKsDz0x8eeLTSG0ABSsc6gn92aQsg7+oPS+G4rFSNVNx4tc+uDRXKcSVpsUnyGGtG75aVN94Q40fTqMGkVSpwlhCirZ6lN8WDIOYbeTUYCi+xHU7HBJcYJsDc8lHofUeeD1LqsSQ2ru5BMd4gP8AHiQr+JPqMFGa629w6dxPqLYL1CCJCzUaa/8ACygAN6RcKHo4PMH+WJ4l+Yt13KrLtMckMzXFFywTtWdi0k+Y88MbTl77IzdWaAyu7CkEqsOAtO02t/avhy0fOYjLbouYY5YKnPu7q+7Uf4F9CP4T0wnRKK1R821Srx3d7UtkyE2P4isk4ttEbEg2PMuF2XtQM3S+80/o8ph2bBZMiGzIdKO+i36tnzKb2I9LemBis+WM2Zly7LjZmyu+pqqUslLSwopCu8QpChceQSf1wMZVuB1OWQkbmpV6i1ShCAdTaCtEKr1SRfpMeP8AjOKS/wCkwy1LlULT/N7LajGp8yZTZBCbhBfShxpSvYlpwfl74u/VqZNVmCpOJDZSuU8oeMdN5wxdZ9I06v6ZVzT2choLqTF4TpWLMTGyFML9vHYE+hUPPDoHMQPiY2LT3stpJBCUi9jjxVl7jGQk2PiP88KT8CTTqjJiVKOqPMiPKjPNOCxadQSlaCPZQIwlSwVyo6QPlQT/ADwaBhWW6YUtqRusl0d2v2PkcKsd9uYi6FJWCOhwUqsFx+AsbLqRZzpzcf8AzCVGjvFCXobykX5tfjEkixKp81pfgYCgeePLHBMidGPLKrelsdYtWqUQpTJaKwPxD0wssVKJLH3sf9BiSxEZ2RAmsqZqUawX1UU8E45QWZDbz9PhuqeZQwChVyS22T4gPUD08sOZMOG6NyWLA88jBKS2xSZ0aoNoDaPEw8pJ2nYs8A28tx59iPTF6k3OiUlDaIDLWxlKbrUfNV+uBj3MkqjngpI9R0wMQzoGa35mgVhecq8sVuehK6rL2IS8oBKe+VYDnpbHlFArDjYIrk/pa5eVz7dcOKuND9rqy7v6VCR+veKx2aWVIAWzYX8sJaO/Ma2NDiZl9sLIz2RdbZz7iVfDZjhtVhtxV/G4olt8X/rd4kqP9u/niDokRcqf3ivkabCfqTzjRLt56YnN+lbGd6ZFLtQya8p94IF1rgOlKXx6nYrunLegVjPenupdbLTbgC1dVDgfUYbrOxFXGjDISh5TrTPy2sT+uGZSZHdPORln5Fmx9gcOme87TYy2ae2HXynY3f8AEtXS/wBPEfphhxUTqfNabnIPeFRCyTwcdGcR7ssmSi7akqB5tfnHkQZjKiW0pAPIxwjx0Js7FeUmx5scKbUmQLJeAUnqFYocyTw1PmM/0rQI9hjnPmMzo64zqCApJBB6XwbdktJaKigH/O+ECfOSVEAC9+gxck5iY+5A+GcX9/GUGlKUfmT+FX1It+d8DCdIXLjOfaD0bv2LBLrINl2/AffrgYqdCbdVsn9rq0L8faUr/qqwZYUpTR3KJt6nAwMKnzGj4EIVNhmZTqhElsofYeiracacSFIWhQIUlQPBBBIIPW5xjPTfmQPr/wA2BgYNVA2xSaANRZuL2cUf8Ch/lxhuZ2QlM9gpSBdS72HtgYGDGBh2gKUWxdRP54Wlf0S/Y8YGBihJEx5R7p5VzfeRf88JjaEmakFIPJ8sDAxDJBUf6OT7Otgew2njAwMDFS5//9k= - !record {model: 'res.partner', id: base.res_partner_address_33}: name: Morgan Rose parent_id: base.res_partner_21 use_parent_address: True function: Financial Manager - email: + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_34}: name: Kevin Clarke parent_id: base.res_partner_21 use_parent_address: True function: Knowledge Manager - email: + image: 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 - !record {model: 'res.partner', id: base.res_partner_address_35}: name: Peter Mitchell @@ -251,6 +261,7 @@ use_parent_address: True function: Chief Executive Officer (CEO) email: mark@yourcompany.com + image: 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 - !record {model: 'res.partner', id: base.res_partner_main2}: name: Roger Scott @@ -259,3 +270,4 @@ use_parent_address: True function: Chief Operations Officer (COO) email: roger@yourcompany.com + image: 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 diff --git a/openerp/addons/base/res/res_partner_view.xml b/openerp/addons/base/res/res_partner_view.xml index 43a37d1a79c..a79610b7a18 100644 --- a/openerp/addons/base/res/res_partner_view.xml +++ b/openerp/addons/base/res/res_partner_view.xml @@ -95,7 +95,7 @@ <field name="arch" type="xml"> <form string="Partners" version="7.0"> <sheet> - <field name="image_medium" widget='image' class="oe_avatar oe_left"/> + <field name="image" widget='image' class="oe_left oe_avatar" options='{"preview_image": "image_medium", "size": [90, 90]}'/> <div class="oe_title"> <div class="oe_edit_only"> <label for="name"/> ( @@ -130,8 +130,8 @@ <field name="street2"/> <div class="address_format"> <field name="city" placeholder="City" style="width: 40%%"/> - <field name="state_id" class="oe_no_button" placeholder="State" style="width: 24%%" options='{"no_open": true}'/> - <field name="zip" placeholder="ZIP" style="width: 34%%"/> + <field name="state_id" class="oe_no_button" placeholder="State" style="width: 37%%" options='{"no_open": true}'/> + <field name="zip" placeholder="ZIP" style="width: 20%%"/> </div> <field name="country_id" placeholder="Country" class="oe_no_button" options='{"no_open": true}'/> </div> @@ -164,7 +164,7 @@ <field name="phone"/> <field name="street"/> <field name="street2"/> - <field name="image_small"/> + <field name="image"/> <field name="zip"/> <field name="city"/> <field name="country_id"/> @@ -176,23 +176,20 @@ <div t-att-class="color + (record.title.raw_value == 1 ? ' oe_kanban_color_alert' : '')" style="position: relative"> <a t-if="! read_only_mode" type="delete" style="position: absolute; right: 0; padding: 4px; diplay: inline-block">X</a> <div class="oe_module_vignette"> - <a type="edit"> - <img t-att-src="kanban_image('res.partner', 'image_small', record.id.value)" class="oe_avatar oe_kanban_avatar_smallbox"/> + <a type="open"> + <img t-att-src="kanban_image('res.partner', 'image', record.id.value, {'preview_image': 'image_small'})" class="oe_avatar oe_kanban_avatar_smallbox"/> </a> <div class="oe_module_desc"> <div class="oe_kanban_box_content oe_kanban_color_bglight oe_kanban_box_show_onclick_trigger oe_kanban_color_border"> <table class="oe_kanban_table"> <tr> <td class="oe_kanban_title1" align="left" valign="middle"> - <h4><a type="edit"><field name="name"/></a></h4> + <h4><a type="open"><field name="name"/></a></h4> <i><div t-if="record.function.raw_value"> - <field name="function"/><br/></div></i> - </td> - <td valign="top" align="right"> - <a t-if="record.email.raw_value" title="Mail" t-att-href="'mailto:'+record.email.value" style="text-decoration: none;" > - <img src="/web/static/src/img/icons/terp-mail-message-new.png" border="0" width="16" height="16"/> - </a> - + <field name="function"/></div></i> + <div><a t-if="record.email.raw_value" title="Mail" t-att-href="'mailto:'+record.email.value"> + <field name="email"/> + </a></div> </td> </tr> </table> @@ -204,7 +201,7 @@ </templates> </kanban> <form string="Contact" version="7.0"> - <field name="image_small" widget='image' class="oe_avatar oe_left"/> + <field name="image" widget='image' class="oe_avatar oe_left" options='{"preview_image": "image_medium"}'/> <div class="oe_title"> <group> <field name="name"/> @@ -293,7 +290,6 @@ <field name="phone"/> <field name="street"/> <field name="street2"/> - <field name="image_small"/> <field name="zip"/> <field name="city"/> <field name="country_id"/> @@ -302,12 +298,12 @@ <field name="category_id"/> <templates> <t t-name="kanban-box"> - <div class="oe_kanban_vignette"> - <a type="edit"> + <div class="oe_kanban_vignette oe_semantic_html_override"> + <a type="open"> <img t-att-src="kanban_image('res.partner', 'image_small', record.id.value)" class="oe_kanban_image"/> </a> <div class="oe_kanban_details"> - <h4 class="oe_partner_heading"><a type="edit"><field name="name"/></a></h4> + <h4 class="oe_partner_heading"><a type="open"><field name="name"/></a></h4> <div class="oe_kanban_partner_categories"/> <div class="oe_kanban_partner_links"/> <ul> diff --git a/openerp/addons/base/res/res_security.xml b/openerp/addons/base/res/res_security.xml index f02abd90985..c7d2a77f846 100644 --- a/openerp/addons/base/res/res_security.xml +++ b/openerp/addons/base/res/res_security.xml @@ -1,42 +1,37 @@ <?xml version="1.0" encoding="utf-8"?> <openerp> -<data noupdate="0"> + <data noupdate="1"> - <record model="res.groups" id="group_partner_manager"> - <field name="name">Partner Manager</field> - </record> + <record model="res.groups" id="group_partner_manager"> + <field name="name">Partner Manager</field> + </record> - <record model="ir.ui.menu" id="menu_config_address_book"> - <field eval="[(6,0,[ref('group_system'), ref('group_partner_manager')])]" name="groups_id"/> - </record> - <record model="ir.ui.menu" id="menu_base_config"> - <field eval="[(6,0,[ref('group_system'), ref('group_partner_manager')])]" name="groups_id"/> - </record> - <record model="ir.ui.menu" id="menu_base_partner"> - <field eval="[(6,0,[ref('group_partner_manager')])]" name="groups_id"/> - </record> + <record model="ir.ui.menu" id="menu_config_address_book"> + <field eval="[(6,0,[ref('group_system'), ref('group_partner_manager')])]" name="groups_id"/> + </record> + <record model="ir.ui.menu" id="menu_base_config"> + <field eval="[(6,0,[ref('group_system'), ref('group_partner_manager')])]" name="groups_id"/> + </record> + <record model="ir.ui.menu" id="menu_base_partner"> + <field eval="[(6,0,[ref('group_partner_manager')])]" name="groups_id"/> + </record> -</data> + <!-- Record Rule For Company --> + <record id="res_company_rule" model="ir.rule"> + <field name="name">company rule</field> + <field model="ir.model" name="model_id" ref="model_res_company"/> + <field eval="True" name="global"/> + <!-- TODO: review this <field name="domain_force">['|', ('child_ids', 'child_of', [user.company_id.id]), ('parent_id', 'child_of', [user.company_id.id])]</field> --> + <field name="domain_force">[('id','child_of',[user.company_id.id])]</field> + </record> -<data noupdate="1"> + <!-- Record Rule For User --> + <record id="res_users_rule" model="ir.rule"> + <field name="name">user rule</field> + <field model="ir.model" name="model_id" ref="model_res_users"/> + <field eval="True" name="global"/> + <field name="domain_force">[('company_ids','child_of',[user.company_id.id])]</field> + </record> - <!-- Record Rule For Company --> - - <record id="res_company_rule" model="ir.rule"> - <field name="name">company rule</field> - <field model="ir.model" name="model_id" ref="model_res_company"/> - <field eval="True" name="global"/> - <!-- TODO: review this <field name="domain_force">['|', ('child_ids', 'child_of', [user.company_id.id]), ('parent_id', 'child_of', [user.company_id.id])]</field> --> - <field name="domain_force">[('id','child_of',[user.company_id.id])]</field> - </record> - - <!-- Record Rule For User --> - <record id="res_users_rule" model="ir.rule"> - <field name="name">user rule</field> - <field model="ir.model" name="model_id" ref="model_res_users"/> - <field eval="True" name="global"/> - <field name="domain_force">[('company_ids','child_of',[user.company_id.id])]</field> - </record> - -</data> + </data> </openerp> diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index cddc02673b8..5e1ea88f5ac 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -26,6 +26,7 @@ import logging from lxml import etree from lxml.builder import E import netsvc +from openerp import SUPERUSER_ID import openerp import openerp.exceptions from osv import fields,osv @@ -188,7 +189,7 @@ class res_users(osv.osv): result = super(res_users, self).read(cr, uid, ids, fields, context, load) canwrite = self.pool.get('ir.model.access').check(cr, uid, 'res.users', 'write', False) if not canwrite: - if isinstance(ids, (int, float)): + if isinstance(ids, (int, long)): result = override_password(result) else: result = map(override_password, result) @@ -206,11 +207,6 @@ class res_users(osv.osv): ('login_key', 'UNIQUE (login)', 'You can not have two users with the same login !') ] - def _get_default_image(self, cr, uid, context=None): - """ Override of res.partner: multicolor avatars ! """ - image_path = openerp.modules.get_module_resource('base', 'static/src/img', 'avatar%d.png' % random.randint(0, 6)) - return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64')) - def _get_company(self,cr, uid, context=None, uid2=False): if not uid2: uid2 = uid @@ -238,9 +234,9 @@ class res_users(osv.osv): dataobj = self.pool.get('ir.model.data') result = [] try: - dummy,group_id = dataobj.get_object_reference(cr, 1, 'base', 'group_user') + dummy,group_id = dataobj.get_object_reference(cr, SUPERUSER_ID, 'base', 'group_user') result.append(group_id) - dummy,group_id = dataobj.get_object_reference(cr, 1, 'base', 'group_partner_manager') + dummy,group_id = dataobj.get_object_reference(cr, SUPERUSER_ID, 'base', 'group_partner_manager') result.append(group_id) except ValueError: # If these groups does not exists anymore @@ -248,14 +244,14 @@ class res_users(osv.osv): return result _defaults = { - 'password' : '', - 'active' : True, + 'password': '', + 'active': True, 'customer': False, 'menu_id': _get_menu, 'company_id': _get_company, 'company_ids': _get_companies, 'groups_id': _get_group, - 'image': lambda self, cr, uid, context: self._get_default_image(cr, uid, context), + 'image': lambda self, cr, uid, ctx={}: self.pool.get('res.partner')._get_default_image(cr, uid, False, ctx, colorize=True), } def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): @@ -280,7 +276,7 @@ class res_users(osv.osv): break else: if 'company_id' in values: - if not (values['company_id'] in self.read(cr, 1, uid, ['company_ids'], context=context)['company_ids']): + if not (values['company_id'] in self.read(cr, SUPERUSER_ID, uid, ['company_ids'], context=context)['company_ids']): del values['company_id'] uid = 1 # safe fields only, so we write as super-user to bypass access rights @@ -332,7 +328,7 @@ class res_users(osv.osv): return super(res_users, self).copy(cr, uid, id, copydef, context) def context_get(self, cr, uid, context=None): - user = self.browse(cr, 1, uid, context) + user = self.browse(cr, SUPERUSER_ID, uid, context) result = {} for k in self._all_columns.keys(): if k.startswith('context_'): @@ -350,7 +346,7 @@ class res_users(osv.osv): def action_get(self, cr, uid, context=None): dataobj = self.pool.get('ir.model.data') - data_id = dataobj._get_id(cr, 1, 'base', 'action_res_users_my') + data_id = dataobj._get_id(cr, SUPERUSER_ID, 'base', 'action_res_users_my') return dataobj.browse(cr, uid, data_id, context=context).res_id def check_super(self, passwd): @@ -361,7 +357,7 @@ class res_users(osv.osv): def check_credentials(self, cr, uid, password): """ Override this method to plug additional authentication methods""" - res = self.search(cr, 1, [('id','=',uid),('password','=',password)]) + res = self.search(cr, SUPERUSER_ID, [('id','=',uid),('password','=',password)]) if not res: raise openerp.exceptions.AccessDenied() @@ -377,7 +373,7 @@ class res_users(osv.osv): # of them rolled back due to a concurrent access.) cr.autocommit(True) # check if user exists - res = self.search(cr, 1, [('login','=',login)]) + res = self.search(cr, SUPERUSER_ID, [('login','=',login)]) if res: user_id = res[0] # check credentials @@ -542,7 +538,7 @@ class groups_implied(osv.osv): return memo[g] res = {} - for g in self.browse(cr, 1, ids, context): + for g in self.browse(cr, SUPERUSER_ID, ids, context): res[g.id] = map(int, computed_set(g)) return res @@ -687,7 +683,7 @@ class groups_view(osv.osv): def get_user_groups_view(self, cr, uid, context=None): try: - view = self.pool.get('ir.model.data').get_object(cr, 1, 'base', 'user_groups_view', context) + view = self.pool.get('ir.model.data').get_object(cr, SUPERUSER_ID, 'base', 'user_groups_view', context) assert view and view._table_name == 'ir.ui.view' except Exception: view = False diff --git a/openerp/addons/base/res/res_users_view.xml b/openerp/addons/base/res/res_users_view.xml index 9c32d32287c..a1d0b0d5f2e 100644 --- a/openerp/addons/base/res/res_users_view.xml +++ b/openerp/addons/base/res/res_users_view.xml @@ -88,7 +88,7 @@ <form string="Users" version="7.0"> <field name="id" invisible="1"/> <sheet> - <field name="image_medium" widget='image' class="oe_avatar oe_left"/> + <field name="image" widget='image' class="oe_avatar oe_left" options='{"preview_image": "image_medium"}'/> <div class="oe_title"> <label for="name" class="oe_edit_only"/> <h1><field name="name"/></h1> @@ -195,9 +195,7 @@ <field eval="18" name="priority"/> <field name="arch" type="xml"> <form string="Users" version="7.0"> - <div class="oe_right oe_avatar"> - <field name="image_small" widget='image' class="oe_image_small"/> - </div> + <field name="image" widget='image' class="oe_right oe_avatar" options='{"preview_image": "image_small"}'/> <h1> <field name="name" readonly="1" class="oe_inline"/> (<field name="login" readonly="1" class="oe_inline"/>) diff --git a/openerp/addons/base/rng/view.rng b/openerp/addons/base/rng/view.rng index c583040495b..dfeeb03d98b 100644 --- a/openerp/addons/base/rng/view.rng +++ b/openerp/addons/base/rng/view.rng @@ -172,6 +172,9 @@ <rng:define name="form"> <rng:element name="form"> <rng:ref name="overload"/> + <rng:optional><rng:attribute name="create" /></rng:optional> + <rng:optional><rng:attribute name="delete" /></rng:optional> + <rng:optional><rng:attribute name="edit" /></rng:optional> <rng:optional><rng:attribute name="string"/></rng:optional> <rng:optional><rng:attribute name="type"/></rng:optional> <rng:optional><rng:attribute name="link"/></rng:optional> @@ -181,9 +184,13 @@ <rng:define name="diagram"> <rng:element name="diagram"> + <rng:optional><rng:attribute name="create" /></rng:optional> <rng:optional><rng:attribute name="string"/></rng:optional> <rng:ref name="node"/> - <rng:ref name="arrow"/> + <rng:ref name="arrow"/> + <rng:zeroOrMore> + <rng:ref name="label"/> + </rng:zeroOrMore> </rng:element> </rng:define> @@ -220,6 +227,8 @@ <rng:attribute name="default_group_by" /> </rng:optional> <rng:optional><rng:attribute name="create" /></rng:optional> + <rng:optional><rng:attribute name="delete" /></rng:optional> + <rng:optional><rng:attribute name="edit" /></rng:optional> <rng:optional><rng:attribute name="quick_create" /></rng:optional> <rng:zeroOrMore> <rng:ref name="field"/> @@ -235,6 +244,9 @@ <rng:define name="tree"> <rng:element name="tree"> <rng:ref name="overload"/> + <rng:optional><rng:attribute name="create" /></rng:optional> + <rng:optional><rng:attribute name="delete" /></rng:optional> + <rng:optional><rng:attribute name="edit" /></rng:optional> <rng:optional><rng:attribute name="string"/></rng:optional> <rng:optional><rng:attribute name="colors"/></rng:optional> <rng:optional><rng:attribute name="fonts"/></rng:optional> @@ -373,6 +385,9 @@ <rng:value>5years</rng:value> </rng:choice></rng:attribute> </rng:optional> + <rng:optional><rng:attribute name="create"/></rng:optional> + <rng:optional><rng:attribute name="delete"/></rng:optional> + <rng:optional><rng:attribute name="edit"/></rng:optional> <rng:optional><rng:attribute name="color"/></rng:optional> <rng:optional><rng:attribute name="date_delay"/></rng:optional> <rng:optional><rng:attribute name="day_length"/></rng:optional> diff --git a/openerp/addons/base/security/base_security.xml b/openerp/addons/base/security/base_security.xml index cd0b7e999b3..8eb832ea618 100644 --- a/openerp/addons/base/security/base_security.xml +++ b/openerp/addons/base/security/base_security.xml @@ -1,54 +1,51 @@ <?xml version="1.0"?> <openerp> - <data noupdate="0"> - -<!-- - Users Groups - [Note] Field 'category_id' is set later in base/module/module_data.xml ---> - <record model="res.groups" id="group_erp_manager"> - <field name="name">Access Rights</field> - </record> - <record model="res.groups" id="group_system"> - <field name="name">Configuration</field> - <field name="implied_ids" eval="[(4, ref('group_erp_manager'))]"/> - <field name="users" eval="[(4, ref('base.user_root'))]"/> - </record> - - <record model="res.groups" id="group_user"> - <field name="name">Employee</field> - <field name="users" eval="[(4, ref('base.user_root'))]"/> - </record> - - <record model="res.groups" id="group_multi_company"> - <field name="name">Multi Companies</field> - </record> - - <record model="res.groups" id="group_multi_currency"> - <field name="name">Multi Currencies</field> - </record> - - <record model="res.groups" id="group_no_one"> - <field name="name">Technical Features</field> - </record> - - <record id="group_sale_salesman" model="res.groups"> - <field name="name">User</field> - </record> - <record id="group_sale_manager" model="res.groups"> - <field name="name">Manager</field> - <field name="implied_ids" eval="[(4, ref('group_sale_salesman'))]"/> - </record> - - <!-- Set accesses to menu --> - <record model="ir.ui.menu" id="base.menu_administration"> - <field name="groups_id" eval="[(6,0, [ref('group_system'), ref('group_erp_manager')])]"/> - </record> - - </data> - <data noupdate="1"> + <!-- + Users Groups + Note that the field 'category_id' is set later in + base/module/module_data.xml + --> + <record model="res.groups" id="group_erp_manager"> + <field name="name">Access Rights</field> + </record> + <record model="res.groups" id="group_system"> + <field name="name">Configuration</field> + <field name="implied_ids" eval="[(4, ref('group_erp_manager'))]"/> + <field name="users" eval="[(4, ref('base.user_root'))]"/> + </record> + + <record model="res.groups" id="group_user"> + <field name="name">Employee</field> + <field name="users" eval="[(4, ref('base.user_root'))]"/> + </record> + + <record model="res.groups" id="group_multi_company"> + <field name="name">Multi Companies</field> + </record> + + <record model="res.groups" id="group_multi_currency"> + <field name="name">Multi Currencies</field> + </record> + + <record model="res.groups" id="group_no_one"> + <field name="name">Technical Features</field> + </record> + + <record id="group_sale_salesman" model="res.groups"> + <field name="name">User</field> + </record> + <record id="group_sale_manager" model="res.groups"> + <field name="name">Manager</field> + <field name="implied_ids" eval="[(4, ref('group_sale_salesman'))]"/> + </record> + + <!-- Set accesses to menu --> + <record model="ir.ui.menu" id="base.menu_administration"> + <field name="groups_id" eval="[(6,0, [ref('group_system'), ref('group_erp_manager')])]"/> + </record> + <record model="ir.rule" id="res_widget_user_rule"> <field name="name">res.widget.user rule</field> <field name="model_id" ref="model_res_widget_user"/> @@ -58,8 +55,11 @@ <record model="ir.rule" id="res_partner_rule"> <field name="name">res.partner company</field> <field name="model_id" ref="model_res_partner"/> - <!-- Show partners from ancestors and descendants companies (or company-less), this is usually a better - default for multicompany setups. --> + <!-- + Show partners from ancestors and descendants companies + (or company-less), this is usually a better default for + multicompany setups. + --> <field name="domain_force">['|','|',('company_id.child_ids','child_of',[user.company_id.id]),('company_id','child_of',[user.company_id.id]),('company_id','=',False)]</field> </record> diff --git a/openerp/addons/base/security/ir.model.access.csv b/openerp/addons/base/security/ir.model.access.csv index d49aa18db8c..c340e922396 100644 --- a/openerp/addons/base/security/ir.model.access.csv +++ b/openerp/addons/base/security/ir.model.access.csv @@ -9,10 +9,14 @@ "access_ir_exports_group_system","ir_exports group_system","model_ir_exports","base.group_user",1,1,1,1 "access_ir_exports_line_group_system","ir_exports_line group_system","model_ir_exports_line","base.group_user",1,1,1,1 "access_ir_model_group_erp_manager","ir_model group_erp_manager","model_ir_model","group_erp_manager",1,1,1,1 +"access_ir_model_constraint_group_erp_manager","ir_model_constraint group_erp_manager","model_ir_model_constraint","group_erp_manager",1,1,1,1 +"access_ir_model_relation_group_erp_manager","ir_model_relation group_erp_manager","model_ir_model_relation","group_erp_manager",1,1,1,1 "access_ir_model_access_group_erp_manager","ir_model_access_group_erp_manager","model_ir_model_access","group_erp_manager",1,1,1,1 "access_ir_model_data_group_erp_manager","ir_model_data group_erp_manager","model_ir_model_data","group_erp_manager",1,1,1,1 "access_ir_model_fields_group_erp_manager","ir_model_fields group_erp_manager","model_ir_model_fields","group_erp_manager",1,1,1,1 "access_ir_model_all","ir_model_all","model_ir_model",,1,0,0,0 +"access_ir_model_constraint","ir_model_constraint","model_ir_model_constraint",,1,0,0,0 +"access_ir_model_relation","ir_model_relation","model_ir_model_relation",,1,0,0,0 "access_ir_model_access_all","ir_model_access_all","model_ir_model_access",,1,0,0,0 "access_ir_model_data_all","ir_model_data all","model_ir_model_data",,1,0,0,0 "access_ir_model_fields_all","ir_model_fields all","model_ir_model_fields",,1,0,0,0 @@ -106,8 +110,6 @@ "access_res_payterm_group_system","res_payterm_group_system","model_res_payterm","group_system",1,1,1,1 "access_res_bank_group_partner_manager","res_bank_group_partner_manager","model_res_bank","group_partner_manager",1,1,1,1 "access_res_bank_user","res_bank user","model_res_bank","group_user",1,0,0,0 -"access_publisher_warranty_group_user","publisher_warranty_contract group_user","model_publisher_warranty_contract","group_system",1,1,1,1 -"access_publisher_warranty_all","publisher_warranty_contract all","model_publisher_warranty_contract",,1,0,0,0 "access_multi_company_default user","multi_company_default all","model_multi_company_default",,1,0,0,0 "access_multi_company_default manager","multi_company_default Manager","model_multi_company_default","group_erp_manager",1,1,1,1 "access_ir_filter all","ir_filters all","model_ir_filters",,1,0,0,0 @@ -118,6 +120,5 @@ "access_ir_config_parameter","ir_config_parameter","model_ir_config_parameter",,1,0,0,0 "access_ir_mail_server_all","ir_mail_server","model_ir_mail_server",,1,0,0,0 "access_ir_actions_client","ir_actions_client all","model_ir_actions_client",,1,0,0,0 -"access_ir_needaction_users_rel","ir_needaction_users_rel","model_ir_needaction_users_rel",,1,1,1,1 "access_ir_needaction_mixin","ir_needaction_mixin","model_ir_needaction_mixin",,1,1,1,1 diff --git a/openerp/addons/base/static/src/img/avatar.png b/openerp/addons/base/static/src/img/avatar.png new file mode 100644 index 00000000000..0965da9de99 Binary files /dev/null and b/openerp/addons/base/static/src/img/avatar.png differ diff --git a/openerp/addons/base/static/src/img/avatar0.png b/openerp/addons/base/static/src/img/avatar0.png deleted file mode 100644 index 2bcc7c8d2e4..00000000000 Binary files a/openerp/addons/base/static/src/img/avatar0.png and /dev/null differ diff --git a/openerp/addons/base/static/src/img/avatar1.png b/openerp/addons/base/static/src/img/avatar1.png deleted file mode 100644 index 4f6d2f7e818..00000000000 Binary files a/openerp/addons/base/static/src/img/avatar1.png and /dev/null differ diff --git a/openerp/addons/base/static/src/img/avatar2.png b/openerp/addons/base/static/src/img/avatar2.png deleted file mode 100644 index 70d5df7ee60..00000000000 Binary files a/openerp/addons/base/static/src/img/avatar2.png and /dev/null differ diff --git a/openerp/addons/base/static/src/img/avatar3.png b/openerp/addons/base/static/src/img/avatar3.png deleted file mode 100644 index 053768aa035..00000000000 Binary files a/openerp/addons/base/static/src/img/avatar3.png and /dev/null differ diff --git a/openerp/addons/base/static/src/img/avatar4.png b/openerp/addons/base/static/src/img/avatar4.png deleted file mode 100644 index 1b2a99f05c3..00000000000 Binary files a/openerp/addons/base/static/src/img/avatar4.png and /dev/null differ diff --git a/openerp/addons/base/static/src/img/avatar5.png b/openerp/addons/base/static/src/img/avatar5.png deleted file mode 100644 index 0f6c416ecf0..00000000000 Binary files a/openerp/addons/base/static/src/img/avatar5.png and /dev/null differ diff --git a/openerp/addons/base/static/src/img/avatar6.png b/openerp/addons/base/static/src/img/avatar6.png deleted file mode 100644 index d6a18c2779e..00000000000 Binary files a/openerp/addons/base/static/src/img/avatar6.png and /dev/null differ diff --git a/openerp/addons/base/static/src/img/company_image.png b/openerp/addons/base/static/src/img/company_image.png index 2995ba12644..0a52179c779 100644 Binary files a/openerp/addons/base/static/src/img/company_image.png and b/openerp/addons/base/static/src/img/company_image.png differ diff --git a/openerp/addons/base/static/src/img/partner_image.png b/openerp/addons/base/static/src/img/partner_image.png deleted file mode 100644 index 87fdbc5af55..00000000000 Binary files a/openerp/addons/base/static/src/img/partner_image.png and /dev/null differ diff --git a/openerp/addons/base/test/base_test.yml b/openerp/addons/base/test/base_test.yml index fe22e3a4935..1aea2363f84 100644 --- a/openerp/addons/base/test/base_test.yml +++ b/openerp/addons/base/test/base_test.yml @@ -42,15 +42,13 @@ - !python {model: ir.model}: | from tools.safe_eval import safe_eval + from tools.misc import mute_logger try: - safe_eval('open("/etc/passwd","r")') - assert False, "safe_eval should not allow calling open() builtin" + with mute_logger('openerp.tools.safe_eval'): + safe_eval('open("/etc/passwd","r")') + assert False, "safe_eval should not allow calling open() builtin" except NameError: - pass - except: - # NameError should be raised because open() builtin is not found, - # but other exceptions probably indicate that open() was executed! - assert False, "safe_eval should not allow calling open() builtin" + pass - "ORM test: verify that parent_store computation are going right" diff --git a/openerp/addons/base/test/test_osv_expression.yml b/openerp/addons/base/test/test_osv_expression.yml index d607b17f801..3843d374e64 100644 --- a/openerp/addons/base/test/test_osv_expression.yml +++ b/openerp/addons/base/test/test_osv_expression.yml @@ -206,8 +206,7 @@ # that don't have OpenERP has a parent company, you expect to find, # among others, the companies that don't have parent company. # - # ('parent_id', 'not in', [0]) must give the same result than - # ('parent_id', 'not in', []), i.e. a empty set or a set with non- + # existing values be treated similarly if we simply check that some # existing value belongs to them. @@ -215,7 +214,7 @@ res_0.sort() res_1 = self.search(cr, uid, [('parent_id', 'not in', [max_partner_id + 1])]) # get all rows, included null parent_id res_1.sort() - res_2 = self.search(cr, uid, [('parent_id', 'not in', False)]) # get rows with not null parent_id, deprecated syntax + res_2 = self.search(cr, uid, [('parent_id', '!=', False)]) # get rows with not null parent_id, deprecated syntax res_2.sort() res_3 = self.search(cr, uid, [('parent_id', 'not in', [])]) # get all rows, included null parent_id res_3.sort() @@ -235,7 +234,7 @@ res_5.sort() res_6 = self.search(cr, uid, [('parent_id', 'in', [max_partner_id + 1])]) res_6.sort() - res_7 = self.search(cr, uid, [('parent_id', 'in', False)]) + res_7 = self.search(cr, uid, [('parent_id', '=', False)]) res_7.sort() res_8 = self.search(cr, uid, [('parent_id', 'in', [])]) res_8.sort() @@ -256,7 +255,7 @@ res_10.sort() res_11 = self.search(cr, uid, ['!', ('parent_id', 'in', [max_partner_id + 1])]) res_11.sort() - res_12 = self.search(cr, uid, ['!', ('parent_id', 'in', False)]) + res_12 = self.search(cr, uid, ['!', ('parent_id', '=', False)]) res_12.sort() res_13 = self.search(cr, uid, ['!', ('parent_id', 'in', [])]) res_13.sort() @@ -277,7 +276,7 @@ res_16.sort() assert res_16 == partner_ids - res_17 = self.search(cr, uid, [('website', 'not in', False)]) + res_17 = self.search(cr, uid, [('website', '!=', False)]) res_17.sort() assert res_17 == with_website @@ -292,21 +291,21 @@ assert res_101 == [], 'res_101: expected %r, got %r' % ([], res_101) assert res_102 == company_ids, 'res_102: expected %r, got %r' % (company_ids, res_102) - - Property of the query (one2many not in False). + Property of the query (one2many != False). - !python {model: res.currency }: | ids = self.search(cr, uid, []) referenced_companies = set([x.company_id.id for x in self.browse(cr, uid, ids)]) - companies = set(self.pool.get('res.company').search(cr, uid, [('currency_ids', 'not in', False)])) + companies = set(self.pool.get('res.company').search(cr, uid, [('currency_ids', '!=', False)])) assert referenced_companies == companies - - Property of the query (one2many in False). + Property of the query (one2many = False). - !python {model: res.currency }: | ids = self.search(cr, uid, []) referenced_companies = set([x.company_id.id for x in self.browse(cr, uid, ids)]) unreferenced_companies = set(self.pool.get('res.company').search(cr, uid, [])).difference(referenced_companies) - companies = set(self.pool.get('res.company').search(cr, uid, [('currency_ids', 'in', False)])) + companies = set(self.pool.get('res.company').search(cr, uid, [('currency_ids', '=', False)])) assert unreferenced_companies == companies - Equivalent queries. @@ -317,7 +316,7 @@ res_1 = self.search(cr, uid, [('name', 'not like', 'probably_unexisting_name')]) res_2 = self.search(cr, uid, [('id', 'not in', [max_currency_id + 1003])]) res_3 = self.search(cr, uid, [('id', 'not in', [])]) - res_4 = self.search(cr, uid, [('id', 'not in', False)]) + res_4 = self.search(cr, uid, [('id', '!=', False)]) res_0.sort() res_1.sort() res_2.sort() @@ -400,7 +399,7 @@ # get the companies referenced by some currency (this is normally the main company) res_10 = self.search(cr, uid, [('currency_ids', 'not like', 'probably_unexisting_name')]) res_11 = self.search(cr, uid, [('currency_ids', 'not in', [max_currency_id + 1])]) - res_12 = self.search(cr, uid, [('currency_ids', 'not in', False)]) + res_12 = self.search(cr, uid, [('currency_ids', '!=', False)]) res_13 = self.search(cr, uid, [('currency_ids', 'not in', [])]) res_10.sort() res_11.sort() diff --git a/openerp/addons/base/tests/__init__.py b/openerp/addons/base/tests/__init__.py index 5ea7654c008..42fef2eb39d 100644 --- a/openerp/addons/base/tests/__init__.py +++ b/openerp/addons/base/tests/__init__.py @@ -1,5 +1,5 @@ -import test_ir_values +import test_ir_values, test_base checks = [ - test_ir_values, + test_ir_values, test_base ] diff --git a/openerp/addons/base/tests/test_base.py b/openerp/addons/base/tests/test_base.py new file mode 100644 index 00000000000..285af8fbf6e --- /dev/null +++ b/openerp/addons/base/tests/test_base.py @@ -0,0 +1,43 @@ +import unittest2 + +import openerp.tests.common as common + +class test_base(common.TransactionCase): + + def setUp(self): + super(test_base,self).setUp() + self.res_partner = self.registry('res.partner') + + # samples use effective TLDs from the Mozilla public suffix + # list at http://publicsuffix.org + self.samples = [ + ('"Raoul Grosbedon" <raoul@chirurgiens-dentistes.fr> ', 'Raoul Grosbedon', 'raoul@chirurgiens-dentistes.fr'), + ('ryu+giga-Sushi@aizubange.fukushima.jp', '', 'ryu+giga-Sushi@aizubange.fukushima.jp'), + ('Raoul chirurgiens-dentistes.fr', 'Raoul chirurgiens-dentistes.fr', ''), + (" Raoul O'hara <!@historicalsociety.museum>", "Raoul O'hara", '!@historicalsociety.museum') + ] + + def test_00_res_partner_name_create(self): + cr, uid = self.cr, self.uid + parse = self.res_partner._parse_partner_name + for text, name, mail in self.samples: + self.assertEqual((name,mail), parse(text), 'Partner name parsing failed') + partner_id, dummy = self.res_partner.name_create(cr, uid, text) + partner = self.res_partner.browse(cr, uid, partner_id) + self.assertEqual(name or mail, partner.name, 'Partner name incorrect') + self.assertEqual(mail or False, partner.email, 'Partner email incorrect') + + def test_10_res_partner_find_or_create(self): + cr,uid = self.cr, self.uid + email = self.samples[0][0] + partner_id, dummy = self.res_partner.name_create(cr, uid, email) + found_id = self.res_partner.find_or_create(cr, uid, email) + self.assertEqual(partner_id, found_id, 'find_or_create failed') + new_id = self.res_partner.find_or_create(cr, uid, self.samples[1][0]) + self.assertTrue(new_id > partner_id, 'find_or_create failed - should have created new one') + new_id2 = self.res_partner.find_or_create(cr, uid, self.samples[2][0]) + self.assertTrue(new_id2 > new_id, 'find_or_create failed - should have created new one again') + + +if __name__ == '__main__': + unittest2.main() \ No newline at end of file diff --git a/openerp/import_xml.rng b/openerp/import_xml.rng index bf5a9e1800e..5dd789c6e95 100644 --- a/openerp/import_xml.rng +++ b/openerp/import_xml.rng @@ -185,7 +185,6 @@ <rng:optional> <rng:attribute name="string"/> </rng:optional> <rng:optional> <rng:attribute name="sequence"/> </rng:optional> <rng:optional> <rng:attribute name="groups"/> </rng:optional> - <rng:optional> <rng:attribute name="type"/> </rng:optional> <rng:optional> <rng:attribute name="menu"/> </rng:optional> <rng:empty /> </rng:element> diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py index 874a6ce7063..86e69fa64ba 100644 --- a/openerp/modules/loading.py +++ b/openerp/modules/loading.py @@ -3,7 +3,7 @@ # # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). -# Copyright (C) 2010-2011 OpenERP s.a. (<http://openerp.com>). +# Copyright (C) 2010-2012 OpenERP s.a. (<http://openerp.com>). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -39,6 +39,7 @@ import openerp.pooler as pooler import openerp.release as release import openerp.tools as tools import openerp.tools.assertion_report as assertion_report +from openerp import SUPERUSER_ID from openerp import SUPERUSER_ID from openerp.tools.translate import _ @@ -84,7 +85,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= _load_data(cr, module_name, idref, mode, 'test') return True except Exception: - _logger.error( + _logger.exception( 'module %s: an exception occurred in a test', module_name) return False finally: @@ -119,7 +120,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= elif ext == '.sql': process_sql_file(cr, fp) elif ext == '.yml': - tools.convert_yaml_import(cr, module_name, fp, idref, mode, noupdate, report) + tools.convert_yaml_import(cr, module_name, fp, kind, idref, mode, noupdate, report) else: tools.convert_xml_import(cr, module_name, fp, idref, mode, noupdate, report) finally: @@ -296,7 +297,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): modobj = pool.get('ir.module.module') if ('base' in tools.config['init']) or ('base' in tools.config['update']): _logger.info('updating modules list') - modobj.update_list(cr, 1) + modobj.update_list(cr, SUPERUSER_ID) _check_module_names(cr, itertools.chain(tools.config['init'].keys(), tools.config['update'].keys())) diff --git a/openerp/modules/module.py b/openerp/modules/module.py index b1d4de31bce..540a23c5bcd 100644 --- a/openerp/modules/module.py +++ b/openerp/modules/module.py @@ -162,7 +162,7 @@ def initialize_sys_path(): return ad_paths = map(lambda m: os.path.abspath(tools.ustr(m.strip())), tools.config['addons_path'].split(',')) - ad_paths.append(_ad) # for get_module_path + ad_paths.append(os.path.abspath(_ad)) # for get_module_path sys.meta_path.append(AddonsImportHook()) def get_module_path(module, downloaded=False, display_warning=True): @@ -283,25 +283,28 @@ def get_module_as_zip(modulename, b64enc=True, src=True): def get_module_resource(module, *args): """Return the full path of a resource of the given module. - @param module: the module - @param args: the resource path components + :param module: module name + :param list(str) args: resource path components within module - @return: absolute path to the resource + :rtype: str + :return: absolute path to the resource TODO name it get_resource_path TODO make it available inside on osv object (self.get_resource_path) """ - a = get_module_path(module) - if not a: return False - resource_path = opj(a, *args) - if zipfile.is_zipfile( a +'.zip') : - zip = zipfile.ZipFile( a + ".zip") + mod_path = get_module_path(module) + if not mod_path: return False + resource_path = opj(mod_path, *args) + if os.path.isdir(mod_path): + # the module is a directory - ignore zip behavior + if os.path.exists(resource_path): + return resource_path + elif zipfile.is_zipfile(mod_path + '.zip'): + zip = zipfile.ZipFile( mod_path + ".zip") files = ['/'.join(f.split('/')[1:]) for f in zip.namelist()] resource_path = '/'.join(args) if resource_path in files: - return opj(a, resource_path) - elif os.path.exists(resource_path): - return resource_path + return opj(mod_path, resource_path) return False def get_module_icon(module): diff --git a/openerp/netsvc.py b/openerp/netsvc.py index 506c1e4bcba..c1a31602262 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -3,7 +3,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2004-2011 OpenERP SA (<http://www.openerp.com>) +# Copyright (C) 2004-2012 OpenERP SA (<http://www.openerp.com>) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -86,12 +86,12 @@ class Service(object): cls._services.pop(name) def LocalService(name): - # Special case for addons support, will be removed in a few days when addons - # are updated to directly use openerp.osv.osv.service. - if name == 'object_proxy': - return openerp.osv.osv.service + # Special case for addons support, will be removed in a few days when addons + # are updated to directly use openerp.osv.osv.service. + if name == 'object_proxy': + return openerp.osv.osv.service - return Service._services[name] + return Service._services[name] class ExportService(object): """ Proxy for exported services. @@ -238,9 +238,9 @@ def init_logger(): # server intended to test it. def init_alternative_logger(): class H(logging.Handler): - def emit(self, record): - if record.levelno > 20: - print record.levelno, record.pathname, record.msg + def emit(self, record): + if record.levelno > 20: + print record.levelno, record.pathname, record.msg handler = H() # Add the handler to the 'openerp' logger. logger = logging.getLogger('openerp') @@ -376,11 +376,11 @@ def dispatch_rpc(service_name, method, params): except openerp.exceptions.Warning: raise except openerp.exceptions.DeferredException, e: - _logger.error(tools.exception_to_unicode(e)) + _logger.exception(tools.exception_to_unicode(e)) post_mortem(e.traceback) raise except Exception, e: - _logger.error(tools.exception_to_unicode(e)) + _logger.exception(tools.exception_to_unicode(e)) post_mortem(sys.exc_info()) raise diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 5a47601f8a5..037d2a90986 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -46,6 +46,7 @@ from openerp.tools.translate import _ from openerp.tools import float_round, float_repr import simplejson from openerp.tools.html_sanitize import html_sanitize +from openerp import SUPERUSER_ID _logger = logging.getLogger(__name__) @@ -444,7 +445,7 @@ class many2one(_column): # build a dictionary of the form {'id_of_distant_resource': name_of_distant_resource} # we use uid=1 because the visibility of a many2one field value (just id and name) # must be the access right of the parent form and not the linked object itself. - records = dict(obj.name_get(cr, 1, + records = dict(obj.name_get(cr, SUPERUSER_ID, list(set([x for x in res.values() if isinstance(x, (int,long))])), context=context)) for id in res: @@ -514,7 +515,8 @@ class one2many(_column): for id in ids: res[id] = [] - ids2 = obj.pool.get(self._obj).search(cr, user, self._domain + [(self._fields_id, 'in', ids)], limit=self._limit, context=context) + domain = self._domain(obj) if callable(self._domain) else self._domain + ids2 = obj.pool.get(self._obj).search(cr, user, domain + [(self._fields_id, 'in', ids)], limit=self._limit, context=context) for r in obj.pool.get(self._obj)._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'): if r[self._fields_id] in res: res[r[self._fields_id]].append(r['id']) @@ -556,7 +558,8 @@ class one2many(_column): reverse_rel = obj._all_columns.get(self._fields_id) assert reverse_rel, 'Trying to unlink the content of a o2m but the pointed model does not have a m2o' # if the o2m has a static domain we must respect it when unlinking - extra_domain = self._domain if isinstance(getattr(self, '_domain', None), list) else [] + domain = self._domain(obj) if callable(self._domain) else self._domain + extra_domain = domain or [] ids_to_unlink = obj.search(cr, user, [(self._fields_id,'=',id)] + extra_domain, context=context) # If the model has cascade deletion, we delete the rows because it is the intended behavior, # otherwise we only nullify the reverse foreign key column. @@ -574,7 +577,8 @@ class one2many(_column): return result def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like', context=None): - return obj.pool.get(self._obj).name_search(cr, uid, value, self._domain, operator, context=context,limit=limit) + domain = self._domain(obj) if callable(self._domain) else self._domain + return obj.pool.get(self._obj).name_search(cr, uid, value, domain, operator, context=context,limit=limit) @classmethod @@ -1200,7 +1204,7 @@ class related(function): else: res = {}.fromkeys(ids, False) - objlst = obj.browse(cr, 1, ids, context=context) + objlst = obj.browse(cr, SUPERUSER_ID, ids, context=context) for data in objlst: if not data: continue @@ -1230,7 +1234,7 @@ class related(function): # name_get as root, as seeing the name of a related # object depends on access right of source document, # not target, so user may not have access. - ng = dict(obj.pool.get(self._obj).name_get(cr, 1, ids, context=context)) + ng = dict(obj.pool.get(self._obj).name_get(cr, SUPERUSER_ID, ids, context=context)) for r in res: if res[r]: res[r] = (res[r], ng[res[r]]) @@ -1495,7 +1499,7 @@ class property(function): # not target, so user may not have access) in order to avoid # pointing on an unexisting record. if property_destination_obj: - if res[id][prop_name] and obj.pool.get(property_destination_obj).exists(cr, 1, res[id][prop_name].id): + if res[id][prop_name] and obj.pool.get(property_destination_obj).exists(cr, SUPERUSER_ID, res[id][prop_name].id): name_get_ids[id] = res[id][prop_name].id else: res[id][prop_name] = False @@ -1503,7 +1507,7 @@ class property(function): # name_get as root (as seeing the name of a related # object depends on access right of source document, # not target, so user may not have access.) - name_get_values = dict(obj.pool.get(property_destination_obj).name_get(cr, 1, name_get_ids.values(), context=context)) + name_get_values = dict(obj.pool.get(property_destination_obj).name_get(cr, SUPERUSER_ID, name_get_ids.values(), context=context)) # the property field is a m2o, we need to return a tuple with (id, name) for k, v in name_get_ids.iteritems(): if res[k][prop_name]: @@ -1539,9 +1543,7 @@ def field_to_dict(model, cr, user, field, context=None): """ res = {'type': field._type} - # This additional attributes for M2M and function field is added - # because we need to display tooltip with this additional information - # when client is started in debug mode. + # some attributes for m2m/function field are added as debug info only if isinstance(field, function): res['function'] = field._fnct and field._fnct.func_name or False res['store'] = field.store @@ -1576,7 +1578,7 @@ def field_to_dict(model, cr, user, field, context=None): res['selection'] = field.selection(model, cr, user, context) if res['type'] in ('one2many', 'many2many', 'many2one'): res['relation'] = field._obj - res['domain'] = field._domain + res['domain'] = field._domain(model) if callable(field._domain) else field._domain res['context'] = field._context if isinstance(field, one2many): diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 7c8085ea8ed..d81833b17a6 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -63,6 +63,7 @@ from openerp.tools.safe_eval import safe_eval as eval from openerp.tools.translate import _ from openerp import SUPERUSER_ID from query import Query +from openerp import SUPERUSER_ID _logger = logging.getLogger(__name__) _schema = logging.getLogger(__name__ + '.schema') @@ -653,6 +654,7 @@ class BaseModel(object): may be set to False. """ __metaclass__ = MetaModel + _auto = True # create database backend _register = False # Set to false if the model shouldn't be automatically discovered. _name = None _columns = {} @@ -666,8 +668,9 @@ class BaseModel(object): _order = 'id' _sequence = None _description = None + _needaction = False - # dict of {field:method}, with method returning the name_get of records + # dict of {field:method}, with method returning the (name_get of records, {id: fold}) # to include in the _read_group, if grouped on this field _group_by_full = {} @@ -773,7 +776,7 @@ class BaseModel(object): } if getattr(f, 'serialization_field', None): # resolve link to serialization_field if specified by name - serialization_field_id = ir_model_fields_obj.search(cr, 1, [('model','=',vals['model']), ('name', '=', f.serialization_field)]) + serialization_field_id = ir_model_fields_obj.search(cr, SUPERUSER_ID, [('model','=',vals['model']), ('name', '=', f.serialization_field)]) if not serialization_field_id: raise except_orm(_('Error'), _("Serialization field `%s` not found for sparse field `%s`!") % (f.serialization_field, k)) vals['serialization_field_id'] = serialization_field_id[0] @@ -889,8 +892,8 @@ class BaseModel(object): for c in cls.__dict__.get(s, []): exist = False for c2 in range(len(new)): - #For _constraints, we should check field and methods as well - if new[c2][2]==c[2] and (new[c2][0] == c[0] \ + #For _constraints, we should check field and methods as well + if new[c2][2]==c[2] and (new[c2][0] == c[0] \ or getattr(new[c2][0],'__name__', True) == \ getattr(c[0],'__name__', False)): # If new class defines a constraint with @@ -1305,7 +1308,7 @@ class BaseModel(object): if not line[i]: continue - if field[:len(prefix)] <> prefix: + if field[:len(prefix)] != prefix: if line[i] and skip: return False continue @@ -1822,8 +1825,11 @@ class BaseModel(object): fields = {} if node.tag == 'diagram': if node.getchildren()[0].tag == 'node': - node_fields = self.pool.get(node.getchildren()[0].get('object')).fields_get(cr, user, None, context) + node_model = self.pool.get(node.getchildren()[0].get('object')) + node_fields = node_model.fields_get(cr, user, None, context) fields.update(node_fields) + if not node.get("create") and not node_model.check_access_rights(cr, user, 'create', raise_exception=False): + node.set("create", 'false') if node.getchildren()[1].tag == 'arrow': arrow_fields = self.pool.get(node.getchildren()[1].get('object')).fields_get(cr, user, None, context) fields.update(arrow_fields) @@ -1831,6 +1837,10 @@ class BaseModel(object): fields = self.fields_get(cr, user, None, context) fields_def = self.__view_look_dom(cr, user, node, view_id, False, fields, context=context) node = self._disable_workflow_buttons(cr, user, node) + if node.tag in ('kanban', 'tree', 'form', 'gantt'): + for action, operation in (('create', 'create'), ('delete', 'unlink'), ('edit', 'write')): + if not node.get(action) and not self.check_access_rights(cr, user, operation, raise_exception=False): + node.set(action, 'false') arch = etree.tostring(node, encoding="utf-8").replace('\t', '') for k in fields.keys(): if k not in fields_def: @@ -2345,7 +2355,7 @@ class BaseModel(object): def read_string(self, cr, uid, id, langs, fields=None, context=None): res = {} res2 = {} - self.pool.get('ir.translation').check_read(cr, uid) + self.pool.get('ir.translation').check_access_rights(cr, uid, 'read') if not fields: fields = self._columns.keys() + self._inherit_fields.keys() #FIXME: collect all calls to _get_source into one SQL call. @@ -2369,7 +2379,7 @@ class BaseModel(object): return res def write_string(self, cr, uid, id, langs, vals, context=None): - self.pool.get('ir.translation').check_write(cr, uid) + self.pool.get('ir.translation').check_access_rights(cr, uid, 'write') #FIXME: try to only call the translation in one SQL for lang in langs: for field in vals: @@ -2437,7 +2447,7 @@ class BaseModel(object): # Grab the list of all groups that should be displayed, including all present groups present_group_ids = [x[groupby][0] for x in read_group_result if x[groupby]] - all_groups = self._group_by_full[groupby](self, cr, uid, present_group_ids, domain, + all_groups,folded = self._group_by_full[groupby](self, cr, uid, present_group_ids, domain, read_group_order=read_group_order, access_rights_uid=openerp.SUPERUSER_ID, context=context) @@ -2488,6 +2498,10 @@ class BaseModel(object): append_left(read_group_result.pop(0)) else: append_right(all_groups.pop(0)) + + if folded: + for r in result: + r['__fold'] = folded.get(r[groupby] and r[groupby][0], False) return result def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False): @@ -2517,7 +2531,7 @@ class BaseModel(object): """ context = context or {} - self.check_read(cr, uid) + self.check_access_rights(cr, uid, 'read') if not fields: fields = self._columns.keys() @@ -2695,7 +2709,7 @@ class BaseModel(object): # if val is a many2one, just write the ID if type(val) == tuple: val = val[0] - if (val<>False) or (type(val)<>bool): + if val is not False: cr.execute(update_query, (ss[1](val), key)) def _check_selection_field_value(self, cr, uid, field, value, context=None): @@ -2719,7 +2733,7 @@ class BaseModel(object): elif val in dict(self._columns[field].selection(self, cr, uid, context=context)): return raise except_orm(_('ValidateError'), - _('The value "%s" for the field "%s.%s" is not in the selection') % (value, self._table, field)) + _('The value "%s" for the field "%s.%s" is not in the selection') % (value, self._table, field)) def _check_removed_columns(self, cr, log=False): # iterate on the database columns to drop the NOT NULL constraints @@ -3398,8 +3412,7 @@ class BaseModel(object): if context is None: context = {} - write_access = self.check_write(cr, user, False) or \ - self.check_create(cr, user, False) + write_access = self.check_access_rights(cr, user, 'write') or self.check_access_rights(cr, user, 'create') res = {} @@ -3463,7 +3476,7 @@ class BaseModel(object): if not context: context = {} - self.check_read(cr, user) + self.check_access_rights(cr, user, 'read') if not fields: fields = list(set(self._columns.keys() + self._inherit_fields.keys())) if isinstance(ids, (int, long)): @@ -3737,18 +3750,6 @@ class BaseModel(object): according to the access rights.""" return self.pool.get('ir.model.access').check(cr, uid, self._name, operation, raise_exception) - def check_create(self, cr, uid, raise_exception=True): - return self.check_access_rights(cr, uid, 'create', raise_exception) - - def check_read(self, cr, uid, raise_exception=True): - return self.check_access_rights(cr, uid, 'read', raise_exception) - - def check_unlink(self, cr, uid, raise_exception=True): - return self.check_access_rights(cr, uid, 'unlink', raise_exception) - - def check_write(self, cr, uid, raise_exception=True): - return self.check_access_rights(cr, uid, 'write', raise_exception) - def check_access_rule(self, cr, uid, ids, operation, context=None): """Verifies that the operation given by ``operation`` is allowed for the user according to ir.rules. @@ -3812,7 +3813,7 @@ class BaseModel(object): self._check_concurrency(cr, ids, context) - self.check_unlink(cr, uid) + self.check_access_rights(cr, uid, 'unlink') ir_property = self.pool.get('ir.property') @@ -3948,7 +3949,7 @@ class BaseModel(object): ids = [ids] self._check_concurrency(cr, ids, context) - self.check_write(cr, user) + self.check_access_rights(cr, user, 'write') result = self._store_get_values(cr, user, ids, vals.keys(), context) or [] @@ -4168,7 +4169,7 @@ class BaseModel(object): if self.is_transient(): self._transient_vacuum(cr, user) - self.check_create(cr, user) + self.check_access_rights(cr, user, 'create') if self._log_access: for f in LOG_ACCESS_COLUMNS: @@ -4660,7 +4661,7 @@ class BaseModel(object): """ if context is None: context = {} - self.check_read(cr, access_rights_uid or user) + self.check_access_rights(cr, access_rights_uid or user, 'read') # For transient models, restrict acces to the current user, except for the super-user if self.is_transient() and self._log_access and user != SUPERUSER_ID: @@ -4960,37 +4961,7 @@ class BaseModel(object): # backwards compatibility get_xml_id = get_external_id _get_xml_ids = _get_external_ids - - def _get_needaction_info(self, cr, uid, user_id, limit=None, order=None, domain=False, context=None): - """Base method for needaction mechanism - - see ir.needaction for actual implementation - - if the model uses the need action mechanism - (hasattr(model_obj, 'needaction_get_record_ids')): - - get the record ids on which the user has actions to perform - - evaluate the menu domain - - compose a new domain: menu domain, limited to ids of - records requesting an action - - count the number of records maching that domain, that - is the number of actions the user has to perform - - this method returns default values - :param: model_name: the name of the model (ex: hr.holidays) - :param: user_id: the id of user - :return: [uses_needaction=True/False, needaction_uid_ctr=%d] - """ - if hasattr(self, 'needaction_get_record_ids'): - # Arbitrary limit, but still much lower thant infinity, to avoid - # getting too much data. - ids = self.needaction_get_record_ids(cr, uid, user_id, limit=8192, context=context) - if not ids: - return [True, 0] - if domain: - new_domain = eval(domain, locals_dict={'uid': user_id}) + [('id', 'in', ids)] - else: - new_domain = [('id', 'in', ids)] - return [True, self.search(cr, uid, new_domain, limit=limit, order=order, count=True, context=context)] - else: - return [False, 0] - + # Transience def is_transient(self): """ Return whether the model is transient. @@ -5042,66 +5013,56 @@ class BaseModel(object): return True - def resolve_o2m_commands_to_record_dicts(self, cr, uid, field_name, o2m_commands, fields=None, context=None): - """ Serializes o2m commands into record dictionaries (as if - all the o2m records came from the database via a read()), and - returns an iterable over these dictionaries. + def resolve_2many_commands(self, cr, uid, field_name, commands, fields=None, context=None): + """ Serializes one2many and many2many commands into record dictionaries + (as if all the records came from the database via a read()). This + method is aimed at onchange methods on one2many and many2many fields. - Because o2m commands might be creation commands, not all - record ids will contain an ``id`` field. Commands matching an - existing record (``UPDATE`` and ``LINK_TO``) will have an id. + Because commands might be creation commands, not all record dicts + will contain an ``id`` field. Commands matching an existing record + will have an ``id``. - .. note:: ``CREATE``, ``UPDATE`` and ``LINK_TO`` stand for the - o2m command codes ``0``, ``1`` and ``4`` - respectively - - :param field_name: name of the o2m field matching the commands - :type field_name: str - :param o2m_commands: one2many commands to execute on ``field_name`` - :type o2m_commands: list((int|False, int|False, dict|False)) - :param fields: list of fields to read from the database, when applicable - :type fields: list(str) - :raises AssertionError: if a command is not ``CREATE``, ``UPDATE`` or ``LINK_TO`` - :returns: o2m records in a shape similar to that returned by - ``read()`` (except records may be missing the ``id`` - field if they don't exist in db) - :rtype: ``list(dict)`` + :param field_name: name of the one2many or many2many field matching the commands + :type field_name: str + :param commands: one2many or many2many commands to execute on ``field_name`` + :type commands: list((int|False, int|False, dict|False)) + :param fields: list of fields to read from the database, when applicable + :type fields: list(str) + :returns: records in a shape similar to that returned by ``read()`` + (except records may be missing the ``id`` field if they don't exist in db) + :rtype: list(dict) """ - o2m_model = self._all_columns[field_name].column._obj + result = [] # result (list of dict) + record_ids = [] # ids of records to read + updates = {} # {id: dict} of updates on particular records - # convert single ids and pairs to tripled commands - commands = [] - for o2m_command in o2m_commands: - if not isinstance(o2m_command, (list, tuple)): - command = 4 - commands.append((command, o2m_command, False)) - elif len(o2m_command) == 1: - (command,) = o2m_command - commands.append((command, False, False)) - elif len(o2m_command) == 2: - command, id = o2m_command - commands.append((command, id, False)) - else: - command = o2m_command[0] - commands.append(o2m_command) - assert command in (0, 1, 4), \ - "Only CREATE, UPDATE and LINK_TO commands are supported in resolver" + for command in commands: + if not isinstance(command, (list, tuple)): + record_ids.append(command) + elif command[0] == 0: + result.append(command[2]) + elif command[0] == 1: + record_ids.append(command[1]) + updates.setdefault(command[1], {}).update(command[2]) + elif command[0] in (2, 3): + record_ids = [id for id in record_ids if id != command[1]] + elif command[0] == 4: + record_ids.append(command[1]) + elif command[0] == 5: + result, record_ids = [], [] + elif command[0] == 6: + result, record_ids = [], list(command[2]) - # extract records to read, by id, in a mapping dict - ids_to_read = [id for (command, id, _) in commands if command in (1, 4)] - records_by_id = dict( - (record['id'], record) - for record in self.pool.get(o2m_model).read( - cr, uid, ids_to_read, fields=fields, context=context)) + # read the records and apply the updates + other_model = self.pool.get(self._all_columns[field_name].column._obj) + for record in other_model.read(cr, uid, record_ids, fields=fields, context=context): + record.update(updates.get(record['id'], {})) + result.append(record) - record_dicts = [] - # merge record from db with record provided by command - for command, id, record in commands: - item = {} - if command in (1, 4): item.update(records_by_id[id]) - if command in (0, 1): item.update(record) - record_dicts.append(item) - return record_dicts + return result + + # for backward compatibility + resolve_o2m_commands_to_record_dicts = resolve_2many_commands # keep this import here, at top it will cause dependency cycle errors import expression @@ -5117,6 +5078,7 @@ class Model(BaseModel): The system will later instantiate the class once per database (on which the class' module is installed). """ + _auto = True _register = False # not visible in ORM registry, meant to be python-inherited only _transient = False # True in a TransientModel @@ -5129,6 +5091,7 @@ class TransientModel(BaseModel): records they created. The super-user has unrestricted access to all TransientModel records. """ + _auto = True _register = False # not visible in ORM registry, meant to be python-inherited only _transient = True diff --git a/openerp/pychart/__init__.py b/openerp/pychart/__init__.py deleted file mode 100644 index a45c23cc87f..00000000000 --- a/openerp/pychart/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -############################################################################## -__all__ = [ "axis", "area", "basecanvas", "canvas", - "line_plot", "pie_plot", "rose_plot", "tick_mark", - "bar_plot", "chart_data", "arrow", "text_box", "color", "font", - "fill_style", "error_bar", "range_plot", "chart_object", - "line_style", "legend", "pychart_util", "theme", "scaling", - "zap", "coord", "linear_coord", "log_coord", - "category_coord", "afm", "interval_bar_plot" ] - diff --git a/openerp/pychart/afm/AvantGarde_Book.py b/openerp/pychart/afm/AvantGarde_Book.py deleted file mode 100644 index bfaaec0050d..00000000000 --- a/openerp/pychart/afm/AvantGarde_Book.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font AvantGarde-Book (path: /usr/share/fonts/afms/adobe/pagk8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["AvantGarde-Book"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 277, 295, 309, 554, 554, 775, 757, 351, 369, 369, 425, 606, 277, 332, 277, 437, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 277, 277, 606, 606, 606, 591, 867, 740, 574, 813, 744, 536, 485, 872, 683, 226, 482, 591, 462, 919, 740, 869, 592, 871, 607, 498, 426, 655, 702, 960, 609, 592, 480, 351, 605, 351, 606, 500, 351, 683, 682, 647, 685, 650, 314, 673, 610, 200, 203, 502, 200, 938, 610, 655, 682, 682, 301, 388, 339, 608, 554, 831, 480, 536, 425, 351, 672, 351, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 295, 554, 554, 166, 554, 554, 615, 554, 198, 502, 425, 251, 251, 487, 485, 500, 500, 553, 553, 277, 500, 564, 606, 354, 502, 484, 425, 1000, 1174, 500, 591, 500, 378, 375, 502, 439, 485, 453, 222, 369, 500, 332, 324, 500, 552, 302, 502, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 992, 500, 369, 500, 500, 500, 500, 517, 868, 1194, 369, 500, 500, 500, 500, 500, 1157, 500, 500, 500, 200, 500, 500, 300, 653, 1137, 554, ) diff --git a/openerp/pychart/afm/AvantGarde_BookOblique.py b/openerp/pychart/afm/AvantGarde_BookOblique.py deleted file mode 100644 index 1db8aa7dddf..00000000000 --- a/openerp/pychart/afm/AvantGarde_BookOblique.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font AvantGarde-BookOblique (path: /usr/share/fonts/afms/adobe/pagko8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["AvantGarde-BookOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 277, 295, 309, 554, 554, 775, 757, 351, 369, 369, 425, 606, 277, 332, 277, 437, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 277, 277, 606, 606, 606, 591, 867, 740, 574, 813, 744, 536, 485, 872, 683, 226, 482, 591, 462, 919, 740, 869, 592, 871, 607, 498, 426, 655, 702, 960, 609, 592, 480, 351, 605, 351, 606, 500, 351, 683, 682, 647, 685, 650, 314, 673, 610, 200, 203, 502, 200, 938, 610, 655, 682, 682, 301, 388, 339, 608, 554, 831, 480, 536, 425, 351, 672, 351, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 295, 554, 554, 166, 554, 554, 615, 554, 198, 502, 425, 251, 251, 487, 485, 500, 500, 553, 553, 277, 500, 564, 606, 354, 502, 484, 425, 1000, 1174, 500, 591, 500, 378, 375, 502, 439, 485, 453, 222, 369, 500, 332, 324, 500, 552, 302, 502, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 992, 500, 369, 500, 500, 500, 500, 517, 868, 1194, 369, 500, 500, 500, 500, 500, 1157, 500, 500, 500, 200, 500, 500, 300, 653, 1137, 554, ) diff --git a/openerp/pychart/afm/AvantGarde_Demi.py b/openerp/pychart/afm/AvantGarde_Demi.py deleted file mode 100644 index 295b3e7d7c2..00000000000 --- a/openerp/pychart/afm/AvantGarde_Demi.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font AvantGarde-Demi (path: /usr/share/fonts/afms/adobe/pagd8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["AvantGarde-Demi"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 280, 280, 360, 560, 560, 860, 680, 280, 380, 380, 440, 600, 280, 420, 280, 460, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 280, 280, 600, 600, 600, 560, 740, 740, 580, 780, 700, 520, 480, 840, 680, 280, 480, 620, 440, 900, 740, 840, 560, 840, 580, 520, 420, 640, 700, 900, 680, 620, 500, 320, 640, 320, 600, 500, 280, 660, 660, 640, 660, 640, 280, 660, 600, 240, 260, 580, 240, 940, 600, 640, 660, 660, 320, 440, 300, 600, 560, 800, 560, 580, 460, 340, 600, 340, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 280, 560, 560, 160, 560, 560, 560, 560, 220, 480, 460, 240, 240, 520, 520, 500, 500, 560, 560, 280, 500, 600, 600, 280, 480, 480, 460, 1000, 1280, 500, 560, 500, 420, 420, 540, 480, 420, 480, 280, 500, 500, 360, 340, 500, 700, 340, 540, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 900, 500, 360, 500, 500, 500, 500, 480, 840, 1060, 360, 500, 500, 500, 500, 500, 1080, 500, 500, 500, 240, 500, 500, 320, 660, 1080, 600, ) diff --git a/openerp/pychart/afm/AvantGarde_DemiOblique.py b/openerp/pychart/afm/AvantGarde_DemiOblique.py deleted file mode 100644 index 7b6c04feb52..00000000000 --- a/openerp/pychart/afm/AvantGarde_DemiOblique.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font AvantGarde-DemiOblique (path: /usr/share/fonts/afms/adobe/pagdo8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["AvantGarde-DemiOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 280, 280, 360, 560, 560, 860, 680, 280, 380, 380, 440, 600, 280, 420, 280, 460, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 280, 280, 600, 600, 600, 560, 740, 740, 580, 780, 700, 520, 480, 840, 680, 280, 480, 620, 440, 900, 740, 840, 560, 840, 580, 520, 420, 640, 700, 900, 680, 620, 500, 320, 640, 320, 600, 500, 280, 660, 660, 640, 660, 640, 280, 660, 600, 240, 260, 580, 240, 940, 600, 640, 660, 660, 320, 440, 300, 600, 560, 800, 560, 580, 460, 340, 600, 340, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 280, 560, 560, 160, 560, 560, 560, 560, 220, 480, 460, 240, 240, 520, 520, 500, 500, 560, 560, 280, 500, 600, 600, 280, 480, 480, 460, 1000, 1280, 500, 560, 500, 420, 420, 540, 480, 420, 480, 280, 500, 500, 360, 340, 500, 700, 340, 540, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 900, 500, 360, 500, 500, 500, 500, 480, 840, 1060, 360, 500, 500, 500, 500, 500, 1080, 500, 500, 500, 240, 500, 500, 320, 660, 1080, 600, ) diff --git a/openerp/pychart/afm/Bookman_Demi.py b/openerp/pychart/afm/Bookman_Demi.py deleted file mode 100644 index 255593de85e..00000000000 --- a/openerp/pychart/afm/Bookman_Demi.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Bookman-Demi (path: /usr/share/fonts/afms/adobe/pbkd8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Bookman-Demi"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 340, 360, 420, 660, 660, 940, 800, 320, 320, 320, 460, 600, 340, 360, 340, 600, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 340, 340, 600, 600, 600, 660, 820, 720, 720, 740, 780, 720, 680, 780, 820, 400, 640, 800, 640, 940, 740, 800, 660, 800, 780, 660, 700, 740, 720, 940, 780, 700, 640, 300, 600, 300, 600, 500, 320, 580, 600, 580, 640, 580, 380, 580, 680, 360, 340, 660, 340, 1000, 680, 620, 640, 620, 460, 520, 460, 660, 600, 800, 600, 620, 560, 320, 600, 320, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 360, 660, 660, 120, 660, 660, 600, 660, 240, 540, 400, 220, 220, 740, 740, 500, 500, 440, 380, 340, 500, 800, 460, 320, 540, 540, 400, 1000, 1360, 500, 660, 500, 400, 400, 500, 480, 460, 500, 320, 500, 500, 340, 360, 500, 440, 320, 500, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1140, 500, 400, 500, 500, 500, 500, 640, 800, 1220, 400, 500, 500, 500, 500, 500, 880, 500, 500, 500, 360, 500, 500, 340, 620, 940, 660, ) diff --git a/openerp/pychart/afm/Bookman_DemiItalic.py b/openerp/pychart/afm/Bookman_DemiItalic.py deleted file mode 100644 index 865ebd45917..00000000000 --- a/openerp/pychart/afm/Bookman_DemiItalic.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Bookman-DemiItalic (path: /usr/share/fonts/afms/adobe/pbkdi8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Bookman-DemiItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 340, 320, 380, 680, 680, 880, 980, 320, 260, 260, 460, 600, 340, 280, 340, 360, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 340, 340, 620, 600, 620, 620, 780, 720, 720, 700, 760, 720, 660, 760, 800, 380, 620, 780, 640, 860, 740, 760, 640, 760, 740, 700, 700, 740, 660, 1000, 740, 660, 680, 260, 580, 260, 620, 500, 320, 680, 600, 560, 680, 560, 420, 620, 700, 380, 320, 700, 380, 960, 680, 600, 660, 620, 500, 540, 440, 680, 540, 860, 620, 600, 560, 300, 620, 300, 620, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 320, 680, 680, 120, 680, 680, 620, 680, 180, 520, 380, 220, 220, 820, 820, 500, 500, 420, 420, 340, 500, 680, 360, 300, 520, 520, 380, 1000, 1360, 500, 620, 500, 380, 340, 480, 480, 480, 460, 380, 520, 500, 360, 360, 500, 560, 320, 480, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1140, 500, 440, 500, 500, 500, 500, 640, 760, 1180, 440, 500, 500, 500, 500, 500, 880, 500, 500, 500, 380, 500, 500, 380, 600, 920, 660, ) diff --git a/openerp/pychart/afm/Bookman_Light.py b/openerp/pychart/afm/Bookman_Light.py deleted file mode 100644 index 924e2110b7f..00000000000 --- a/openerp/pychart/afm/Bookman_Light.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Bookman-Light (path: /usr/share/fonts/afms/adobe/pbkl8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Bookman-Light"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 320, 300, 380, 620, 620, 900, 800, 220, 300, 300, 440, 600, 320, 400, 320, 600, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 320, 320, 600, 600, 600, 540, 820, 680, 740, 740, 800, 720, 640, 800, 800, 340, 600, 720, 600, 920, 740, 800, 620, 820, 720, 660, 620, 780, 700, 960, 720, 640, 640, 300, 600, 300, 600, 500, 220, 580, 620, 520, 620, 520, 320, 540, 660, 300, 300, 620, 300, 940, 660, 560, 620, 580, 440, 520, 380, 680, 520, 780, 560, 540, 480, 280, 600, 280, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 300, 620, 620, 140, 620, 620, 520, 620, 220, 400, 360, 240, 240, 620, 620, 500, 500, 540, 540, 320, 500, 600, 460, 220, 400, 400, 360, 1000, 1280, 500, 540, 500, 340, 340, 420, 440, 440, 460, 260, 420, 500, 320, 320, 500, 380, 320, 420, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1260, 500, 420, 500, 500, 500, 500, 600, 800, 1240, 420, 500, 500, 500, 500, 500, 860, 500, 500, 500, 300, 500, 500, 320, 560, 900, 660, ) diff --git a/openerp/pychart/afm/Bookman_LightItalic.py b/openerp/pychart/afm/Bookman_LightItalic.py deleted file mode 100644 index 55a3bca71a6..00000000000 --- a/openerp/pychart/afm/Bookman_LightItalic.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Bookman-LightItalic (path: /usr/share/fonts/afms/adobe/pbkli8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Bookman-LightItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 300, 320, 360, 620, 620, 800, 820, 280, 280, 280, 440, 600, 300, 320, 300, 600, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 300, 300, 600, 600, 600, 540, 780, 700, 720, 720, 740, 680, 620, 760, 800, 320, 560, 720, 580, 860, 720, 760, 600, 780, 700, 640, 600, 720, 680, 960, 700, 660, 580, 260, 600, 260, 600, 500, 280, 620, 600, 480, 640, 540, 340, 560, 620, 280, 280, 600, 280, 880, 620, 540, 600, 560, 400, 540, 340, 620, 540, 880, 540, 600, 520, 360, 600, 380, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 320, 620, 620, 20, 620, 620, 620, 620, 200, 440, 300, 180, 180, 640, 660, 500, 500, 620, 620, 300, 500, 620, 460, 320, 480, 440, 300, 1000, 1180, 500, 540, 500, 340, 320, 440, 440, 440, 440, 260, 420, 500, 300, 320, 500, 340, 260, 440, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1220, 500, 440, 500, 500, 500, 500, 580, 760, 1180, 400, 500, 500, 500, 500, 500, 880, 500, 500, 500, 280, 500, 500, 340, 540, 900, 620, ) diff --git a/openerp/pychart/afm/Courier.py b/openerp/pychart/afm/Courier.py deleted file mode 100644 index 66d6aca798d..00000000000 --- a/openerp/pychart/afm/Courier.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Courier (path: /usr/share/fonts/afms/adobe/pcrr8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Courier"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 600, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 500, 600, 500, 500, 500, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 600, 500, 500, 500, 600, 500, 500, 600, 600, 600, 600, ) diff --git a/openerp/pychart/afm/Courier_Bold.py b/openerp/pychart/afm/Courier_Bold.py deleted file mode 100644 index 39575e834da..00000000000 --- a/openerp/pychart/afm/Courier_Bold.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Courier-Bold (path: /usr/share/fonts/afms/adobe/pcrb8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Courier-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 600, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 500, 600, 500, 500, 500, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 600, 500, 500, 500, 600, 500, 500, 600, 600, 600, 600, ) diff --git a/openerp/pychart/afm/Courier_BoldOblique.py b/openerp/pychart/afm/Courier_BoldOblique.py deleted file mode 100644 index 9724375ef1d..00000000000 --- a/openerp/pychart/afm/Courier_BoldOblique.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Courier-BoldOblique (path: /usr/share/fonts/afms/adobe/pcrbo8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Courier-BoldOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 600, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 500, 600, 500, 500, 500, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 600, 500, 500, 500, 600, 500, 500, 600, 600, 600, 600, ) diff --git a/openerp/pychart/afm/Courier_Oblique.py b/openerp/pychart/afm/Courier_Oblique.py deleted file mode 100644 index b95fd09170f..00000000000 --- a/openerp/pychart/afm/Courier_Oblique.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Courier-Oblique (path: /usr/share/fonts/afms/adobe/pcrro8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Courier-Oblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 600, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 500, 600, 500, 500, 500, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 600, 500, 500, 500, 600, 500, 500, 600, 600, 600, 600, ) diff --git a/openerp/pychart/afm/Helvetica.py b/openerp/pychart/afm/Helvetica.py deleted file mode 100644 index 01e829d3be9..00000000000 --- a/openerp/pychart/afm/Helvetica.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Helvetica (path: /usr/share/fonts/afms/adobe/phvr8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Helvetica"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 355, 556, 556, 889, 667, 222, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 222, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 191, 333, 556, 333, 333, 500, 500, 500, 556, 556, 556, 278, 500, 537, 350, 222, 333, 333, 556, 1000, 1000, 500, 611, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 370, 500, 500, 500, 500, 556, 778, 1000, 365, 500, 500, 500, 500, 500, 889, 500, 500, 500, 278, 500, 500, 222, 611, 944, 611, ) diff --git a/openerp/pychart/afm/Helvetica_Bold.py b/openerp/pychart/afm/Helvetica_Bold.py deleted file mode 100644 index b3d3b2175b8..00000000000 --- a/openerp/pychart/afm/Helvetica_Bold.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Helvetica-Bold (path: /usr/share/fonts/afms/adobe/phvb8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Helvetica-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 333, 474, 556, 556, 889, 722, 278, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 278, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 238, 500, 556, 333, 333, 611, 611, 500, 556, 556, 556, 278, 500, 556, 350, 278, 500, 500, 556, 1000, 1000, 500, 611, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 370, 500, 500, 500, 500, 611, 778, 1000, 365, 500, 500, 500, 500, 500, 889, 500, 500, 500, 278, 500, 500, 278, 611, 944, 611, ) diff --git a/openerp/pychart/afm/Helvetica_BoldOblique.py b/openerp/pychart/afm/Helvetica_BoldOblique.py deleted file mode 100644 index c439205c602..00000000000 --- a/openerp/pychart/afm/Helvetica_BoldOblique.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Helvetica-BoldOblique (path: /usr/share/fonts/afms/adobe/phvbo8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Helvetica-BoldOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 333, 474, 556, 556, 889, 722, 278, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 278, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 238, 500, 556, 333, 333, 611, 611, 500, 556, 556, 556, 278, 500, 556, 350, 278, 500, 500, 556, 1000, 1000, 500, 611, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 370, 500, 500, 500, 500, 611, 778, 1000, 365, 500, 500, 500, 500, 500, 889, 500, 500, 500, 278, 500, 500, 278, 611, 944, 611, ) diff --git a/openerp/pychart/afm/Helvetica_Light.py b/openerp/pychart/afm/Helvetica_Light.py deleted file mode 100644 index 7f7eb864d88..00000000000 --- a/openerp/pychart/afm/Helvetica_Light.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Helvetica-Light (path: /usr/share/fonts/afms/adobe/phvl8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Helvetica-Light"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 333, 278, 556, 556, 889, 667, 222, 333, 333, 389, 660, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 660, 660, 660, 500, 800, 667, 667, 722, 722, 611, 556, 778, 722, 278, 500, 667, 556, 833, 722, 778, 611, 778, 667, 611, 556, 722, 611, 889, 611, 611, 611, 333, 278, 333, 660, 500, 222, 556, 611, 556, 611, 556, 278, 611, 556, 222, 222, 500, 222, 833, 556, 556, 611, 611, 333, 500, 278, 556, 500, 722, 500, 500, 500, 333, 222, 333, 660, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 222, 389, 556, 389, 389, 500, 500, 500, 500, 556, 556, 278, 500, 650, 500, 222, 389, 389, 556, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 334, 500, 500, 500, 500, 556, 778, 1000, 334, 500, 500, 500, 500, 500, 889, 500, 500, 500, 222, 500, 500, 222, 556, 944, 500, ) diff --git a/openerp/pychart/afm/Helvetica_LightOblique.py b/openerp/pychart/afm/Helvetica_LightOblique.py deleted file mode 100644 index 5da8c82f48a..00000000000 --- a/openerp/pychart/afm/Helvetica_LightOblique.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Helvetica-LightOblique (path: /usr/share/fonts/afms/adobe/phvlo8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Helvetica-LightOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 333, 278, 556, 556, 889, 667, 222, 333, 333, 389, 660, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 660, 660, 660, 500, 800, 667, 667, 722, 722, 611, 556, 778, 722, 278, 500, 667, 556, 833, 722, 778, 611, 778, 667, 611, 556, 722, 611, 889, 611, 611, 611, 333, 278, 333, 660, 500, 222, 556, 611, 556, 611, 556, 278, 611, 556, 222, 222, 500, 222, 833, 556, 556, 611, 611, 333, 500, 278, 556, 500, 722, 500, 500, 500, 333, 222, 333, 660, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 222, 389, 556, 389, 389, 500, 500, 500, 500, 556, 556, 278, 500, 650, 500, 222, 389, 389, 556, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 334, 500, 500, 500, 500, 556, 778, 1000, 334, 500, 500, 500, 500, 500, 889, 500, 500, 500, 222, 500, 500, 222, 556, 944, 500, ) diff --git a/openerp/pychart/afm/Helvetica_Narrow.py b/openerp/pychart/afm/Helvetica_Narrow.py deleted file mode 100644 index 3c7a78b0704..00000000000 --- a/openerp/pychart/afm/Helvetica_Narrow.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Helvetica-Narrow (path: /usr/share/fonts/afms/adobe/phvr8an.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Helvetica-Narrow"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 228, 228, 291, 456, 456, 729, 547, 182, 273, 273, 319, 479, 228, 273, 228, 228, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 228, 228, 479, 479, 479, 456, 832, 547, 547, 592, 592, 547, 501, 638, 592, 228, 410, 547, 456, 683, 592, 638, 547, 638, 592, 547, 501, 592, 547, 774, 547, 547, 501, 228, 228, 228, 385, 456, 182, 456, 456, 410, 456, 456, 228, 456, 456, 182, 182, 410, 182, 683, 456, 456, 456, 456, 273, 410, 228, 456, 410, 592, 410, 410, 410, 274, 213, 274, 479, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 273, 456, 456, 137, 456, 456, 456, 456, 157, 273, 456, 273, 273, 410, 410, 500, 456, 456, 456, 228, 500, 440, 287, 182, 273, 273, 456, 820, 820, 500, 501, 500, 273, 273, 273, 273, 273, 273, 273, 273, 500, 273, 273, 500, 273, 273, 273, 820, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 820, 500, 303, 500, 500, 500, 500, 456, 638, 820, 299, 500, 500, 500, 500, 500, 729, 500, 500, 500, 228, 500, 500, 182, 501, 774, 501, ) diff --git a/openerp/pychart/afm/Helvetica_Narrow_Bold.py b/openerp/pychart/afm/Helvetica_Narrow_Bold.py deleted file mode 100644 index d96f0648fed..00000000000 --- a/openerp/pychart/afm/Helvetica_Narrow_Bold.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Helvetica-Narrow-Bold (path: /usr/share/fonts/afms/adobe/phvb8an.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Helvetica-Narrow-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 228, 273, 389, 456, 456, 729, 592, 228, 273, 273, 319, 479, 228, 273, 228, 228, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 273, 273, 479, 479, 479, 501, 800, 592, 592, 592, 592, 547, 501, 638, 592, 228, 456, 592, 501, 683, 592, 638, 547, 638, 592, 547, 501, 592, 547, 774, 547, 547, 501, 273, 228, 273, 479, 456, 228, 456, 501, 456, 501, 456, 273, 501, 501, 228, 228, 456, 228, 729, 501, 501, 501, 501, 319, 456, 273, 501, 456, 638, 456, 456, 410, 319, 230, 319, 479, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 273, 456, 456, 137, 456, 456, 456, 456, 195, 410, 456, 273, 273, 501, 501, 500, 456, 456, 456, 228, 500, 456, 287, 228, 410, 410, 456, 820, 820, 500, 501, 500, 273, 273, 273, 273, 273, 273, 273, 273, 500, 273, 273, 500, 273, 273, 273, 820, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 820, 500, 303, 500, 500, 500, 500, 501, 638, 820, 299, 500, 500, 500, 500, 500, 729, 500, 500, 500, 228, 500, 500, 228, 501, 774, 501, ) diff --git a/openerp/pychart/afm/Helvetica_Narrow_BoldOblique.py b/openerp/pychart/afm/Helvetica_Narrow_BoldOblique.py deleted file mode 100644 index 6445397cb2a..00000000000 --- a/openerp/pychart/afm/Helvetica_Narrow_BoldOblique.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Helvetica-Narrow-BoldOblique (path: /usr/share/fonts/afms/adobe/phvbo8an.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Helvetica-Narrow-BoldOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 228, 273, 389, 456, 456, 729, 592, 228, 273, 273, 319, 479, 228, 273, 228, 228, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 273, 273, 479, 479, 479, 501, 800, 592, 592, 592, 592, 547, 501, 638, 592, 228, 456, 592, 501, 683, 592, 638, 547, 638, 592, 547, 501, 592, 547, 774, 547, 547, 501, 273, 228, 273, 479, 456, 228, 456, 501, 456, 501, 456, 273, 501, 501, 228, 228, 456, 228, 729, 501, 501, 501, 501, 319, 456, 273, 501, 456, 638, 456, 456, 410, 319, 230, 319, 479, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 273, 456, 456, 137, 456, 456, 456, 456, 195, 410, 456, 273, 273, 501, 501, 500, 456, 456, 456, 228, 500, 456, 287, 228, 410, 410, 456, 820, 820, 500, 501, 500, 273, 273, 273, 273, 273, 273, 273, 273, 500, 273, 273, 500, 273, 273, 273, 820, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 820, 500, 303, 500, 500, 500, 500, 501, 638, 820, 299, 500, 500, 500, 500, 500, 729, 500, 500, 500, 228, 500, 500, 228, 501, 774, 501, ) diff --git a/openerp/pychart/afm/Helvetica_Narrow_Oblique.py b/openerp/pychart/afm/Helvetica_Narrow_Oblique.py deleted file mode 100644 index 23675c1b3ba..00000000000 --- a/openerp/pychart/afm/Helvetica_Narrow_Oblique.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Helvetica-Narrow-Oblique (path: /usr/share/fonts/afms/adobe/phvro8an.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Helvetica-Narrow-Oblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 228, 228, 291, 456, 456, 729, 547, 182, 273, 273, 319, 479, 228, 273, 228, 228, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 228, 228, 479, 479, 479, 456, 832, 547, 547, 592, 592, 547, 501, 638, 592, 228, 410, 547, 456, 683, 592, 638, 547, 638, 592, 547, 501, 592, 547, 774, 547, 547, 501, 228, 228, 228, 385, 456, 182, 456, 456, 410, 456, 456, 228, 456, 456, 182, 182, 410, 182, 683, 456, 456, 456, 456, 273, 410, 228, 456, 410, 592, 410, 410, 410, 274, 213, 274, 479, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 273, 456, 456, 137, 456, 456, 456, 456, 157, 273, 456, 273, 273, 410, 410, 500, 456, 456, 456, 228, 500, 440, 287, 182, 273, 273, 456, 820, 820, 500, 501, 500, 273, 273, 273, 273, 273, 273, 273, 273, 500, 273, 273, 500, 273, 273, 273, 820, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 820, 500, 303, 500, 500, 500, 500, 456, 638, 820, 299, 500, 500, 500, 500, 500, 729, 500, 500, 500, 228, 500, 500, 182, 501, 774, 501, ) diff --git a/openerp/pychart/afm/Helvetica_Oblique.py b/openerp/pychart/afm/Helvetica_Oblique.py deleted file mode 100644 index 10117189f69..00000000000 --- a/openerp/pychart/afm/Helvetica_Oblique.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Helvetica-Oblique (path: /usr/share/fonts/afms/adobe/phvro8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Helvetica-Oblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 355, 556, 556, 889, 667, 222, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 222, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 191, 333, 556, 333, 333, 500, 500, 500, 556, 556, 556, 278, 500, 537, 350, 222, 333, 333, 556, 1000, 1000, 500, 611, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 370, 500, 500, 500, 500, 556, 778, 1000, 365, 500, 500, 500, 500, 500, 889, 500, 500, 500, 278, 500, 500, 222, 611, 944, 611, ) diff --git a/openerp/pychart/afm/NewCenturySchlbk_Bold.py b/openerp/pychart/afm/NewCenturySchlbk_Bold.py deleted file mode 100644 index f37530e92e8..00000000000 --- a/openerp/pychart/afm/NewCenturySchlbk_Bold.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font NewCenturySchlbk-Bold (path: /usr/share/fonts/afms/adobe/pncb8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["NewCenturySchlbk-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 287, 296, 333, 574, 574, 833, 852, 241, 389, 389, 500, 606, 278, 333, 278, 278, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 278, 278, 606, 606, 606, 500, 747, 759, 778, 778, 833, 759, 722, 833, 870, 444, 648, 815, 722, 981, 833, 833, 759, 833, 815, 667, 722, 833, 759, 981, 722, 722, 667, 389, 606, 389, 606, 500, 241, 611, 648, 556, 667, 574, 389, 611, 685, 370, 352, 667, 352, 963, 685, 611, 667, 648, 519, 500, 426, 685, 611, 889, 611, 611, 537, 389, 606, 389, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 296, 574, 574, 167, 574, 574, 500, 574, 241, 481, 500, 333, 333, 685, 685, 500, 500, 500, 500, 278, 500, 747, 606, 241, 481, 481, 500, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 981, 500, 367, 500, 500, 500, 500, 722, 833, 1000, 367, 500, 500, 500, 500, 500, 870, 500, 500, 500, 370, 500, 500, 352, 611, 907, 611, ) diff --git a/openerp/pychart/afm/NewCenturySchlbk_BoldItalic.py b/openerp/pychart/afm/NewCenturySchlbk_BoldItalic.py deleted file mode 100644 index a5c5c172414..00000000000 --- a/openerp/pychart/afm/NewCenturySchlbk_BoldItalic.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font NewCenturySchlbk-BoldItalic (path: /usr/share/fonts/afms/adobe/pncbi8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["NewCenturySchlbk-BoldItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 287, 333, 400, 574, 574, 889, 889, 259, 407, 407, 500, 606, 287, 333, 287, 278, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 287, 287, 606, 606, 606, 481, 747, 741, 759, 759, 833, 741, 704, 815, 870, 444, 667, 778, 704, 944, 852, 833, 741, 833, 796, 685, 722, 833, 741, 944, 741, 704, 704, 407, 606, 407, 606, 500, 259, 667, 611, 537, 667, 519, 389, 611, 685, 389, 370, 648, 389, 944, 685, 574, 648, 630, 519, 481, 407, 685, 556, 833, 574, 519, 519, 407, 606, 407, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 574, 574, 167, 574, 574, 500, 574, 287, 481, 481, 278, 278, 685, 685, 500, 500, 500, 500, 287, 500, 650, 606, 259, 481, 481, 481, 1000, 1167, 500, 481, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 889, 500, 412, 500, 500, 500, 500, 704, 833, 963, 356, 500, 500, 500, 500, 500, 815, 500, 500, 500, 389, 500, 500, 389, 574, 852, 574, ) diff --git a/openerp/pychart/afm/NewCenturySchlbk_Italic.py b/openerp/pychart/afm/NewCenturySchlbk_Italic.py deleted file mode 100644 index 612a8c60b27..00000000000 --- a/openerp/pychart/afm/NewCenturySchlbk_Italic.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font NewCenturySchlbk-Italic (path: /usr/share/fonts/afms/adobe/pncri8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["NewCenturySchlbk-Italic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 333, 400, 556, 556, 833, 852, 204, 333, 333, 500, 606, 278, 333, 278, 606, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 606, 606, 606, 444, 747, 704, 722, 722, 778, 722, 667, 778, 833, 407, 611, 741, 667, 944, 815, 778, 667, 778, 741, 667, 685, 815, 704, 926, 704, 685, 667, 333, 606, 333, 606, 500, 204, 574, 556, 444, 611, 444, 333, 537, 611, 333, 315, 556, 333, 889, 611, 500, 574, 556, 444, 444, 352, 611, 519, 778, 500, 500, 463, 333, 606, 333, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 500, 556, 278, 389, 426, 333, 333, 611, 611, 500, 500, 500, 500, 278, 500, 650, 606, 204, 389, 389, 426, 1000, 1000, 500, 444, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 870, 500, 422, 500, 500, 500, 500, 667, 778, 981, 372, 500, 500, 500, 500, 500, 722, 500, 500, 500, 333, 500, 500, 333, 500, 778, 556, ) diff --git a/openerp/pychart/afm/NewCenturySchlbk_Roman.py b/openerp/pychart/afm/NewCenturySchlbk_Roman.py deleted file mode 100644 index 010b8c7042a..00000000000 --- a/openerp/pychart/afm/NewCenturySchlbk_Roman.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font NewCenturySchlbk-Roman (path: /usr/share/fonts/afms/adobe/pncr8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["NewCenturySchlbk-Roman"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 296, 389, 556, 556, 833, 815, 204, 333, 333, 500, 606, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 606, 606, 606, 444, 737, 722, 722, 722, 778, 722, 667, 778, 833, 407, 556, 778, 667, 944, 815, 778, 667, 778, 722, 630, 667, 815, 722, 981, 704, 704, 611, 333, 606, 333, 606, 500, 204, 556, 556, 444, 574, 500, 333, 537, 611, 315, 296, 593, 315, 889, 611, 500, 574, 556, 444, 463, 389, 611, 537, 778, 537, 537, 481, 333, 606, 333, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 296, 556, 556, 167, 556, 556, 500, 556, 204, 389, 426, 259, 259, 611, 611, 500, 556, 500, 500, 278, 500, 606, 606, 204, 389, 389, 426, 1000, 1000, 500, 444, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 334, 500, 500, 500, 500, 667, 778, 1000, 300, 500, 500, 500, 500, 500, 796, 500, 500, 500, 315, 500, 500, 315, 500, 833, 574, ) diff --git a/openerp/pychart/afm/Palatino_Bold.py b/openerp/pychart/afm/Palatino_Bold.py deleted file mode 100644 index cd0394bdd69..00000000000 --- a/openerp/pychart/afm/Palatino_Bold.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Palatino-Bold (path: /usr/share/fonts/afms/adobe/pplb8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Palatino-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 278, 402, 500, 500, 889, 833, 278, 333, 333, 444, 606, 250, 333, 250, 296, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 250, 606, 606, 606, 444, 747, 778, 667, 722, 833, 611, 556, 833, 833, 389, 389, 778, 611, 1000, 833, 833, 611, 833, 722, 611, 667, 778, 778, 1000, 667, 667, 667, 333, 606, 333, 606, 500, 278, 500, 611, 444, 611, 500, 389, 556, 611, 333, 333, 611, 333, 889, 611, 556, 611, 611, 389, 444, 333, 611, 556, 833, 500, 556, 500, 310, 606, 310, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 500, 500, 167, 500, 500, 500, 500, 227, 500, 500, 389, 389, 611, 611, 500, 500, 500, 500, 250, 500, 641, 606, 333, 500, 500, 500, 1000, 1000, 500, 444, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 438, 500, 500, 500, 500, 611, 833, 1000, 488, 500, 500, 500, 500, 500, 778, 500, 500, 500, 333, 500, 500, 333, 556, 833, 611, ) diff --git a/openerp/pychart/afm/Palatino_BoldItalic.py b/openerp/pychart/afm/Palatino_BoldItalic.py deleted file mode 100644 index dbea3e12343..00000000000 --- a/openerp/pychart/afm/Palatino_BoldItalic.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Palatino-BoldItalic (path: /usr/share/fonts/afms/adobe/pplbi8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Palatino-BoldItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 500, 500, 500, 889, 833, 278, 333, 333, 444, 606, 250, 389, 250, 315, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 250, 606, 606, 606, 444, 833, 722, 667, 685, 778, 611, 556, 778, 778, 389, 389, 722, 611, 944, 778, 833, 667, 833, 722, 556, 611, 778, 667, 1000, 722, 611, 667, 333, 606, 333, 606, 500, 278, 556, 537, 444, 556, 444, 333, 500, 556, 333, 333, 556, 333, 833, 556, 556, 556, 537, 389, 444, 389, 556, 556, 833, 500, 556, 500, 333, 606, 333, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 500, 500, 167, 500, 500, 556, 500, 250, 500, 500, 333, 333, 611, 611, 500, 500, 556, 556, 250, 500, 556, 606, 250, 500, 500, 500, 1000, 1000, 500, 444, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 556, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 944, 500, 333, 500, 500, 500, 500, 611, 833, 944, 333, 500, 500, 500, 500, 500, 738, 500, 500, 500, 333, 500, 500, 333, 556, 778, 556, ) diff --git a/openerp/pychart/afm/Palatino_Italic.py b/openerp/pychart/afm/Palatino_Italic.py deleted file mode 100644 index e9618f5ade2..00000000000 --- a/openerp/pychart/afm/Palatino_Italic.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Palatino-Italic (path: /usr/share/fonts/afms/adobe/pplri8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Palatino-Italic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 500, 500, 500, 889, 778, 278, 333, 333, 389, 606, 250, 333, 250, 296, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 250, 606, 606, 606, 500, 747, 722, 611, 667, 778, 611, 556, 722, 778, 333, 333, 667, 556, 944, 778, 778, 611, 778, 667, 556, 611, 778, 722, 944, 722, 667, 667, 333, 606, 333, 606, 500, 278, 444, 463, 407, 500, 389, 278, 500, 500, 278, 278, 444, 278, 778, 556, 444, 500, 463, 389, 389, 333, 556, 500, 722, 500, 500, 444, 333, 606, 333, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 500, 500, 167, 500, 500, 500, 500, 333, 500, 500, 333, 333, 528, 545, 500, 500, 500, 500, 250, 500, 500, 500, 278, 500, 500, 500, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 941, 500, 333, 500, 500, 500, 500, 556, 778, 1028, 333, 500, 500, 500, 500, 500, 638, 500, 500, 500, 278, 500, 500, 278, 444, 669, 500, ) diff --git a/openerp/pychart/afm/Palatino_Roman.py b/openerp/pychart/afm/Palatino_Roman.py deleted file mode 100644 index c846b9ad9ba..00000000000 --- a/openerp/pychart/afm/Palatino_Roman.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Palatino-Roman (path: /usr/share/fonts/afms/adobe/pplr8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Palatino-Roman"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 278, 371, 500, 500, 840, 778, 278, 333, 333, 389, 606, 250, 333, 250, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 250, 606, 606, 606, 444, 747, 778, 611, 709, 774, 611, 556, 763, 832, 337, 333, 726, 611, 946, 831, 786, 604, 786, 668, 525, 613, 778, 722, 1000, 667, 667, 667, 333, 606, 333, 606, 500, 278, 500, 553, 444, 611, 479, 333, 556, 582, 291, 234, 556, 291, 883, 582, 546, 601, 560, 395, 424, 326, 603, 565, 834, 516, 556, 500, 333, 606, 333, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 500, 500, 167, 500, 500, 500, 500, 208, 500, 500, 331, 331, 605, 608, 500, 500, 500, 500, 250, 500, 628, 606, 278, 500, 500, 500, 1000, 1144, 500, 444, 500, 333, 333, 333, 333, 333, 333, 250, 333, 500, 333, 333, 500, 380, 313, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 944, 500, 333, 500, 500, 500, 500, 611, 833, 998, 333, 500, 500, 500, 500, 500, 758, 500, 500, 500, 287, 500, 500, 291, 556, 827, 556, ) diff --git a/openerp/pychart/afm/Symbol.py b/openerp/pychart/afm/Symbol.py deleted file mode 100644 index 9ddd708a8df..00000000000 --- a/openerp/pychart/afm/Symbol.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Symbol (path: /usr/share/fonts/afms/adobe/psyr.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Symbol"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 713, 500, 549, 833, 778, 439, 333, 333, 500, 549, 250, 549, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 549, 549, 549, 444, 549, 722, 667, 722, 612, 611, 763, 603, 722, 333, 631, 722, 686, 889, 722, 722, 768, 741, 556, 592, 611, 690, 439, 768, 645, 795, 611, 333, 863, 333, 658, 500, 500, 631, 549, 549, 494, 439, 521, 411, 603, 329, 603, 549, 549, 576, 521, 549, 549, 521, 549, 603, 439, 576, 713, 686, 493, 686, 494, 480, 200, 480, 549, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 620, 247, 549, 167, 713, 500, 753, 753, 753, 753, 1042, 987, 603, 987, 603, 400, 549, 411, 549, 549, 713, 494, 460, 549, 549, 549, 549, 1000, 603, 1000, 658, 823, 686, 795, 987, 768, 768, 823, 768, 768, 713, 713, 713, 713, 713, 713, 713, 768, 713, 790, 790, 890, 823, 549, 250, 713, 603, 603, 1042, 987, 603, 987, 603, 494, 329, 790, 790, 786, 713, 384, 384, 384, 384, 384, 384, 494, 494, 494, 494, 500, 329, 274, 686, 686, 686, 384, 384, 384, 384, 384, 384, 494, 494, 494, ) diff --git a/openerp/pychart/afm/Times_Bold.py b/openerp/pychart/afm/Times_Bold.py deleted file mode 100644 index c966cfc6c6c..00000000000 --- a/openerp/pychart/afm/Times_Bold.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Times-Bold (path: /usr/share/fonts/afms/adobe/ptmb8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Times-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 555, 500, 500, 1000, 833, 333, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 930, 722, 667, 722, 722, 667, 611, 778, 778, 389, 500, 778, 667, 944, 722, 778, 611, 778, 722, 556, 667, 722, 722, 1000, 722, 722, 667, 333, 278, 333, 581, 500, 333, 500, 556, 444, 556, 444, 333, 500, 556, 278, 333, 556, 278, 833, 556, 500, 556, 556, 444, 389, 333, 556, 500, 722, 500, 500, 444, 394, 220, 394, 520, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 500, 500, 167, 500, 500, 500, 500, 278, 500, 500, 333, 333, 556, 556, 500, 500, 500, 500, 250, 500, 540, 350, 333, 500, 500, 500, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 300, 500, 500, 500, 500, 667, 778, 1000, 330, 500, 500, 500, 500, 500, 722, 500, 500, 500, 278, 500, 500, 278, 500, 722, 556, ) diff --git a/openerp/pychart/afm/Times_BoldItalic.py b/openerp/pychart/afm/Times_BoldItalic.py deleted file mode 100644 index 75b0c316128..00000000000 --- a/openerp/pychart/afm/Times_BoldItalic.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Times-BoldItalic (path: /usr/share/fonts/afms/adobe/ptmbi8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Times-BoldItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 389, 555, 500, 500, 833, 778, 333, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 832, 667, 667, 667, 722, 667, 667, 722, 778, 389, 500, 667, 611, 889, 722, 722, 611, 722, 667, 556, 611, 722, 667, 889, 667, 611, 611, 333, 278, 333, 570, 500, 333, 500, 500, 444, 500, 444, 333, 500, 556, 278, 278, 500, 278, 778, 556, 500, 500, 500, 389, 389, 278, 556, 444, 667, 500, 444, 389, 348, 220, 348, 570, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 389, 500, 500, 167, 500, 500, 500, 500, 278, 500, 500, 333, 333, 556, 556, 500, 500, 500, 500, 250, 500, 500, 350, 333, 500, 500, 500, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 944, 500, 266, 500, 500, 500, 500, 611, 722, 944, 300, 500, 500, 500, 500, 500, 722, 500, 500, 500, 278, 500, 500, 278, 500, 722, 500, ) diff --git a/openerp/pychart/afm/Times_Italic.py b/openerp/pychart/afm/Times_Italic.py deleted file mode 100644 index c057c8ff2b7..00000000000 --- a/openerp/pychart/afm/Times_Italic.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Times-Italic (path: /usr/share/fonts/afms/adobe/ptmri8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Times-Italic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 420, 500, 500, 833, 778, 333, 333, 333, 500, 675, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 675, 675, 675, 500, 920, 611, 611, 667, 722, 611, 611, 722, 722, 333, 444, 667, 556, 833, 667, 722, 611, 722, 611, 500, 556, 722, 611, 833, 611, 556, 556, 389, 278, 389, 422, 500, 333, 500, 500, 444, 500, 444, 278, 500, 500, 278, 278, 444, 278, 722, 500, 500, 500, 500, 389, 389, 278, 500, 444, 667, 444, 444, 389, 400, 275, 400, 541, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 389, 500, 500, 167, 500, 500, 500, 500, 214, 556, 500, 333, 333, 500, 500, 500, 500, 500, 500, 250, 500, 523, 350, 333, 556, 556, 500, 889, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 889, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 889, 500, 276, 500, 500, 500, 500, 556, 722, 944, 310, 500, 500, 500, 500, 500, 667, 500, 500, 500, 278, 500, 500, 278, 500, 667, 500, ) diff --git a/openerp/pychart/afm/Times_Roman.py b/openerp/pychart/afm/Times_Roman.py deleted file mode 100644 index b2eb7a0bb90..00000000000 --- a/openerp/pychart/afm/Times_Roman.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Times-Roman (path: /usr/share/fonts/afms/adobe/ptmr8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Times-Roman"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 408, 500, 500, 833, 778, 333, 333, 333, 500, 564, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 564, 564, 564, 444, 921, 722, 667, 667, 722, 611, 556, 722, 722, 333, 389, 722, 611, 889, 722, 722, 556, 722, 667, 556, 611, 722, 722, 944, 722, 722, 611, 333, 278, 333, 469, 500, 333, 444, 500, 444, 500, 444, 333, 500, 500, 278, 278, 500, 278, 778, 500, 500, 500, 500, 333, 389, 278, 500, 500, 722, 500, 500, 444, 480, 200, 480, 541, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 500, 500, 167, 500, 500, 500, 500, 180, 444, 500, 333, 333, 556, 556, 500, 500, 500, 500, 250, 500, 453, 350, 333, 444, 444, 500, 1000, 1000, 500, 444, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 889, 500, 276, 500, 500, 500, 500, 611, 722, 889, 310, 500, 500, 500, 500, 500, 667, 500, 500, 500, 278, 500, 500, 278, 500, 722, 500, ) diff --git a/openerp/pychart/afm/Utopia_Bold.py b/openerp/pychart/afm/Utopia_Bold.py deleted file mode 100644 index d7f5cd519ae..00000000000 --- a/openerp/pychart/afm/Utopia_Bold.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Utopia-Bold (path: /usr/share/fonts/afms/adobe/putb8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Utopia-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 210, 278, 473, 560, 560, 887, 748, 252, 365, 365, 442, 600, 280, 392, 280, 378, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 280, 280, 600, 600, 600, 456, 833, 644, 683, 689, 777, 629, 593, 726, 807, 384, 386, 707, 585, 918, 739, 768, 650, 768, 684, 561, 624, 786, 645, 933, 634, 617, 614, 335, 379, 335, 600, 500, 252, 544, 605, 494, 605, 519, 342, 533, 631, 316, 316, 582, 309, 948, 638, 585, 615, 597, 440, 446, 370, 629, 520, 774, 522, 524, 483, 365, 284, 365, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 560, 560, 100, 560, 560, 566, 560, 252, 473, 487, 287, 287, 639, 639, 500, 500, 510, 486, 280, 500, 552, 455, 252, 473, 473, 487, 1000, 1289, 500, 456, 500, 430, 430, 430, 430, 430, 430, 430, 430, 500, 430, 430, 500, 430, 430, 430, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 879, 500, 405, 500, 500, 500, 500, 591, 768, 1049, 427, 500, 500, 500, 500, 500, 806, 500, 500, 500, 316, 500, 500, 321, 585, 866, 662, ) diff --git a/openerp/pychart/afm/Utopia_BoldItalic.py b/openerp/pychart/afm/Utopia_BoldItalic.py deleted file mode 100644 index f29af4a95f4..00000000000 --- a/openerp/pychart/afm/Utopia_BoldItalic.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Utopia-BoldItalic (path: /usr/share/fonts/afms/adobe/putbi8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Utopia-BoldItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 210, 285, 455, 560, 560, 896, 752, 246, 350, 350, 500, 600, 280, 392, 280, 260, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 280, 280, 600, 600, 600, 454, 828, 634, 680, 672, 774, 622, 585, 726, 800, 386, 388, 688, 586, 921, 741, 761, 660, 761, 681, 551, 616, 776, 630, 920, 630, 622, 618, 350, 460, 350, 600, 500, 246, 596, 586, 456, 609, 476, 348, 522, 629, 339, 333, 570, 327, 914, 635, 562, 606, 584, 440, 417, 359, 634, 518, 795, 516, 489, 466, 340, 265, 340, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 285, 560, 560, 100, 560, 560, 568, 560, 246, 455, 560, 360, 360, 651, 652, 500, 500, 514, 490, 280, 500, 580, 465, 246, 455, 455, 560, 1000, 1297, 500, 454, 500, 400, 400, 400, 400, 400, 400, 402, 400, 500, 400, 400, 500, 400, 350, 400, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 890, 500, 444, 500, 500, 500, 500, 592, 761, 1016, 412, 500, 500, 500, 500, 500, 789, 500, 500, 500, 339, 500, 500, 339, 562, 811, 628, ) diff --git a/openerp/pychart/afm/Utopia_Italic.py b/openerp/pychart/afm/Utopia_Italic.py deleted file mode 100644 index 33eb26837d8..00000000000 --- a/openerp/pychart/afm/Utopia_Italic.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Utopia-Italic (path: /usr/share/fonts/afms/adobe/putri8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Utopia-Italic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 225, 240, 402, 530, 530, 826, 725, 216, 350, 350, 412, 570, 265, 392, 265, 270, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 265, 265, 570, 570, 570, 425, 794, 624, 632, 661, 763, 596, 571, 709, 775, 345, 352, 650, 565, 920, 763, 753, 614, 753, 640, 533, 606, 794, 637, 946, 632, 591, 622, 330, 390, 330, 570, 500, 216, 561, 559, 441, 587, 453, 315, 499, 607, 317, 309, 545, 306, 912, 618, 537, 590, 559, 402, 389, 341, 618, 510, 785, 516, 468, 468, 340, 270, 340, 570, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 240, 530, 530, 100, 530, 530, 530, 530, 216, 402, 462, 277, 277, 607, 603, 500, 500, 500, 490, 265, 500, 560, 500, 216, 402, 402, 462, 1000, 1200, 500, 425, 500, 400, 400, 400, 400, 400, 400, 402, 400, 500, 400, 400, 500, 400, 350, 400, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 880, 500, 425, 500, 500, 500, 500, 571, 753, 1020, 389, 500, 500, 500, 500, 500, 779, 500, 500, 500, 317, 500, 500, 318, 537, 806, 577, ) diff --git a/openerp/pychart/afm/Utopia_Regular.py b/openerp/pychart/afm/Utopia_Regular.py deleted file mode 100644 index 0a61b2ee497..00000000000 --- a/openerp/pychart/afm/Utopia_Regular.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font Utopia-Regular (path: /usr/share/fonts/afms/adobe/putr8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["Utopia-Regular"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 225, 242, 458, 530, 530, 838, 706, 278, 350, 350, 412, 570, 265, 392, 265, 460, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 265, 265, 570, 570, 570, 389, 793, 635, 646, 684, 779, 606, 580, 734, 798, 349, 350, 658, 568, 944, 780, 762, 600, 762, 644, 541, 621, 791, 634, 940, 624, 588, 610, 330, 460, 330, 570, 500, 278, 523, 598, 496, 598, 514, 319, 520, 607, 291, 280, 524, 279, 923, 619, 577, 608, 591, 389, 436, 344, 606, 504, 768, 486, 506, 480, 340, 228, 340, 570, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 242, 530, 530, 150, 530, 530, 554, 530, 278, 458, 442, 257, 257, 610, 610, 500, 500, 504, 488, 265, 500, 555, 409, 278, 458, 458, 442, 1000, 1208, 500, 389, 500, 400, 400, 400, 400, 400, 400, 400, 400, 500, 400, 400, 500, 400, 400, 400, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 876, 500, 390, 500, 500, 500, 500, 574, 762, 1025, 398, 500, 500, 500, 500, 500, 797, 500, 500, 500, 291, 500, 500, 294, 577, 882, 601, ) diff --git a/openerp/pychart/afm/ZapfChancery_MediumItalic.py b/openerp/pychart/afm/ZapfChancery_MediumItalic.py deleted file mode 100644 index 86622dad380..00000000000 --- a/openerp/pychart/afm/ZapfChancery_MediumItalic.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font ZapfChancery-MediumItalic (path: /usr/share/fonts/afms/adobe/pzcmi8a.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["ZapfChancery-MediumItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 220, 280, 220, 440, 440, 680, 780, 240, 260, 220, 420, 520, 220, 280, 220, 340, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 260, 240, 520, 520, 520, 380, 700, 620, 600, 520, 700, 620, 580, 620, 680, 380, 400, 660, 580, 840, 700, 600, 540, 600, 600, 460, 500, 740, 640, 880, 560, 560, 620, 240, 480, 320, 520, 500, 240, 420, 420, 340, 440, 340, 320, 400, 440, 240, 220, 440, 240, 620, 460, 400, 440, 400, 300, 320, 320, 460, 440, 680, 420, 400, 440, 240, 520, 240, 520, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 280, 440, 440, 60, 440, 440, 420, 440, 160, 340, 340, 240, 260, 520, 520, 500, 500, 460, 480, 220, 500, 500, 600, 180, 280, 360, 380, 1000, 960, 500, 400, 500, 220, 300, 340, 440, 440, 440, 220, 360, 500, 300, 300, 500, 400, 280, 340, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 740, 500, 260, 500, 500, 500, 500, 580, 660, 820, 260, 500, 500, 500, 500, 500, 540, 500, 500, 500, 240, 500, 500, 300, 440, 560, 420, ) diff --git a/openerp/pychart/afm/ZapfDingbats.py b/openerp/pychart/afm/ZapfDingbats.py deleted file mode 100644 index acdfcd3b178..00000000000 --- a/openerp/pychart/afm/ZapfDingbats.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# AFM font ZapfDingbats (path: /usr/share/fonts/afms/adobe/pzdr.afm). -# Derived from Ghostscript distribution. -# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code. -import dir -dir.afm["ZapfDingbats"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 974, 961, 974, 980, 719, 789, 790, 791, 690, 960, 939, 549, 855, 911, 933, 911, 945, 974, 755, 846, 762, 761, 571, 677, 763, 760, 759, 754, 494, 552, 537, 577, 692, 786, 788, 788, 790, 793, 794, 816, 823, 789, 841, 823, 833, 816, 831, 923, 744, 723, 749, 790, 792, 695, 776, 768, 792, 759, 707, 708, 682, 701, 826, 815, 789, 789, 707, 687, 696, 689, 786, 787, 713, 791, 785, 791, 873, 761, 762, 762, 759, 759, 892, 892, 788, 784, 438, 138, 277, 415, 392, 392, 668, 668, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 732, 544, 544, 910, 667, 760, 760, 776, 595, 694, 626, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 894, 838, 1016, 458, 748, 924, 748, 918, 927, 928, 928, 834, 873, 828, 924, 924, 917, 930, 931, 463, 883, 836, 836, 867, 867, 696, 696, 874, 500, 874, 760, 946, 771, 865, 771, 888, 967, 888, 831, 873, 927, 970, 918, ) diff --git a/openerp/pychart/afm/__init__.py b/openerp/pychart/afm/__init__.py deleted file mode 100644 index 83ce5c3234b..00000000000 --- a/openerp/pychart/afm/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -############################################################################## - -__all__ = ["Courier_Oblique", "AvantGarde_BookOblique", "Times_Italic", "Helvetica_Bold", "NewCenturySchlbk_Roman", "Helvetica", "Helvetica_Narrow", "AvantGarde_Demi", "Times_BoldItalic", "Helvetica_Narrow_Bold", "Helvetica_Light", "Bookman_DemiItalic", "Utopia_Regular", "Times_Roman", "Palatino_Italic", "Courier_Bold", "ZapfChancery_MediumItalic", "NewCenturySchlbk_Italic", "NewCenturySchlbk_BoldItalic", "Helvetica_Narrow_BoldOblique", "Courier", "AvantGarde_DemiOblique", "Courier_BoldOblique", "Bookman_LightItalic", "Symbol", "Utopia_Bold", "Times_Bold", "Helvetica_BoldOblique", "Utopia_BoldItalic", "AvantGarde_Book", "Bookman_Demi", "Palatino_Roman", "Bookman_Light", "Utopia_Italic", "NewCenturySchlbk_Bold", "Helvetica_LightOblique", "ZapfDingbats", "Helvetica_Narrow_Oblique", "Helvetica_Oblique", "Palatino_BoldItalic", "Palatino_Bold", "dir"] diff --git a/openerp/pychart/afm/dir.py b/openerp/pychart/afm/dir.py deleted file mode 100644 index e48804e6a88..00000000000 --- a/openerp/pychart/afm/dir.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -afm = {} - diff --git a/openerp/pychart/area.py b/openerp/pychart/area.py deleted file mode 100644 index 0f714d068d8..00000000000 --- a/openerp/pychart/area.py +++ /dev/null @@ -1,250 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import coord -import line_style -import legend -import axis -import pychart_util -import chart_object -import fill_style -import canvas -import area_doc -import linear_coord -import category_coord -import theme -from pychart_types import * -from types import * - -_dummy_legend = legend.T() - -def range_doc(t): - u = t.upper() - - return """Specifies the range of %s values that are displayed in the - chart. IF the value is None, both the values are computed - automatically from the samples. Otherwise, the value must be a - tuple of format (MIN, MAX). MIN and MAX must be either None or a - number. If None, the value is computed automatically from the - samples. For example, if %s_range = (None,5), then the minimum %s - value is computed automatically, but the maximum %s value is fixed - at 5.""" % (u, t, u, u) - -_keys = { - "loc" : (CoordType, (0,0), - """The location of the bottom-left corner of the chart. -@cindex chart location -@cindex location, chart -"""), - "size" : (CoordType, (120,110), - """The size of the chart-drawing area, excluding axis labels, - legends, tick marks, etc. -@cindex chart size -@cindex size, chart - """), - "bg_style": (fill_style.T, None, "Background fill-pattern."), - "border_line_style": (line_style.T, None, "Line style of the outer frame of the chart."), - "x_coord": - (coord.T, linear_coord.T(), - """Set the X coordinate system.""", - """A linear coordinate system."""), - "y_coord": (coord.T, linear_coord.T(), - "Set the Y coordinate system.", - """A linear coordinate system."""), - "x_range": (CoordType, None, range_doc("x")), - "y_range": (CoordType, None, range_doc("y")), - "x_axis": (axis.X, None, "The X axis. <<axis>>."), - "x_axis2": (axis.X, None, """The second X axis. This axis should be non-None either when you want to display plots with two distinct domains or when - you just want to display two axes at the top and bottom of the chart. - <<axis>>"""), - "y_axis": (axis.Y, None, "The Y axis. <<axis>>."), - "y_axis2": (axis.Y, None, - """The second Y axis. This axis should be non-None either when you want to display plots with two distinct ranges or when - you just want to display two axes at the left and right of the chart. <<axis>>"""), - "x_grid_style" : (line_style.T, None, - """The style of horizontal grid lines. -@cindex grid lines"""), - "y_grid_style" : (line_style.T, line_style.gray70_dash3, - "The style of vertical grid lines."), - "x_grid_interval": (IntervalType, None, - """The horizontal grid-line interval. - A numeric value - specifies the interval at which - lines are drawn. If value is a function, it - takes two arguments, (MIN, MAX), that tells - the minimum and maximum values found in the - sample data. The function should return a list - of values at which lines are drawn."""), - "y_grid_interval": (IntervalType, None, - "The vertical grid-line interval. See also x_grid_interval"), - "x_grid_over_plot": (IntType, False, - "If True, grid lines are drawn over plots. Otherwise, plots are drawn over grid lines."), - "y_grid_over_plot": (IntType, False, "See x_grid_over_plot."), - "plots": (ListType, pychart_util.new_list, - """Used only internally by pychart."""), - "legend": (legend.T, _dummy_legend, "The legend of the chart.", - """a legend is by default displayed - in the right-center of the chart."""), - } - - -class T(chart_object.T): - keys = _keys - __doc__ = area_doc.doc -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def x_pos(self, xval): - "Return the x position (on the canvas) corresponding to XVAL." - off = self.x_coord.get_canvas_pos(self.size[0], xval, - self.x_range[0], self.x_range[1]) - return self.loc[0] + off - - def y_pos(self, yval): - "Return the y position (on the canvas) corresponding to YVAL." - off = self.y_coord.get_canvas_pos(self.size[1], yval, - self.y_range[0], self.y_range[1]) - return self.loc[1] + off - - def x_tic_points(self, interval): - "Return the list of X values for which tick marks and grid lines are drawn." - if type(interval) == FunctionType: - return apply(interval, self.x_range) - - return self.x_coord.get_tics(self.x_range[0], self.x_range[1], interval) - def y_tic_points(self, interval): - "Return the list of Y values for which tick marks and grid lines are drawn." - if type(interval) == FunctionType: - return apply(interval, self.y_range) - - return self.y_coord.get_tics(self.y_range[0], self.y_range[1], interval) - def __draw_x_grid_and_axis(self, can): - if self.x_grid_style: - for i in self.x_tic_points(self.x_grid_interval): - x = self.x_pos(i) - if x > self.loc[0]: - can.line(self.x_grid_style, - x, self.loc[1], x, self.loc[1]+self.size[1]) - if self.x_axis: - self.x_axis.draw(self, can) - if self.x_axis2: - self.x_axis2.draw(self, can) - def __draw_y_grid_and_axis(self, can): - if self.y_grid_style: - for i in self.y_tic_points(self.y_grid_interval): - y = self.y_pos(i) - if y > self.loc[1]: - can.line(self.y_grid_style, - self.loc[0], y, - self.loc[0]+self.size[0], y) - if self.y_axis: - self.y_axis.draw(self, can) - if self.y_axis2: - self.y_axis2.draw(self, can) - - def __get_data_range(self, r, which, coord, interval): - if isinstance(coord, category_coord.T): - # This info is unused for the category coord type. - # So I just return a random value. - return ((0,0), 1) - - r = r or (None, None) - - if len(self.plots) == 0: - raise ValueError, "No chart to draw, and no data range specified.\n"; - dmin, dmax = 999999, -999999 - - for plot in self.plots: - this_min, this_max = plot.get_data_range(which) - dmin = min(this_min, dmin) - dmax = max(this_max, dmax) - - if interval and type(interval) == FunctionType: - tics = apply(interval, (dmin, dmax)) - dmin = tics[0] - dmax = tics[len(tics)-1] - else: - dmin, dmax, interval = coord.get_min_max(dmin, dmax, interval) - - if r[0] != None: - dmin = r[0] - if r[1] != None: - dmax = r[1] - return ((dmin, dmax), interval) - def draw(self, can = None): - "Draw the charts." - - if can == None: - can = canvas.default_canvas() - - self.type_check() - for plot in self.plots: - plot.check_integrity() - - self.x_range, self.x_grid_interval = \ - self.__get_data_range(self.x_range, 'X', - self.x_coord, - self.x_grid_interval) - - self.y_range, self.y_grid_interval = \ - self.__get_data_range(self.y_range, 'Y', - self.y_coord, - self.y_grid_interval) - - can.rectangle(self.border_line_style, self.bg_style, - self.loc[0], self.loc[1], - self.loc[0] + self.size[0], self.loc[1] + self.size[1]) - - if not self.x_grid_over_plot: - self.__draw_x_grid_and_axis(can) - - if not self.y_grid_over_plot: - self.__draw_y_grid_and_axis(can) - - clipbox = theme.adjust_bounding_box([self.loc[0], self.loc[1], - self.loc[0] + self.size[0], - self.loc[1] + self.size[1]]) - - can.clip(clipbox[0], clipbox[1], - clipbox[2], clipbox[3]) - - for plot in self.plots: - plot.draw(self, can) - - can.endclip() - - if self.x_grid_over_plot: - self.__draw_x_grid_and_axis(can) - if self.y_grid_over_plot: - self.__draw_y_grid_and_axis(can) - - if self.legend == _dummy_legend: - self.legend = legend.T() - - if self.legend: - legends = [] - for plot in self.plots: - entry = plot.get_legend_entry() - if entry == None: - pass - elif type(entry) != ListType: - legends.append(entry) - else: - for e in entry: - legends.append(e) - self.legend.draw(self, legends, can) - - def add_plot(self, *plots): - "Add PLOTS... to the area." - self.plots.extend(plots) diff --git a/openerp/pychart/area_doc.py b/openerp/pychart/area_doc.py deleted file mode 100644 index a23e71bc31f..00000000000 --- a/openerp/pychart/area_doc.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -plots(type:list) default="Used only internally by pychart.". -loc(type:(x,y)) default="The location of the bottom-left corner of the chart. -@cindex chart location -@cindex location, chart -". -y_grid_style(type:line_style.T) default="The style of vertical grid lines.". -y_grid_interval(type:Number or function) default="The vertical grid-line interval. See also x_grid_interval". -x_grid_over_plot(type:int) default="If True, grid lines are drawn over plots. Otherwise, plots are drawn over grid lines.". -x_range(type:(x,y)) default="Specifies the range of X values that are displayed in the - chart. IF the value is None, both the values are computed - automatically from the samples. Otherwise, the value must be a - tuple of format (MIN, MAX). MIN and MAX must be either None or a - number. If None, the value is computed automatically from the - samples. For example, if x_range = (None,5), then the minimum X - value is computed automatically, but the maximum X value is fixed - at 5.". -y_coord(type:coord.T) default="Set the Y coordinate system.". - A linear coordinate system. - -y_range(type:(x,y)) default="Specifies the range of Y values that are displayed in the - chart. IF the value is None, both the values are computed - automatically from the samples. Otherwise, the value must be a - tuple of format (MIN, MAX). MIN and MAX must be either None or a - number. If None, the value is computed automatically from the - samples. For example, if y_range = (None,5), then the minimum Y - value is computed automatically, but the maximum Y value is fixed - at 5.". -x_axis(type:axis.X) default="The X axis. <<axis>>.". -bg_style(type:fill_style.T) default="Background fill-pattern.". -x_coord(type:coord.T) default="Set the X coordinate system.". - A linear coordinate system. - -legend(type:legend.T) default="The legend of the chart.". - a legend is by default displayed in the right-center of the - chart. - -y_grid_over_plot(type:int) default="See x_grid_over_plot.". -x_axis2(type:axis.X) default="The second X axis. This axis should be non-None either when you want to display plots with two distinct domains or when - you just want to display two axes at the top and bottom of the chart. - <<axis>>". -y_axis2(type:axis.Y) default="The second Y axis. This axis should be non-None either when you want to display plots with two distinct ranges or when - you just want to display two axes at the left and right of the chart. <<axis>>". -x_grid_style(type:line_style.T) default="The style of horizontal grid lines. -@cindex grid lines". -y_axis(type:axis.Y) default="The Y axis. <<axis>>.". -border_line_style(type:line_style.T) default="Line style of the outer frame of the chart.". -x_grid_interval(type:Number or function) default="The horizontal grid-line interval. - A numeric value - specifies the interval at which - lines are drawn. If value is a function, it - takes two arguments, (MIN, MAX), that tells - the minimum and maximum values found in the - sample data. The function should return a list - of values at which lines are drawn.". -size(type:(x,y)) default="The size of the chart-drawing area, excluding axis labels, - legends, tick marks, etc. -@cindex chart size -@cindex size, chart - ". -""" - diff --git a/openerp/pychart/arrow.py b/openerp/pychart/arrow.py deleted file mode 100644 index 4271c36f66b..00000000000 --- a/openerp/pychart/arrow.py +++ /dev/null @@ -1,185 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import line_style -import color -import chart_object -import object_set -import math -import arrow_doc -import canvas - -from pychart_types import * -from types import * -from scaling import * - -__doc__ = """ -Arrow is an optional component of a chart that draws line segments with -an arrowhead. To draw an arrow, one creates an arrow.T object, and calls -its "draw" method usually after area.draw() is called (otherwise, area.draw() -may overwrite the arrow). For example, the below code draws an arrow -from (10,10) to (20,30). - -ar = area.T(...) -a = arrow.T(head_style = 1) -ar.draw() -a.draw([(10,10), (20,30)]) -""" - -def draw_arrowhead(can, tailx, taily, tipx, tipy, thickness, head_len, style): - can.comment("ARROWHEAD tail=(%d,%d) tip=(%d,%d)\n" - % (tailx, taily, tipx, tipy)) - - halfthickness = thickness/2.0 - dx = tipx - tailx - dy = tipy - taily - arrow_len = math.sqrt(dx*dx + dy*dy) - angle = math.atan2(dy, dx) * 360 / (2*math.pi) - base = arrow_len - head_len - can.push_transformation((tailx, taily), None, angle) - - can.newpath() - if style == 0: - can.moveto(base, - halfthickness) - can.lineto(base, halfthickness) - can.lineto(arrow_len, 0) - can.closepath() - elif style == 1: - depth = head_len / 2.5 - can.moveto(base - depth, -halfthickness) - can.lineto(base, 0) - can.lineto(base - depth, halfthickness) - can.lineto(arrow_len, 0) - can.closepath() - elif style == 2: - can.moveto(base + head_len/2.0, 0) - can.path_arc(base + head_len / 2.0, 0, head_len / 2.0, 1.0, 0, 400) - elif style == 3: - can.moveto(base, 0) - can.lineto(base + head_len/2.0, -halfthickness) - can.lineto(arrow_len, 0) - can.lineto(base + head_len/2.0, halfthickness) - can.closepath() - else: - raise Exception, "Arrow style must be a number between 0 and 3." - can.fill() - can.pop_transformation() - can.comment("end ARROWHEAD.\n") - -def draw_arrowbody(can, tailx, taily, tipx, tipy, head_len): - dx = tipx - tailx - dy = tipy - taily - arrow_len = math.sqrt(dx*dx + dy*dy) - angle = math.atan2(dy, dx) * 360 / (2*math.pi) - base = arrow_len - head_len - can.push_transformation((tailx, taily), None, angle) - can.moveto(0, 0) - can.lineto(base+head_len*0.1, 0) - can.stroke() - can.pop_transformation() - - -class T(chart_object.T): - __doc__ = arrow_doc.doc - keys = { - "thickness" : (UnitType, 4, - "The width of the arrow head."), - "head_len": (UnitType, 8, - "The length of the arrow head."), - "head_color": (color.T, color.default, - "The color of the arrow head."), - "line_style": (line_style.T, line_style.default, - "Line style."), - "head_style": (IntType, 1, - "The value of 0 draws a triangular arrow head. The value of 1 draws a swallow-tail arrow head. The value of 2 draws a circular head. The value of 3 draws a diamond-shaped head.") - } -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def draw(self, points, can = None): - """Parameter <points> specifies the - list of points the arrow traverses through. - It should contain at least two points, i.e., - the tail and tip. Parameter - <can> is an optional parameter that specifies the output. - <<canvas>> - """ - if can == None: can = canvas.default_canvas() - self.type_check() - xtip = points[-1][0] - ytip = points[-1][1] - - xtail = points[-2][0] - ytail = points[-2][1] - - can.newpath() - can.set_line_style(self.line_style) - if len(points) > 2: - can.moveto(points[0][0], points[0][1]) - for i in range(1, len(points)-1): - can.lineto(points[i][0], points[i][1]) - - draw_arrowbody(can, xscale(xtail), yscale(ytail), - yscale(xtip), yscale(ytip), - nscale(self.head_len)) - - can.set_fill_color(self.head_color) - draw_arrowhead(can, xscale(xtail), yscale(ytail), - xscale(xtip), yscale(ytip), - nscale(self.thickness), - nscale(self.head_len), - self.head_style) - - can.setbb(xtail, ytail) - can.setbb(xtip, ytip) - -standards = object_set.T() -def _intern(a): - global standards - standards.add(a) - return a - -a0 = _intern(T(head_style=0)) -a1 = _intern(T(head_style=1)) -a2 = _intern(T(head_style=2)) -a3 = _intern(T(head_style=3)) -gray0 = _intern(T(head_style=0, head_color = color.gray50, - line_style=line_style.T(color=color.gray50))) -gray1 = _intern(T(head_style=1, head_color = color.gray50, - line_style=line_style.T(color=color.gray50))) -gray2 = _intern(T(head_style=2, head_color = color.gray50, - line_style=line_style.T(color=color.gray50))) -gray3 = _intern(T(head_style=3, head_color = color.gray50, - line_style=line_style.T(color=color.gray50))) - -fat0 = _intern(T(head_style=0, head_len=12, thickness=10, line_style=line_style.T(width=2))) -fat1 = _intern(T(head_style=1, head_len=12, thickness=10, line_style=line_style.T(width=2))) -fat2 = _intern(T(head_style=2, head_len=12, thickness=10, line_style=line_style.T(width=2))) -fat3 = _intern(T(head_style=3, head_len=12, thickness=10, line_style=line_style.T(width=2))) -fatgray0 = _intern(T(head_style=0, head_len=12, thickness=10, - head_color = color.gray50, - line_style=line_style.T(width=2, color=color.gray50))) -fatgray1 = _intern(T(head_style=1, head_len=12, thickness=10, - head_color = color.gray50, - line_style=line_style.T(width=2, color=color.gray50))) -fatgray2 = _intern(T(head_style=2, head_len=12, thickness=10, - head_color = color.gray50, - line_style=line_style.T(width=2, color=color.gray50))) -fatgray3 = _intern(T(head_style=3, head_len=12, thickness=10, - head_color = color.gray50, - line_style=line_style.T(width=2, color=color.gray50))) - -default = a1 - - diff --git a/openerp/pychart/arrow_doc.py b/openerp/pychart/arrow_doc.py deleted file mode 100644 index 38391a9d886..00000000000 --- a/openerp/pychart/arrow_doc.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -head_color(type:color.T) default="The color of the arrow head.". -head_style(type:int) default="The value of 0 draws a triangular arrow head. The value of 1 draws a swallow-tail arrow head. The value of 2 draws a circular head. The value of 3 draws a diamond-shaped head.". -head_len(type:length in points (\\xref{unit})) default="The length of the arrow head.". -line_style(type:line_style.T) default="Line style.". -thickness(type:length in points (\\xref{unit})) default="The width of the arrow head.". -""" - diff --git a/openerp/pychart/axis.py b/openerp/pychart/axis.py deleted file mode 100644 index e236188b1e6..00000000000 --- a/openerp/pychart/axis.py +++ /dev/null @@ -1,242 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import font -import pychart_util -import chart_object -import line_style -import math -import theme -import axis_doc -from pychart_types import * -from types import * - -class T(chart_object.T): - keys = { - "tic_interval" : (IntervalType, None, - pychart_util.interval_desc("tick marks")), - "tic_len" : (UnitType, 6, """The length of tick lines. The value can be negative, in which case the tick lines are drawn right of (or above) the axis."""), - "minor_tic_interval" : (IntervalType, None, - pychart_util.interval_desc("minor tick marks")), - "minor_tic_len" : (UnitType, 3, """The length of minor tick marks. The value can be negative, in which case the tick lines are drawn right of (or above) the axis."""), - "line_style": (line_style.T, line_style.default, - "Specifies the style of axis and tick lines."), - "label": (types.StringType, "axis label", - "The descriptive string displayed below (or to the left of) the axis. <<font>>."), - "format": (FormatType, "%s", - """The format string for tick labels. - It can be a `printf' style format string, or - a single-parameter function that takes an X (or Y) value - and returns a string. """ + - pychart_util.string_desc), - "label_offset": (CoordOrNoneType, (None,None), - """The location for drawing the axis label, - relative to the middle point of the axis. - If the value is None, the label is displayed - below (or to the left of) of axis at the middle."""), - "tic_label_offset": (CoordType, (0,0), - """The location for drawing tick labels, - relative to the tip of the tick line."""), - "offset": (UnitType, 0, - """The location of the axis. - The value of 0 draws the - axis at the left (for the Y axis) or bottom (for the X axis) - edge of the drawing area. - """) - } - -class X(T): - keys = pychart_util.union_dict(T.keys, - {"draw_tics_above": (IntType, 0, - "If true, tick lines and labels are drawn above the axis line.")}) - __doc__ = axis_doc.doc_x -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def draw_below(self, ar, can): - self.type_check() - self.tic_interval = self.tic_interval or ar.x_grid_interval - y_base = ar.loc[1] + self.offset - - can.line(self.line_style, ar.loc[0], y_base, - ar.loc[0]+ ar.size[0], y_base) - - tic_dic = {} - max_tic_height = 0 - - for i in ar.x_tic_points(self.tic_interval): - tic_dic[i] = 1 - ticx = ar.x_pos(i) - - str = "/hC" + pychart_util.apply_format(self.format, (i, ), 0) - - (total_height, base_height) = font.text_height(str) - max_tic_height = max(max_tic_height, total_height) - - can.line(self.line_style, ticx, y_base, ticx, y_base-self.tic_len) - can.show(ticx+self.tic_label_offset[0], - y_base-self.tic_len-base_height+self.tic_label_offset[1], - str) - - if self.minor_tic_interval: - for i in ar.x_tic_points(self.minor_tic_interval): - if tic_dic.has_key(i): - # a major tic was drawn already. - pass - else: - ticx = ar.x_pos(i) - can.line(self.line_style, ticx, y_base, ticx, - y_base-self.minor_tic_len) - - self.draw_label(ar, can, y_base - self.tic_len - max_tic_height - 10) - - def draw_above(self, ar, can): - y_base = ar.loc[1] + self.offset - - tic_dic = {} - max_tic_height = 0 - - for i in ar.x_tic_points(self.tic_interval): - tic_dic[i] = 1 - ticx = ar.x_pos(i) - - str = "/hC" + pychart_util.apply_format(self.format, (i, ), 0) - - (total_height, base_height) = font.text_height(str) - max_tic_height = max(max_tic_height, total_height) - - can.line(self.line_style, ticx, y_base, ticx, y_base + self.tic_len) - can.show(ticx+self.tic_label_offset[0], - y_base + self.tic_len + base_height + self.tic_label_offset[1], - str) - - if self.minor_tic_interval: - for i in ar.x_tic_points(self.minor_tic_interval): - if tic_dic.has_key(i): - # a major tic was drawn already. - pass - else: - ticx = ar.x_pos(i) - can.line(self.line_style, ticx, y_base, ticx, - y_base + self.minor_tic_len) - self.draw_label(ar, can, y_base + self.tic_len + max_tic_height + 10) - - def draw_label(self, ar, can, ylabel): - if self.label == None: return - - str = "/hC/vM" + self.label - (label_height, base_height) = font.text_height(str) - xlabel = ar.loc[0] + ar.size[0]/2.0 - if self.label_offset[0] != None: - xlabel += self.label_offset[0] - if self.label_offset[1] != None: - ylabel += self.label_offset[1] - can.show(xlabel, ylabel, str) - - def draw(self, ar, can): - self.type_check() - self.tic_interval = self.tic_interval or ar.x_grid_interval - y_base = ar.loc[1] + self.offset - can.line(self.line_style, ar.loc[0], y_base, - ar.loc[0]+ ar.size[0], y_base) - if self.draw_tics_above: - self.draw_above(ar, can) - else: - self.draw_below(ar, can) -class Y(T): - __doc__ = axis_doc.doc_y - keys = pychart_util.union_dict(T.keys, - {"draw_tics_right": (IntType, 0, - "If true, tick lines and labels are drawn right of the axis line.")}) - - def draw_left(self, ar, can): - x_base = ar.loc[0] + self.offset - xmin = 999999 - tic_dic = {} - for i in ar.y_tic_points(self.tic_interval): - y_tic = ar.y_pos(i) - tic_dic[i] = 1 - can.line(self.line_style, x_base, y_tic, - x_base - self.tic_len, y_tic) - str = pychart_util.apply_format(self.format, (i,), 0) - if self.tic_len > 0: str = "/hR" + str - - tic_height, base_height = font.text_height(str) - x = x_base - self.tic_len + self.tic_label_offset[0] - can.show(x, y_tic - tic_height/2.0 + self.tic_label_offset[1], - str) - xmin = min(xmin, x - font.text_width(str)) - - if self.minor_tic_interval: - for i in ar.y_tic_points(self.minor_tic_interval): - if tic_dic.has_key(i): - # a major tic line was drawn already. - pass - else: - y_tic = ar.y_pos(i) - can.line(self.line_style, x_base, y_tic, - x_base - self.minor_tic_len, y_tic) - - self.draw_label(ar, can, xmin - theme.default_font_size/2.0) - - def draw_right(self, ar, can): - x_base = ar.loc[0] + self.offset - xmax = 0 - tic_dic = {} - for i in ar.y_tic_points(self.tic_interval): - y_tic = ar.y_pos(i) - tic_dic[i] = 1 - can.line(self.line_style, x_base, y_tic, - x_base + self.tic_len, y_tic) - str = pychart_util.apply_format(self.format, (i,), 0) - if self.tic_len > 0: str = "/hL" + str - - tic_height, base_height = font.text_height(str) - x = x_base + self.tic_len + self.tic_label_offset[0] - can.show(x, y_tic - tic_height/2.0 + self.tic_label_offset[1], - str) - xmax = max(xmax, x + font.text_width(str)) - - if self.minor_tic_interval: - for i in ar.y_tic_points(self.minor_tic_interval): - if tic_dic.has_key(i): - # a major tic line was drawn already. - pass - else: - y_tic = ar.y_pos(i) - can.line(self.line_style, x_base, y_tic, - x_base + self.minor_tic_len, y_tic) - - self.draw_label(ar, can, xmax + theme.default_font_size) - - def draw_label(self, ar, can, xlabel): - if self.label == None: - return - ylabel = ar.loc[1] + ar.size[1] / 2 - if self.label_offset[0] != None: - xlabel += self.label_offset[0] - if self.label_offset[1] != None: - ylabel += self.label_offset[1] - can.show(xlabel, ylabel, "/a90/hC" + self.label) - - def draw(self, ar, can): - self.type_check() - self.tic_interval = self.tic_interval or ar.y_grid_interval - - x_base = ar.loc[0] + self.offset - can.line(self.line_style, x_base, ar.loc[1], x_base, ar.loc[1]+ar.size[1]) - if self.draw_tics_right: - self.draw_right(ar, can) - else: - self.draw_left(ar, can) diff --git a/openerp/pychart/axis_doc.py b/openerp/pychart/axis_doc.py deleted file mode 100644 index 43fb4046769..00000000000 --- a/openerp/pychart/axis_doc.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc_x="""Attributes supported by this class are: -draw_tics_above(type:int) default="If true, tick lines and labels are drawn above the axis line.". -minor_tic_len(type:length in points (\\xref{unit})) default="The length of minor tick marks. The value can be negative, in which case the tick lines are drawn right of (or above) the axis.". -tic_label_offset(type:(x,y)) default="The location for drawing tick labels, - relative to the tip of the tick line.". -format(type:printf format string) default="The format string for tick labels. - It can be a `printf' style format string, or - a single-parameter function that takes an X (or Y) value - and returns a string. The appearance of the string produced here can be -controlled using escape sequences. <<font>>". -label_offset(type:(x,y) or None) default="The location for drawing the axis label, - relative to the middle point of the axis. - If the value is None, the label is displayed - below (or to the left of) of axis at the middle.". -label(type:str) default="The descriptive string displayed below (or to the left of) the axis. <<font>>.". -offset(type:length in points (\\xref{unit})) default="The location of the axis. - The value of 0 draws the - axis at the left (for the Y axis) or bottom (for the X axis) - edge of the drawing area. - ". -tic_interval(type:Number or function) default="When the value is a number, it specifies the interval at which tick marks are drawn. Otherwise, the value must be a function that takes no argument and returns the list of numbers. The return value specifies the X or Y points at which tick marks are drawn.". -line_style(type:line_style.T) default="Specifies the style of axis and tick lines.". -tic_len(type:length in points (\\xref{unit})) default="The length of tick lines. The value can be negative, in which case the tick lines are drawn right of (or above) the axis.". -minor_tic_interval(type:Number or function) default="When the value is a number, it specifies the interval at which minor tick marks are drawn. Otherwise, the value must be a function that takes no argument and returns the list of numbers. The return value specifies the X or Y points at which minor tick marks are drawn.". -""" - -doc_y="""Attributes supported by this class are: -draw_tics_right(type:int) default="If true, tick lines and labels are drawn right of the axis line.". -minor_tic_len(type:length in points (\\xref{unit})) default="The length of minor tick marks. The value can be negative, in which case the tick lines are drawn right of (or above) the axis.". -tic_label_offset(type:(x,y)) default="The location for drawing tick labels, - relative to the tip of the tick line.". -format(type:printf format string) default="The format string for tick labels. - It can be a `printf' style format string, or - a single-parameter function that takes an X (or Y) value - and returns a string. The appearance of the string produced here can be -controlled using escape sequences. <<font>>". -label_offset(type:(x,y) or None) default="The location for drawing the axis label, - relative to the middle point of the axis. - If the value is None, the label is displayed - below (or to the left of) of axis at the middle.". -label(type:str) default="The descriptive string displayed below (or to the left of) the axis. <<font>>.". -offset(type:length in points (\\xref{unit})) default="The location of the axis. - The value of 0 draws the - axis at the left (for the Y axis) or bottom (for the X axis) - edge of the drawing area. - ". -tic_interval(type:Number or function) default="When the value is a number, it specifies the interval at which tick marks are drawn. Otherwise, the value must be a function that takes no argument and returns the list of numbers. The return value specifies the X or Y points at which tick marks are drawn.". -line_style(type:line_style.T) default="Specifies the style of axis and tick lines.". -tic_len(type:length in points (\\xref{unit})) default="The length of tick lines. The value can be negative, in which case the tick lines are drawn right of (or above) the axis.". -minor_tic_interval(type:Number or function) default="When the value is a number, it specifies the interval at which minor tick marks are drawn. Otherwise, the value must be a function that takes no argument and returns the list of numbers. The return value specifies the X or Y points at which minor tick marks are drawn.". -""" - diff --git a/openerp/pychart/axis_x_doc.py b/openerp/pychart/axis_x_doc.py deleted file mode 100644 index ca2a377f881..00000000000 --- a/openerp/pychart/axis_x_doc.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -doc="""Attributes supported by this class are: -tic_label_offset(type:(x,y)): - The location where the tick labels is drawn. Relative to the - tip of the tick mark. - default value=(0, 0). -format(type:printf format string): - The format string for tick labels. It can be a `printf' style - format string, or a single-parameter function that returns a - string. See also font. - default value=%s. -minor_tic_len(type:number): - The length of minor tick marks. - default value=3. -label_offset(type:(x,y) or None): - The location where the axis label is drawn. Relative to the - left-bottom corner of the axis. - default value=(None, None). -grid_interval(type:Number or function): - When the value is a number, it specifies the interval with which - grid lines are drawn. Otherwise, the value must be a function. - It must take no argument and return the list of numbers, which - specifies the X or Y points where grid lines are drawn. - default value=None. -label(type:str): - The description of the axis. See also font. - default value=axis label. -grid_style(type:line_style.T): - The style of grid lines. - default value=None. -tic_interval(type:Number or function): - When the value is a number, it specifies the interval with which - tick marks are drawn. Otherwise, the value must be a function. - It must take no argument and return the list of numbers, which - specifies the X or Y points where tick marks are drawn. - default value=None. -line_style(type:line_style.T): - The style of tick lines. - default value=default. -tic_len(type:number): - The length of tick lines - default value=6. -minor_tic_interval(type:Number or function): - When the value is a number, it specifies the interval with which - minor tick marks are drawn. Otherwise, the value must be a function. - It must take no argument and return the list of numbers, which - specifies the X or Y points where minor tick marks are drawn. - default value=None. -first_tic_value(type:number): - The location of the first tick mark. Defaults to the x_range[0] - (or y_range[0]) of the area. - default value=None. -""" \ No newline at end of file diff --git a/openerp/pychart/axis_y_doc.py b/openerp/pychart/axis_y_doc.py deleted file mode 100644 index 354afb25884..00000000000 --- a/openerp/pychart/axis_y_doc.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -doc="""Attributes supported by this class are: -minor_tic_len(type:number): - The length of minor tick marks. - default value=3. -tic_label_offset(type:(x,y)): - The location where the tick labels is drawn. Relative to the - tip of the tick mark. - default value=(0, 0). -format(type:printf format string): - The format string for tick labels. It can be a `printf' style - format string, or a single-parameter function that returns a - string. See also font. - default value=%s. -label_offset(type:(x,y) or None): - The location where the axis label is drawn. Relative to the - left-bottom corner of the axis. - default value=(None, None). -grid_interval(type:Number or function): - When the value is a number, it specifies the interval with which - grid lines are drawn. Otherwise, the value must be a function. - It must take no argument and return the list of numbers, which - specifies the X or Y points where grid lines are drawn. - default value=None. -tic_len(type:number): - The length of tick lines - default value=6. -grid_style(type:line_style.T): - - default value=gray70dash3. -tic_interval(type:Number or function): - When the value is a number, it specifies the interval with which - tick marks are drawn. Otherwise, the value must be a function. - It must take no argument and return the list of numbers, which - specifies the X or Y points where tick marks are drawn. - default value=None. -line_style(type:line_style.T): - The style of tick lines. - default value=default. -label(type:str): - The description of the axis. See also font. - default value=axis label. -minor_tic_interval(type:Number or function): - When the value is a number, it specifies the interval with which - minor tick marks are drawn. Otherwise, the value must be a function. - It must take no argument and return the list of numbers, which - specifies the X or Y points where minor tick marks are drawn. - default value=None. -first_tic_value(type:number): - The location of the first tick mark. Defaults to the x_range[0] - (or y_range[0]) of the area. - default value=None. -""" diff --git a/openerp/pychart/bar_plot.py b/openerp/pychart/bar_plot.py deleted file mode 100644 index b332626949d..00000000000 --- a/openerp/pychart/bar_plot.py +++ /dev/null @@ -1,269 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import line_style -import fill_style -import pychart_util -import chart_object -import legend -import error_bar -import bar_plot_doc -import theme -from types import * -from pychart_types import * - -fill_styles = None - -_keys = { - "direction" : (StringType, "vertical", - """The direction the growth of the bars. The value is either 'horizontal' - or 'vertical'."""), - "data" : (AnyType, None, pychart_util.data_desc), - "data_label_offset": (CoordType, (0, 5), - "The location of data labels relative to the sample point. See also attribute data_label_format."), - - "data_label_format": (FormatType, None, """The - format string for the label displayed besides each - bar. It can be a `printf' style format - string, or a two-parameter function that - takes (x,y) values and returns a string. """ - + pychart_util.string_desc), - - "label": (StringType, "???", pychart_util.label_desc), - "bcol" : (IntType, 0, - """Specifies the column from which base values (i.e., X values when attribute "direction" is "vertical", Y values otherwise) are extracted. -The - combination of "data", "bcol", and "hcol" attributes defines - the set of boxes drawn by this chart. See the - below example: - -@example - d = [[5,10], [7,22], [8,25]] - p = bar_plot.T(data = d, bcol = 1, hcol = 2) -@end example - - Here, three bars will be drawn. The X values of the bars - will be 5, 7, and 8. The Y values of the bars will be - 10, 22, and 25, respectively. (In practice, because - the values of bcol and hcol defaults to 1 and 2, you can - write the above example just as "p = bar_plot.T(data = d)". - """), - "hcol": (IntType, 1, - """The column from which the height of each bar is extracted. - See also the description of the 'bcol' attribute."""), - "line_style": (line_style.T, line_style.default, - "The style of the outer frame of each box."), - "fill_style": (fill_style.T, lambda: fill_styles.next(), - "Defines the fill style of each box.", - "The style is picked from standard styles round-robin."), - "legend_line_style": (line_style.T, None, - """The line style used to draw a legend entry. Usually, the value is None, meaning that the value of "line_style" attribute is used."""), - "legend_fill_style": (fill_style.T, None, - """The fill style used to draw a legend entry. Usually, the value is None, meaning that the value of "fill_style" attribute is used."""), - - "cluster": (TupleType, (0, 1), """This attribute is used to - cluster multiple bar plots side by side in a single chart. - The value should be a tuple of two integers. The second value should be equal to the total number of bar plots in the chart. The first value should be the relative position of this chart; 0 places this chart the leftmost, and N-1 - (where N is the 2nd value of this attribute) places this chart the rightmost. Consider the below example: - -@example - a = area.T(...) - p1 = bar_plot.T(data = [[1,20][2,30]], cluster=(0,2)) - p2 = bar_plot.T(data = [[1,25],[2,10]], cluster=(1,2)) - a.add_plot(p1, p2) - a.draw() -@end example - - In this example, one group of bars will be drawn side-by-side at - position x=1, one with height 20, the other with height 25. The - other two bars will be drawn side by side at position x=2, one - with height 30 and the other with height 10. - """), - "width": (UnitType, 5, """Width of each box. -@cindex width, bar chart -@cindex size, bar chart -"""), - "cluster_sep": (UnitType, 0, """The separation between - clustered boxes."""), - "stack_on": (AnyType, None, - "The value must be either None or bar_plot.T. If not None, bars of this plot are stacked on top of another bar plot."), - "error_minus_col": (IntType, -1, - """Specifies the column from which the depth of the errorbar is extracted. This attribute is meaningful only when - error_bar != None. - """), - "qerror_minus_col": (IntType, -1, - """The depth of the "quartile" errorbar is extracted from - this column in data. This attribute is meaningful only - when error_bar != None. """), - "error_plus_col": (IntType, -1, - """The depth of the errorbar is extracted from - this column in data. This attribute is meaningful only - when error_bar != None."""), - "qerror_plus_col": (IntType, -1, - """The depth of the "quartile" errorbar is extracted from - this column in data. This attribute is meaningful only - when error_bar != None."""), - "error_bar": (error_bar.T, None, - "Specifies the style of the error bar. <<error_bar>>"), - "_abs_data" : (ListType, None, - "Used only internally."), - } - -def find_bar_plot(ar, nth): - "Find the NTH barplot of the cluster in area AR." - for plot in ar.plots: - if isinstance(plot, T) and plot.cluster[0] == nth: - return plot - raise Exception, "The %dth bar plot in the cluster not found." % nth - -class T(chart_object.T): - __doc__ = bar_plot_doc.doc - keys = _keys - def check_integrity(self): - self.type_check() - self.compute_abs_data() - def compute_abs_data(self): - if self._abs_data != None: - return - - if self.stack_on == None: - self._abs_data = self.data - else: - n = [] - for pair in self.data: - self.stack_on.compute_abs_data() - newpair = list(pair[:]) - newpair[self.hcol] = self.stack_on.get_value(newpair[self.bcol]) + pair[self.hcol] - n.append(newpair) - self._abs_data = n - -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def get_value(self, bval): - for pair in self._abs_data: - if pair[self.bcol] == bval: - return pair[self.hcol] - raise ValueError, str(bval) + ": can't find the xval" - - def get_data_range(self, which): - if self.direction == 'vertical': - if which == 'X': - return pychart_util.get_data_range(self._abs_data, self.bcol) - else: - return pychart_util.get_data_range(self._abs_data, self.hcol) - else: - assert self.direction == 'horizontal' - if which == 'Y': - return pychart_util.get_data_range(self._abs_data, self.bcol) - else: - return pychart_util.get_data_range(self._abs_data, self.hcol) - - def get_bar_width(self, ar, nth): - off = 0 - for i in range(0, nth): - plot = find_bar_plot(ar, i) - off += plot.width + plot.cluster_sep - return off - - def draw_vertical(self, ar, can): - for pair in self.data: - xval = pair[self.bcol] - yval = pychart_util.get_sample_val(pair, self.hcol) - - if None in (xval, yval): continue - - ybot = 0 - if self.stack_on: - ybot = self.stack_on.get_value(xval) - yval += ybot - - totalWidth = self.get_bar_width(ar, self.cluster[1]) - firstX = ar.x_pos(xval) - totalWidth/2.0 - thisX = firstX + self.get_bar_width(ar, self.cluster[0]) - - can.rectangle(self.line_style, self.fill_style, - thisX, ar.y_pos(ybot), thisX+self.width, - ar.y_pos(yval)) - - if self.error_bar: - plus = pair[self.error_minus_col or self.error_plus_col] - minus = pair[self.error_plus_col or self.error_minus_col] - qplus = 0 - qminus = 0 - if self.qerror_minus_col or self.qerror_plus_col: - qplus = pair[self.qerror_minus_col or self.qerror_plus_col] - qminus = pair[self.qerror_plus_col or self.qerror_minus_col] - if None not in (plus, minus, qplus, qminus): - self.error_bar.draw(can, (thisX+self.width/2.0, ar.y_pos(yval)), - ar.y_pos(yval - minus), - ar.y_pos(yval + plus), - ar.y_pos(yval - qminus), - ar.y_pos(yval + qplus)) - - if self.data_label_format: - can.show(thisX + self.width/2.0 + self.data_label_offset[0], - ar.y_pos(yval) + self.data_label_offset[1], - "/hC" + pychart_util.apply_format(self.data_label_format, (pair[self.bcol], pair[self.hcol]), 1)) - - def draw_horizontal(self, ar, can): - for pair in self.data: - yval = pair[self.bcol] - xval = pychart_util.get_sample_val(pair, self.hcol) - - if None in (xval, yval): continue - - xbot = 0 - if self.stack_on: - xbot = self.stack_on.get_value(yval) - xval += xbot - totalWidth = self.get_bar_width(ar, self.cluster[1]) - firstY = ar.y_pos(yval) - totalWidth/2.0 - thisY = firstY + self.get_bar_width(ar, self.cluster[0]) - - can.rectangle(self.line_style, self.fill_style, - ar.x_pos(xbot), thisY, - ar.x_pos(xval), thisY+self.width) - - if self.data_label_format: - can.show(ar.x_pos(xval) + self.data_label_offset[0], - thisY + self.width/2.0 + self.data_label_offset[1], - "/vM/hL" + pychart_util.apply_format(self.data_label_format, (pair[self.bcol], pair[self.hcol]), 1)) - - def get_legend_entry(self): - if self.label: - return legend.Entry(line_style=(self.legend_line_style or self.line_style), - fill_style=(self.legend_fill_style or self.fill_style), - label=self.label) - return None - - def draw(self, ar, can): - self.type_check() - can.clip(ar.loc[0], ar.loc[1], - ar.loc[0] + ar.size[0], ar.loc[1] + ar.size[1]) - - if self.direction == "vertical": - self.draw_vertical(ar, can) - else: - self.draw_horizontal(ar, can) - - can.endclip() - - -def init(): - global fill_styles - fill_styles = fill_style.standards.iterate() - -theme.add_reinitialization_hook(init) - diff --git a/openerp/pychart/bar_plot_doc.py b/openerp/pychart/bar_plot_doc.py deleted file mode 100644 index c262367b9e5..00000000000 --- a/openerp/pychart/bar_plot_doc.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -cluster_sep(type:length in points (\\xref{unit})) default="The separation between - clustered boxes.". -error_plus_col(type:int) default="The depth of the errorbar is extracted from - this column in data. This attribute is meaningful only - when error_bar != None.". -direction(type:str) default="The direction the growth of the bars. The value is either 'horizontal' - or 'vertical'.". -legend_line_style(type:line_style.T) default="The line style used to draw a legend entry. Usually, the value is None, meaning that the value of "line_style" attribute is used.". -error_bar(type:error_bar.T) default="Specifies the style of the error bar. <<error_bar>>". -data_label_format(type:printf format string) default="The - format string for the label displayed besides each - bar. It can be a `printf' style format - string, or a two-parameter function that - takes (x,y) values and returns a string. The appearance of the string produced here can be -controlled using escape sequences. <<font>>". -width(type:length in points (\\xref{unit})) default="Width of each box. -@cindex width, bar chart -@cindex size, bar chart -". -bcol(type:int) default="Specifies the column from which base values (i.e., X values when attribute "direction" is "vertical", Y values otherwise) are extracted. -The - combination of "data", "bcol", and "hcol" attributes defines - the set of boxes drawn by this chart. See the - below example: - -@example - d = [[5,10], [7,22], [8,25]] - p = bar_plot.T(data = d, bcol = 1, hcol = 2) -@end example - - Here, three bars will be drawn. The X values of the bars - will be 5, 7, and 8. The Y values of the bars will be - 10, 22, and 25, respectively. (In practice, because - the values of bcol and hcol defaults to 1 and 2, you can - write the above example just as "p = bar_plot.T(data = d)". - ". -qerror_minus_col(type:int) default="The depth of the "quartile" errorbar is extracted from - this column in data. This attribute is meaningful only - when error_bar != None. ". -_abs_data(type:list) default="Used only internally.". -label(type:str) default="The label to be displayed in the legend. <<legend>>, <<font>>". -cluster(type:tuple) default="This attribute is used to - cluster multiple bar plots side by side in a single chart. - The value should be a tuple of two integers. The second value should be equal to the total number of bar plots in the chart. The first value should be the relative position of this chart; 0 places this chart the leftmost, and N-1 - (where N is the 2nd value of this attribute) places this chart the rightmost. Consider the below example: - -@example - a = area.T(...) - p1 = bar_plot.T(data = [[1,20][2,30]], cluster=(0,2)) - p2 = bar_plot.T(data = [[1,25],[2,10]], cluster=(1,2)) - a.add_plot(p1, p2) - a.draw() -@end example - - In this example, one group of bars will be drawn side-by-side at - position x=1, one with height 20, the other with height 25. The - other two bars will be drawn side by side at position x=2, one - with height 30 and the other with height 10. - ". -hcol(type:int) default="The column from which the height of each bar is extracted. - See also the description of the 'bcol' attribute.". -stack_on(type:any) default="The value must be either None or bar_plot.T. If not None, bars of this plot are stacked on top of another bar plot.". -qerror_plus_col(type:int) default="The depth of the "quartile" errorbar is extracted from - this column in data. This attribute is meaningful only - when error_bar != None.". -data_label_offset(type:(x,y)) default="The location of data labels relative to the sample point. See also attribute data_label_format.". -fill_style(type:fill_style.T) default="Defines the fill style of each box.". - The style is picked from standard styles round-robin. - -data(type:any) default="Specifies the data points. <<chart_data>>". -line_style(type:line_style.T) default="The style of the outer frame of each box.". -legend_fill_style(type:fill_style.T) default="The fill style used to draw a legend entry. Usually, the value is None, meaning that the value of "fill_style" attribute is used.". -error_minus_col(type:int) default="Specifies the column from which the depth of the errorbar is extracted. This attribute is meaningful only when - error_bar != None. - ". -""" - diff --git a/openerp/pychart/basecanvas.py b/openerp/pychart/basecanvas.py deleted file mode 100644 index d32a8ca76ab..00000000000 --- a/openerp/pychart/basecanvas.py +++ /dev/null @@ -1,506 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import math -import sys -import time -import re - -import font -import pychart_util -import version -from scaling import * - -def _compute_bounding_box(points): - """Given the list of coordinates (x,y), this procedure computes - the smallest rectangle that covers all the points.""" - (xmin, ymin, xmax, ymax) = (999999, 999999, -999999, -999999) - for p in points: - xmin = min(xmin, p[0]) - xmax = max(xmax, p[0]) - ymin = min(ymin, p[1]) - ymax = max(ymax, p[1]) - return (xmin, ymin, xmax, ymax) - -def _intersect_box(b1, b2): - xmin = max(b1[0], b2[0]) - ymin = max(b1[1], b2[1]) - xmax = min(b1[2], b2[2]) - ymax = min(b1[3], b2[3]) - return (xmin, ymin, xmax, ymax) - -def invisible_p(x, y): - """Return true if the point (X, Y) is visible in the canvas.""" - if x < -499999 or y < -499999: - return 1 - return 0 - -def to_radian(deg): - return deg*2*math.pi / 360.0 - -def midpoint(p1, p2): - return ( (p1[0]+p2[0])/2.0, (p1[1]+p2[1])/2.0 ) - - -active_canvases = [] - -InvalidCoord = 999999 -class T(object): - def __init__(self): - global active_canvases - - self.__xmax = -InvalidCoord - self.__xmin = InvalidCoord - self.__ymax = -InvalidCoord - self.__ymin = InvalidCoord - self.__clip_box = (-InvalidCoord, -InvalidCoord, InvalidCoord, InvalidCoord) - self.__clip_stack = [] - self.__nr_gsave = 0 - - self.title = re.sub("(.*)\\.py$", "\\1", sys.argv[0]) - self.creator = "pychart %s" % (version.version,) - self.creation_date = time.strftime("(%m/%d/%y) (%I:%M %p)") - self.aux_comments = "" - self.author = None - active_canvases.append(self) - - def set_title(self, s): - """Define the string to shown in EPS/PDF "Title" field. The default value is the name of the script that creates the EPS/PDF file.""" - self.title = s - - def set_creator(self, tag): - """Define the string to be shown in EPS %%Creator or PDF Producer field. The default value is "pychart".""" - self.creator = tag - - def set_creation_date(self, s): - """Define the string to shown in EPS/PDF "CreationDate" field. Defalt value of this field is the current time.""" - self.creation_date = s - - def set_author(self, s): - """Set the author string. Unless this method is called, the Author field is not output in EPS or PDF.""" - self.author = s - - def add_aux_comments(self, s): - """Define an auxiliary comments to be output to the file, just after the required headers""" - self.aux_comments += s - - def close(self): - """This method closes the canvas and writes - contents to the associated file. - Calling this procedure is optional, because - Pychart calls this procedure for every open canvas on normal exit.""" - for i in range(0, len(active_canvases)): - if active_canvases[i] == self: - del active_canvases[i] - return - - def open_output(self, fname): - """Open the output file FNAME. Returns tuple (FD, NEED_CLOSE), - where FD is a file (or file-like) object, and NEED_CLOSE is a - boolean flag that tells whether FD.close() should be called - after finishing writing to the file. - - FNAME can be one of the three things: - (1) None, in which case (sys.stdout, False) is returned. - (2) A file-like object, in which case (fname, False) is returned. - (3) A string, in which case this procedure opens the file and returns - (fd, True).""" - - if not fname: - return (sys.stdout, False) - elif isinstance(fname, str): - return (file(fname, "wb"), True) - else: - if not hasattr(fname, "write"): - raise Exception, "Expecting either a filename or a file-like object, but got %s" % fname - return (fname, False) - - def setbb(self, x, y): - """Call this method when point (X,Y) is to be drawn in the - canvas. This methods expands the bounding box to include - this point.""" - self.__xmin = min(self.__xmin, max(x, self.__clip_box[0])) - self.__xmax = max(self.__xmax, min(x, self.__clip_box[2])) - self.__ymin = min(self.__ymin, max(y, self.__clip_box[1])) - self.__ymax = max(self.__ymax, min(y, self.__clip_box[3])) - - def fill_with_pattern(self, pat, x1, y1, x2, y2): - if invisible_p(x2, y2): return - - self.comment("FILL pat=%s (%d %d)-(%d %d)\n" % (pat, x1, y1, x2, y2)) - self.set_fill_color(pat.bgcolor) - self._path_polygon([(x1, y1), (x1, y2), (x2, y2), (x2, y1)]) - self.fill() - pat.draw(self, x1, y1, x2, y2) - self.comment("end FILL.\n") - - def _path_polygon(self, points): - "Low-level polygon-drawing routine." - (xmin, ymin, xmax, ymax) = _compute_bounding_box(points) - if invisible_p(xmax, ymax): - return - self.setbb(xmin, ymin) - self.setbb(xmax, ymax) - - self.newpath() - self.moveto(xscale(points[0][0]), yscale(points[0][1])) - for point in points[1:]: - self.lineto(xscale(point[0]), yscale(point[1])) - self.closepath() - - def polygon(self, edge_style, pat, points, shadow = None): - """Draw a polygon with EDGE_STYLE, fill with PAT, and the edges - POINTS. POINTS is a sequence of coordinates, e.g., ((10,10), (15,5), - (20,8)). SHADOW is either None or a tuple (XDELTA, YDELTA, - fillstyle). If non-null, a shadow of FILLSTYLE is drawn beneath - the polygon at the offset of (XDELTA, YDELTA).""" - - if pat: - self.comment("POLYGON points=[%s] pat=[%s]" - % (str(points), str(pat))) - (xmin, ymin, xmax, ymax) = _compute_bounding_box(points) - - if shadow: - xoff, yoff, shadow_pat = shadow - self.gsave() - self._path_polygon(map(lambda p, xoff=xoff, yoff=yoff: (p[0]+xoff, p[1]+yoff), points)) - self.clip_sub() - self.fill_with_pattern(shadow_pat, xmin+xoff, ymin+yoff, - xmax+xoff, ymax+yoff) - self.grestore() - - self.gsave() - self._path_polygon(points) - self.clip_sub() - self.fill_with_pattern(pat, xmin, ymin, xmax, ymax) - self.grestore() - if edge_style: - self.comment("POLYGON points=[%s] edge=[%s]" - % (str(points), str(edge_style))) - self.set_line_style(edge_style) - self._path_polygon(points) - self.stroke() - - def set_background(self, pat, x1, y1, x2, y2): - xmax, xmin, ymax, ymin = self.__xmax, self.__xmin, self.__ymax, self.__ymin - self.rectangle(None, pat, x1, y1, x2, y2) - self.__xmax, self.__xmin, self.__ymax, self.__ymin = xmax, xmin, ymax, ymin - - def rectangle(self, edge_style, pat, x1, y1, x2, y2, shadow = None): - """Draw a rectangle with EDGE_STYLE, fill with PAT, and the - bounding box (X1, Y1, X2, Y2). SHADOW is either None or a - tuple (XDELTA, YDELTA, fillstyle). If non-null, a shadow of - FILLSTYLE is drawn beneath the polygon at the offset of - (XDELTA, YDELTA).""" - - self.polygon(edge_style, pat, [(x1,y1), (x1,y2), (x2,y2), (x2, y1)], - shadow) - - def _path_ellipsis(self, x, y, radius, ratio, start_angle, end_angle): - self.setbb(x - radius, y - radius*ratio) - self.setbb(x + radius, y + radius*ratio) - oradius = nscale(radius) - centerx, centery = xscale(x), yscale(y) - startx, starty = centerx+oradius * math.cos(to_radian(start_angle)), \ - centery+oradius * math.sin(to_radian(start_angle)) - self.moveto(centerx, centery) - if start_angle % 360 != end_angle % 360: - self.moveto(centerx, centery) - self.lineto(startx, starty) - else: - self.moveto(startx, starty) - self.path_arc(xscale(x), yscale(y), nscale(radius), - ratio, start_angle, end_angle) - self.closepath() - - def ellipsis(self, line_style, pattern, x, y, radius, ratio = 1.0, - start_angle=0, end_angle=360, shadow=None): - """Draw an ellipsis with line_style and fill PATTERN. The center is \ - (X, Y), X radius is RADIUS, and Y radius is RADIUS*RATIO, whose \ - default value is 1.0. SHADOW is either None or a tuple (XDELTA, - YDELTA, fillstyle). If non-null, a shadow of FILLSTYLE is drawn - beneath the polygon at the offset of (XDELTA, YDELTA).""" - - if invisible_p(x + radius, y + radius*ratio): - return - - if pattern: - if shadow: - x_off, y_off, shadow_pat = shadow - self.gsave() - self.newpath() - self._path_ellipsis(x+x_off, y+y_off, radius, ratio, - start_angle, end_angle) - self.clip_sub() - self.fill_with_pattern(shadow_pat, - x-radius*2+x_off, - y-radius*ratio*2+y_off, - x+radius*2+x_off, - y+radius*ratio*2+y_off) - self.grestore() - self.gsave() - self.newpath() - self._path_ellipsis(x, y, radius, ratio, start_angle, end_angle) - self.clip_sub() - self.fill_with_pattern(pattern, - (x-radius*2), (y-radius*ratio*2), - (x+radius*2), (y+radius*ratio*2)) - self.grestore() - if line_style: - self.set_line_style(line_style) - self.newpath() - self._path_ellipsis(x, y, radius, ratio, start_angle, end_angle) - self.stroke() - - def clip_ellipsis(self, x, y, radius, ratio = 1.0): - """Create an elliptical clip region. You must call endclip() after - you completed drawing. See also the ellipsis method.""" - - self.gsave() - self.newpath() - self.moveto(xscale(x)+nscale(radius), yscale(y)) - self.path_arc(xscale(x), yscale(y), nscale(radius), ratio, 0, 360) - self.closepath() - self.__clip_stack.append(self.__clip_box) - self.clip_sub() - - def clip_polygon(self, points): - """Create a polygonal clip region. You must call endclip() after - you completed drawing. See also the polygon method.""" - self.gsave() - self._path_polygon(points) - self.__clip_stack.append(self.__clip_box) - self.__clip_box = _intersect_box(self.__clip_box, _compute_bounding_box(points)) - self.clip_sub() - - def clip(self, x1, y1, x2, y2): - """Activate a rectangular clip region, (X1, Y1) - (X2, Y2). - You must call endclip() after you completed drawing. - -canvas.clip(x,y,x2,y2) -draw something ... -canvas.endclip() -""" - - self.__clip_stack.append(self.__clip_box) - self.__clip_box = _intersect_box(self.__clip_box, (x1, y1, x2, y2)) - self.gsave() - self.newpath() - self.moveto(xscale(x1), yscale(y1)) - self.lineto(xscale(x1), yscale(y2)) - self.lineto(xscale(x2), yscale(y2)) - self.lineto(xscale(x2), yscale(y1)) - self.closepath() - self.clip_sub() - - def endclip(self): - """End the current clip region. When clip calls are nested, it - ends the most recently created crip region.""" - self.__clip_box = self.__clip_stack[-1] - del self.__clip_stack[-1] - self.grestore() - - def curve(self, style, points): - for p in points: - self.setbb(p[0], p[1]) - self.newpath() - self.set_line_style(style) - self.moveto(xscale(points[0][0]), xscale(points[0][1])) - i = 1 - n = 1 - while i < len(points): - if n == 1: - x2 = points[i] - n += 1 - elif n == 2: - x3 = points[i] - n += 1 - elif n == 3: - x4 = midpoint(x3, points[i]) - self.curveto(xscale(x2[0]), xscale(x2[1]), - xscale(x3[0]), xscale(x3[1]), - xscale(x4[0]), xscale(x4[1])) - n = 1 - i += 1 - if n == 1: - pass - if n == 2: - self.lineto(xscale(x2[0]), xscale(x2[1])) - if n == 3: - self.curveto(xscale(x2[0]), xscale(x2[1]), - xscale(x2[0]), xscale(x2[1]), - xscale(x3[0]), xscale(x3[1])) - self.stroke() - - def line(self, style, x1, y1, x2, y2): - if not style: - return - if invisible_p(x2, y2) and invisible_p(x1, y1): - return - - self.setbb(x1, y1) - self.setbb(x2, y2) - - self.newpath() - self.set_line_style(style) - self.moveto(xscale(x1), yscale(y1)) - self.lineto(xscale(x2), yscale(y2)) - self.stroke() - - def lines(self, style, segments): - if not style: - return - (xmin, ymin, xmax, ymax) = _compute_bounding_box(segments) - if invisible_p(xmax, ymax): - return - - self.setbb(xmin, ymin) - self.setbb(xmax, ymax) - self.newpath() - self.set_line_style(style) - self.moveto(xscale(segments[0][0]), xscale(segments[0][1])) - for i in range(1, len(segments)): - self.lineto(xscale(segments[i][0]), yscale(segments[i][1])) - self.stroke() - - def _path_round_rectangle(self, x1, y1, x2, y2, radius): - self.moveto(xscale(x1 + radius), yscale(y1)) - self.lineto(xscale(x2 - radius), yscale(y1)) - self.path_arc(xscale(x2-radius), yscale(y1+radius), nscale(radius), 1, 270, 360) - self.lineto(xscale(x2), yscale(y2-radius)) - self.path_arc(xscale(x2-radius), yscale(y2-radius), nscale(radius), 1, 0, 90) - self.lineto(xscale(x1+radius), yscale(y2)) - self.path_arc(xscale(x1 + radius), yscale(y2 - radius), nscale(radius), 1, 90, 180) - self.lineto(xscale(x1), xscale(y1+radius)) - self.path_arc(xscale(x1 + radius), yscale(y1 + radius), nscale(radius), 1, 180, 270) - - def round_rectangle(self, style, fill, x1, y1, x2, y2, radius, shadow=None): - """Draw a rectangle with rounded four corners. Parameter <radius> specifies the radius of each corner.""" - - if invisible_p(x2, y2): - return - self.setbb(x1, y1) - self.setbb(x2, y2) - - if fill: - if shadow: - x_off, y_off, shadow_fill = shadow - self.gsave(); - self.newpath() - self._path_round_rectangle(x1+x_off, y1+y_off, x2+x_off, y2+y_off, - radius) - self.closepath() - self.clip_sub() - self.fill_with_pattern(shadow_fill, x1+x_off, y1+y_off, - x2+x_off, y2+y_off) - self.grestore() - - self.gsave(); - self.newpath() - self._path_round_rectangle(x1, y1, x2, y2, radius) - self.closepath() - self.clip_sub() - self.fill_with_pattern(fill, x1, y1, x2, y2) - self.grestore() - if style: - self.set_line_style(style) - self.newpath() - self._path_round_rectangle(x1, y1, x2, y2, radius) - self.closepath() - self.stroke() - - def show(self, x, y, str): - global out - y_org = y - org_str = str - - if invisible_p(x, y): - return - - (xmin, xmax, ymin, ymax) = font.get_dimension(str) - - # rectangle(line_style.default, None, x+xmin, y+ymin, x+xmax, y+ymax) - # ellipsis(line_style.default, None, x, y, 1) - self.setbb(x+xmin, y+ymin) - self.setbb(x+xmax, y+ymax) - - (halign, valign, angle) = font.get_align(str) - - base_x = x - base_y = y - - # Handle vertical alignment - if valign == "B": - y = font.unaligned_text_height(str) - elif valign == "T": - y = 0 - elif valign == "M": - y = font.unaligned_text_height(str) / 2.0 - - (xmin, xmax, ymin, ymax) = font.get_dimension(org_str) - # print org_str, xmin, xmax, ymin, ymax, x, y_org, y - self.setbb(x+xmin, y_org+y+ymin) - self.setbb(x+xmax, y_org+y+ymax) - itr = font.text_iterator(None) - - max_width = 0 - - lines = [] - for line in str.split('\n'): - cur_width = 0 - cur_height = 0 - - itr.reset(line) - - strs = [] - - while 1: - elem = itr.next() - if not elem: - break - - (font_name, size, line_height, color, _h, _v, _a, str) = elem - cur_width += font.line_width(font_name, size, str) - max_width = max(cur_width, max_width) - cur_height = max(cur_height, line_height) - - # replace '(' -> '\(', ')' -> '\)' to make - # Postscript string parser happy. - str = str.replace("(", "\\(") - str = str.replace(")", "\\)") - strs.append((font_name, size, color, str)) - lines.append((cur_width, cur_height, strs)) - - for line in lines: - cur_width, cur_height, strs = line - cur_y = y - cur_height - y = y - cur_height - self.comment("cury: %d hei %d str %s\n" % (cur_y, cur_height, strs)) - if halign == 'C': - cur_x = -cur_width/2.0 - elif halign == 'R': - cur_x = -cur_width - else: - cur_x = 0 - - rel_x, rel_y = pychart_util.rotate(cur_x, cur_y, angle) - self.text_begin() - self.text_moveto(xscale(base_x + rel_x), - yscale(base_y + rel_y), angle) - for segment in strs: - font_name, size, color, str = segment - self.text_show(font_name, nscale(size), color, str) - self.text_end() - - diff --git a/openerp/pychart/canvas.py b/openerp/pychart/canvas.py deleted file mode 100644 index bb220954f59..00000000000 --- a/openerp/pychart/canvas.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import sys -import basecanvas -import pscanvas -import pdfcanvas -import svgcanvas -import pngcanvas -import x11canvas -import theme -import re - -invalid_coord = -999999 -_oldexitfunc = None - -T = basecanvas.T - -def init(fname = None, format = None): - - """This is a "factory" procedure that creates a new canvas.T object. - Both parameters, <fname> and - <format>, are optional. Parameter <fname> specifies either the output - file name or a file object. Parameter <format>, if specified, defines the - file's format. Its value must be one of "ps", "pdf", "svg", "x11", or - "png". - - When <fname> is omitted or is None, the output is sent to standard - output. When <format> is omitted, it is guessed from the <fname>'s - suffix; failing that, "ps" is selected.""" - - fname = fname or theme.output_file - format = format or theme.output_format - - if format == None: - if not isinstance(fname, str): - format = "ps" - elif re.search("pdf$", fname): - format = "pdf" - elif re.search("png$", fname): - format = "png" - elif re.search("svg$", fname): - format = "svg" - else: - format = "ps" - - if format == "ps": - can = pscanvas.T(fname) - elif format == "png": - can = pngcanvas.T(fname) - elif format == "x11": - can = x11canvas.T(fname) - elif format == "svg": - can = svgcanvas.T(fname) - else: - can = pdfcanvas.T(fname, theme.compress_output) - return can - -def default_canvas(): - if len(basecanvas.active_canvases) > 0: - return basecanvas.active_canvases[0] - else: - return init(None) - -def _exit(): - global _oldexitfunc, _active_canvases - - for can in basecanvas.active_canvases[:]: - can.close() - - if _oldexitfunc: - foo = _oldexitfunc - _oldexitfunc = None - foo() - -# -# The following procedures are there just for backward compatibility. -# -def line(style, x1, y1, x2, y2): - default_canvas().line(style, x1, y1, x2, y2) -def curve(style, points): - default_canvas().curve(style, points) -def clip(x1, y1, x2, y2): - default_canvas().clip(x1, y1, x2, y2) -def endclip(): - default_canvas().endclip() -def clip_polygon(points): - default_canvas().clip_polygon(points) -def clip_ellipsis(x, y, radius, ratio = 1.0): - default_canvas().clip_ellipsis(x, y, radius, ratio) -def ellipsis(line_style, pattern, x, y, radius, ratio = 1.0, - start_angle=0, end_angle=360, shadow=None): - default_canvas().ellipsis(line_style, pattern, x, y, radius, ratio, - start_angle, end_angle, shadow) -def rectangle(edge_style, pat, x1, y1, x2, y2, shadow = None): - default_canvas().rectangle(edge_style, pat, x1, y1, x2, y2, shadow) -def polygon(edge_style, pat, points, shadow = None): - default_canvas().polygon(edge_style, pat, points, shadow = None) -def close(): - default_canvas().close() -def round_rectangle(style, fill, x1, y1, x2, y2, radius, shadow=None): - default_canvas().round_rectangle(style, fill, x1, y1, x2, y2, radius, shadow) -def show(x, y, str): - default_canvas().show(x, y, str) - - -if not vars(sys).has_key("exitfunc"): - sys.exitfunc = _exit -elif sys.exitfunc != _exit: - _oldexitfunc = sys.exitfunc - sys.exitfunc = _exit - -#theme.add_reinitialization_hook(lambda: init(None)) diff --git a/openerp/pychart/category_coord.py b/openerp/pychart/category_coord.py deleted file mode 100644 index 60a3def7277..00000000000 --- a/openerp/pychart/category_coord.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import coord -import canvas - -class T(coord.T): - def __init__(self, data, col): - - """This attribute is meaningful only when x_coord_system == - 'category'. This attribute selects the column of - 'x_category_data' from which X values are computed. - Meaningful only when x_coord_system == 'category'. This - attribute specifies the data-set from which the X values are - extracted. See also x_category_col.""" - - self.data = data - self.col = col - - def get_canvas_pos(self, size, val, min, max): - i = 0.5 - for v in self.data: - if v[self.col] == val: - return size * i / float(len(self.data)) - i += 1 - # the drawing area is clipped. So negative offset will make this plot - # invisible. - return canvas.invalid_coord; - def get_tics(self, min, max, interval): - tics = [] - if interval == None: interval = 1 - - for i in range(0, len(self.data), interval): - tics.append(self.data[i][self.col]) - return tics - #return map(lambda pair, self = self: pair[self.col], self.data) - diff --git a/openerp/pychart/chart_data.py b/openerp/pychart/chart_data.py deleted file mode 100644 index dc805ee1762..00000000000 --- a/openerp/pychart/chart_data.py +++ /dev/null @@ -1,388 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import pychart_util -import copy -import math - -def _convert_item(v, typ, line): - if typ == "a": - try: - i = float(v) - except ValueError: # non-number - i = v - return i - elif typ == "d": - try: - return int(v) - except ValueError: - raise ValueError, "Can't convert %s to int; line=%s" % (v, line) - elif typ == "f": - try: - return float(v) - except ValueError: - raise ValueError, "Can't convert %s to float; line=%s" % (v, line) - elif typ == "s": - return v - else: - raise ValueError, "Unknown conversion type, type=%s; line=%s" % (typ,line) - -def parse_line(line, delim): - if delim.find("%") < 0: - return [ _convert_item(item, "a", None) for item in line.split(delim) ] - - data = [] - idx = 0 # indexes delim - ch = 'f' - sep = ',' - - while idx < len(delim): - if delim[idx] != '%': - raise ValueError, "bad delimitor: '" + delim + "'" - ch = delim[idx+1] - idx += 2 - sep = "" - while idx < len(delim) and delim[idx] != '%': - sep += delim[idx] - idx += 1 - xx = line.split(sep, 1) - data.append(_convert_item(xx[0], ch, line)) - if len(xx) >= 2: - line = xx[1] - else: - line = "" - break - - if line != "": - for item in line.split(sep): - data.append(_convert_item(item, ch, line)) - return data - -def escape_string(str): - return str.replace("/", "//") - -def extract_rows(data, *rows): - """Extract rows specified in the argument list. - ->>> chart_data.extract_rows([[10,20], [30,40], [50,60]], 1, 2) -[[30,40],[50,60]] -""" - try: - # for python 2.2 - # return [data[r] for r in rows] - out = [] - for r in rows: - out.append(data[r]) - return out - except IndexError: - raise IndexError, "data=%s rows=%s" % (data, rows) - return out - -def extract_columns(data, *cols): - """Extract columns specified in the argument list. - ->>> chart_data.extract_columns([[10,20], [30,40], [50,60]], 0) -[[10],[30],[50]] -""" - out = [] - try: - # for python 2.2: - # return [ [r[c] for c in cols] for r in data] - for r in data: - col = [] - for c in cols: - col.append(r[c]) - out.append(col) - except IndexError: - raise IndexError, "data=%s col=%s" % (data, col) - return out - - - - -def moving_average(data, xcol, ycol, width): - """Compute the moving average of YCOL'th column of each sample point -in DATA. In particular, for each element I in DATA, -this function extracts up to WIDTH*2+1 elements, consisting of - I itself, WIDTH elements before I, and WIDTH -elements after I. It then computes the mean of the YCOL'th -column of these elements, and it composes a two-element sample -consisting of XCOL'th element and the mean. - ->>> data = [[10,20], [20,30], [30,50], [40,70], [50,5]] -... chart_data.moving_average(data, 0, 1, 1) -[(10, 25.0), (20, 33.333333333333336), (30, 50.0), (40, 41.666666666666664), (50, 37.5)] - - The above value actually represents: - -[(10, (20+30)/2), (20, (20+30+50)/3), (30, (30+50+70)/3), - (40, (50+70+5)/3), (50, (70+5)/2)] - -""" - - - out = [] - try: - for i in range(len(data)): - n = 0 - total = 0 - for j in range(i-width, i+width+1): - if j >= 0 and j < len(data): - total += data[j][ycol] - n += 1 - out.append((data[i][xcol], float(total) / n)) - except IndexError: - raise IndexError, "bad data: %s,xcol=%d,ycol=%d,width=%d" % (data,xcol,ycol,width) - - return out - -def filter(func, data): - """Parameter <func> must be a single-argument - function that takes a sequence (i.e., -a sample point) and returns a boolean. This procedure calls <func> on -each element in <data> and returns a list comprising elements for -which <func> returns True. - ->>> data = [[1,5], [2,10], [3,13], [4,16]] -... chart_data.filter(lambda x: x[1] % 2 == 0, data) -[[2,10], [4,16]]. -""" - - out = [] - for r in data: - if func(r): - out.append(r) - return out - -def transform(func, data): - """Apply <func> on each element in <data> and return the list -consisting of the return values from <func>. - ->>> data = [[10,20], [30,40], [50,60]] -... chart_data.transform(lambda x: [x[0], x[1]+1], data) -[[10, 21], [30, 41], [50, 61]] - -""" - out = [] - for r in data: - out.append(func(r)) - return out - -def aggregate_rows(data, col): - out = copy.deepcopy(data) - total = 0 - for r in out: - total += r[col] - r[col] = total - return out - -def empty_line_p(s): - return s.strip() == "" - -def fread_csv(fd, delim = ','): - """This function is similar to read_csv, except that it reads from - an open file handle <fd>, or any object that provides method "readline". - -fd = open("foo", "r") -data = chart_data.fread_csv(fd, ",") """ - - data = [] - line = fd.readline() - while line != "": - if line[0] != '#' and not empty_line_p(line): - data.append(parse_line(line, delim)) - line = fd.readline() - return data - -def read_csv(path, delim = ','): - """This function reads - comma-separated values from file <path>. Empty lines and lines - beginning with "#" are ignored. Parameter <delim> specifies how - a line is separated into values. If it does not contain the - letter "%", then <delim> marks the end of a value. - Otherwise, this function acts like scanf in C: - -chart_data.read_csv("file", "%d,%s:%d") - - Paramter <delim> currently supports - only three conversion format specifiers: - "d"(int), "f"(double), and "s"(string).""" - - f = open(path) - data = fread_csv(f, delim) - f.close() - return data - -def fwrite_csv(fd, data): - """This function writes comma-separated <data> to <fd>. Parameter <fd> must be a file-like object - that supports the |write()| method.""" - for v in data: - fd.write(",".join([str(x) for x in v])) - fd.write("\n") - -def write_csv(path, data): - """This function writes comma-separated values to <path>.""" - fd = file(path, "w") - fwrite_csv(fd, data) - fd.close() - -def read_str(delim = ',', *lines): - """This function is similar to read_csv, but it reads data from the - list of <lines>. - -fd = open("foo", "r") -data = chart_data.read_str(",", fd.readlines())""" - - data = [] - for line in lines: - com = parse_line(line, delim) - data.append(com) - return data - -def func(f, xmin, xmax, step = None): - """Create sample points from function <f>, which must be a - single-parameter function that returns a number (e.g., math.sin). - Parameters <xmin> and <xmax> specify the first and last X values, and - <step> specifies the sampling interval. - ->>> chart_data.func(math.sin, 0, math.pi * 4, math.pi / 2) -[(0, 0.0), (1.5707963267948966, 1.0), (3.1415926535897931, 1.2246063538223773e-16), (4.7123889803846897, -1.0), (6.2831853071795862, -2.4492127076447545e-16), (7.8539816339744828, 1.0), (9.4247779607693793, 3.6738190614671318e-16), (10.995574287564276, -1.0)] - -""" - - data = [] - x = xmin - if not step: - step = (xmax - xmin) / 100.0 - while x < xmax: - data.append((x, f(x))) - x += step - return data - -def _nr_data(data, col): - nr_data = 0 - for d in data: - nr_data += d[col] - return nr_data - -def median(data, freq_col=1): - """Compute the median of the <freq_col>'th column of the values is <data>. - ->>> chart_data.median([(10,20), (20,4), (30,5)], 0) -20 ->>> chart_data.median([(10,20), (20,4), (30,5)], 1) -5. - """ - - nr_data = _nr_data(data, freq_col) - median_idx = nr_data / 2 - i = 0 - for d in data: - i += d[freq_col] - if i >= median_idx: - return d - raise Exception, "??? median ???" - -def cut_extremes(data, cutoff_percentage, freq_col=1): - nr_data = _nr_data(data, freq_col) - min_idx = nr_data * cutoff_percentage / 100.0 - max_idx = nr_data * (100 - cutoff_percentage) / 100.0 - r = [] - - i = 0 - for d in data: - if i < min_idx: - if i + d[freq_col] >= min_idx: - x = copy.deepcopy(d) - x[freq_col] = x[freq_col] - (min_idx - i) - r.append(x) - i += d[freq_col] - continue - elif i + d[freq_col] >= max_idx: - if i < max_idx and i + d[freq_col] >= max_idx: - x = copy.deepcopy(d) - x[freq_col] = x[freq_col] - (max_idx - i) - r.append(x) - break - i += d[freq_col] - r.append(d) - return r - -def mean(data, val_col, freq_col): - nr_data = 0 - sum = 0 - for d in data: - sum += d[val_col] * d[freq_col] - nr_data += d[freq_col] - if nr_data == 0: - raise IndexError, "data is empty" - - return sum / float(nr_data) - -def mean_samples(data, xcol, ycollist): - """Create a sample list that contains - the mean of the original list. - ->>> chart_data.mean_samples([ [1, 10, 15], [2, 5, 10], [3, 8, 33] ], 0, (1, 2)) -[(1, 12.5), (2, 7.5), (3, 20.5)] -""" - out = [] - numcol = len(ycollist) - try: - for elem in data: - v = 0 - for col in ycollist: - v += elem[col] - out.append( (elem[xcol], float(v) / numcol) ) - except IndexError: - raise IndexError, "bad data: %s,xcol=%d,ycollist=%s" % (data,xcol,ycollist) - - return out - -def stddev_samples(data, xcol, ycollist, delta = 1.0): - """Create a sample list that contains the mean and standard deviation of the original list. Each element in the returned list contains following values: [MEAN, STDDEV, MEAN - STDDEV*delta, MEAN + STDDEV*delta]. - ->>> chart_data.stddev_samples([ [1, 10, 15, 12, 15], [2, 5, 10, 5, 10], [3, 32, 33, 35, 36], [4,16,66, 67, 68] ], 0, range(1,5)) -[(1, 13.0, 2.1213203435596424, 10.878679656440358, 15.121320343559642), (2, 7.5, 2.5, 5.0, 10.0), (3, 34.0, 1.5811388300841898, 32.418861169915807, 35.581138830084193), (4, 54.25, 22.094965489902897, 32.155034510097103, 76.344965489902904)] -""" - out = [] - numcol = len(ycollist) - try: - for elem in data: - total = 0 - for col in ycollist: - total += elem[col] - mean = float(total) / numcol - variance = 0 - for col in ycollist: - variance += (mean - elem[col]) ** 2 - stddev = math.sqrt(variance / numcol) * delta - out.append( (elem[xcol], mean, stddev, mean-stddev, mean+stddev) ) - - - - except IndexError: - raise IndexError, "bad data: %s,xcol=%d,ycollist=%s" % (data,xcol,ycollist) - return out - -def nearest_match(data, col, val): - min_delta = None - match = None - - for d in data: - if min_delta == None or abs(d[col] - val) < min_delta: - min_delta = abs(d[col] - val) - match = d - pychart_util.warn("XXX ", match) - return match diff --git a/openerp/pychart/chart_object.py b/openerp/pychart/chart_object.py deleted file mode 100644 index 7ebfc1829c1..00000000000 --- a/openerp/pychart/chart_object.py +++ /dev/null @@ -1,74 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import pychart_types -import types - -def _check_attr_types(obj, keys): - for attr in obj.__dict__.keys(): - if not keys.has_key(attr): - raise Exception, "%s: unknown attribute '%s'" % (obj, attr) - - typeval, default_value, docstring = keys[attr][0:3] - val = getattr(obj, attr) - if val == None or typeval == pychart_types.AnyType: - pass - elif isinstance(typeval, types.FunctionType): - # user-defined check procedure - error = apply(typeval, (val,)) - if error != None: - raise Exception, "%s: %s for attribute '%s', but got '%s'" % (obj, error, attr, val) - elif 1: - try: - if isinstance(val, typeval): - pass - except: - raise Exception, "%s: Expecting type %s, but got %s (attr=%s, %s)" % (obj, typeval, val, attr, keys[attr]) - - else: - raise Exception, "%s: attribute '%s' expects type %s but found %s" % (obj, attr, typeval, val) - -def set_defaults(cls, **dict): - validAttrs = getattr(cls, "keys") - for attr, val in dict.items(): - if not validAttrs.has_key(attr): - raise Exception, "%s: unknown attribute %s." % (cls, attr) - tuple = list(validAttrs[attr]) - # 0 : type - # 1: defaultValue - # 2: document - # 3: defaultValue document (optional) - tuple[1] = val - validAttrs[attr] = tuple - -class T(object): - def init(self, args): - keys = self.keys - for attr, tuple in keys.items(): - defaultVal = tuple[1] - if isinstance(defaultVal, types.FunctionType): - # if the value is procedure, use the result of the proc call - # as the default value - defaultVal = apply(defaultVal, ()) - setattr(self, attr, defaultVal) - - for key, val in args.items(): - setattr(self, key, val) - _check_attr_types(self, keys) - - def __init__(self, **args): - self.init(args) - - def type_check(self): - _check_attr_types(self, self.keys) diff --git a/openerp/pychart/color.py b/openerp/pychart/color.py deleted file mode 100644 index 30b1cc9b00d..00000000000 --- a/openerp/pychart/color.py +++ /dev/null @@ -1,612 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import chart_object -import object_set -import types -import theme -import pychart_util -import color_doc -from pychart_types import * - -blackify_colors = 1 - -class T(chart_object.T): - __doc__ = color_doc.doc - keys={ - "r" : (NumType, 0.0, "The intensity of red. The value is between 0 and 1."), - "g" : (NumType, 0.0, "The intensity of green. The value is between 0 and 1."), - "b" : (NumType, 0.0, "The intensity of blue. The value is between 0 and 1.") - } -##AUTOMATICALLY GENERATED -##END AUTOMATICALLY GENERATED - def __str__(self): - s = name_table().lookup(self) - if s: - return s - if self.r == self.g and self.r == self.b: - return "<color:grayscale=%f>" % self.r - else: - return "<color:r=%f,g=%f,b=%f>" % (self.r, self.g, self.b) - -standards = object_set.T() -def _intern(r,g,b): - c = T(r = r, g = g, b = b) - standards.add(c) - return c - -def gray_scale(g): - """Generate a grayscale color.T object. G=0 produces white, G=1.0 - produces black.""" - return T(r=g,g=g,b=g) - -# generated automatically from rgb.txt - -snow = _intern(r=1.000000,g=0.980392,b=0.980392) -ghostwhite = _intern(r=0.972549,g=0.972549,b=1.000000) -whitesmoke = _intern(r=0.960784,g=0.960784,b=0.960784) -gainsboro = _intern(r=0.862745,g=0.862745,b=0.862745) -floralwhite = _intern(r=1.000000,g=0.980392,b=0.941176) -oldlace = _intern(r=0.992157,g=0.960784,b=0.901961) -linen = _intern(r=0.980392,g=0.941176,b=0.901961) -antiquewhite = _intern(r=0.980392,g=0.921569,b=0.843137) -papayawhip = _intern(r=1.000000,g=0.937255,b=0.835294) -blanchedalmond = _intern(r=1.000000,g=0.921569,b=0.803922) -bisque = _intern(r=1.000000,g=0.894118,b=0.768627) -peachpuff = _intern(r=1.000000,g=0.854902,b=0.725490) -navajowhite = _intern(r=1.000000,g=0.870588,b=0.678431) -moccasin = _intern(r=1.000000,g=0.894118,b=0.709804) -cornsilk = _intern(r=1.000000,g=0.972549,b=0.862745) -ivory = _intern(r=1.000000,g=1.000000,b=0.941176) -lemonchiffon = _intern(r=1.000000,g=0.980392,b=0.803922) -seashell = _intern(r=1.000000,g=0.960784,b=0.933333) -honeydew = _intern(r=0.941176,g=1.000000,b=0.941176) -mintcream = _intern(r=0.960784,g=1.000000,b=0.980392) -azure = _intern(r=0.941176,g=1.000000,b=1.000000) -aliceblue = _intern(r=0.941176,g=0.972549,b=1.000000) -lavender = _intern(r=0.901961,g=0.901961,b=0.980392) -lavenderblush = _intern(r=1.000000,g=0.941176,b=0.960784) -mistyrose = _intern(r=1.000000,g=0.894118,b=0.882353) -white = _intern(r=1.000000,g=1.000000,b=1.000000) -black = _intern(r=0.000000,g=0.000000,b=0.000000) -darkslategray = _intern(r=0.184314,g=0.309804,b=0.309804) -dimgray = _intern(r=0.411765,g=0.411765,b=0.411765) -slategray = _intern(r=0.439216,g=0.501961,b=0.564706) -lightslategray = _intern(r=0.466667,g=0.533333,b=0.600000) -gray = _intern(r=0.745098,g=0.745098,b=0.745098) -lightgray = _intern(r=0.827451,g=0.827451,b=0.827451) -midnightblue = _intern(r=0.098039,g=0.098039,b=0.439216) -navy = _intern(r=0.000000,g=0.000000,b=0.501961) -navyblue = _intern(r=0.000000,g=0.000000,b=0.501961) -cornflowerblue = _intern(r=0.392157,g=0.584314,b=0.929412) -darkslateblue = _intern(r=0.282353,g=0.239216,b=0.545098) -slateblue = _intern(r=0.415686,g=0.352941,b=0.803922) -mediumslateblue = _intern(r=0.482353,g=0.407843,b=0.933333) -lightslateblue = _intern(r=0.517647,g=0.439216,b=1.000000) -mediumblue = _intern(r=0.000000,g=0.000000,b=0.803922) -royalblue = _intern(r=0.254902,g=0.411765,b=0.882353) -blue = _intern(r=0.000000,g=0.000000,b=1.000000) -dodgerblue = _intern(r=0.117647,g=0.564706,b=1.000000) -deepskyblue = _intern(r=0.000000,g=0.749020,b=1.000000) -skyblue = _intern(r=0.529412,g=0.807843,b=0.921569) -lightskyblue = _intern(r=0.529412,g=0.807843,b=0.980392) -steelblue = _intern(r=0.274510,g=0.509804,b=0.705882) -lightsteelblue = _intern(r=0.690196,g=0.768627,b=0.870588) -lightblue = _intern(r=0.678431,g=0.847059,b=0.901961) -powderblue = _intern(r=0.690196,g=0.878431,b=0.901961) -paleturquoise = _intern(r=0.686275,g=0.933333,b=0.933333) -darkturquoise = _intern(r=0.000000,g=0.807843,b=0.819608) -mediumturquoise = _intern(r=0.282353,g=0.819608,b=0.800000) -turquoise = _intern(r=0.250980,g=0.878431,b=0.815686) -cyan = _intern(r=0.000000,g=1.000000,b=1.000000) -lightcyan = _intern(r=0.878431,g=1.000000,b=1.000000) -cadetblue = _intern(r=0.372549,g=0.619608,b=0.627451) -mediumaquamarine = _intern(r=0.400000,g=0.803922,b=0.666667) -aquamarine = _intern(r=0.498039,g=1.000000,b=0.831373) -darkgreen = _intern(r=0.000000,g=0.392157,b=0.000000) -darkolivegreen = _intern(r=0.333333,g=0.419608,b=0.184314) -darkseagreen = _intern(r=0.560784,g=0.737255,b=0.560784) -seagreen = _intern(r=0.180392,g=0.545098,b=0.341176) -mediumseagreen = _intern(r=0.235294,g=0.701961,b=0.443137) -lightseagreen = _intern(r=0.125490,g=0.698039,b=0.666667) -palegreen = _intern(r=0.596078,g=0.984314,b=0.596078) -springgreen = _intern(r=0.000000,g=1.000000,b=0.498039) -lawngreen = _intern(r=0.486275,g=0.988235,b=0.000000) -green = _intern(r=0.000000,g=1.000000,b=0.000000) -chartreuse = _intern(r=0.498039,g=1.000000,b=0.000000) -mediumspringgreen = _intern(r=0.000000,g=0.980392,b=0.603922) -greenyellow = _intern(r=0.678431,g=1.000000,b=0.184314) -limegreen = _intern(r=0.196078,g=0.803922,b=0.196078) -yellowgreen = _intern(r=0.603922,g=0.803922,b=0.196078) -forestgreen = _intern(r=0.133333,g=0.545098,b=0.133333) -olivedrab = _intern(r=0.419608,g=0.556863,b=0.137255) -darkkhaki = _intern(r=0.741176,g=0.717647,b=0.419608) -khaki = _intern(r=0.941176,g=0.901961,b=0.549020) -palegoldenrod = _intern(r=0.933333,g=0.909804,b=0.666667) -lightgoldenrodyellow = _intern(r=0.980392,g=0.980392,b=0.823529) -lightyellow = _intern(r=1.000000,g=1.000000,b=0.878431) -yellow = _intern(r=1.000000,g=1.000000,b=0.000000) -gold = _intern(r=1.000000,g=0.843137,b=0.000000) -lightgoldenrod = _intern(r=0.933333,g=0.866667,b=0.509804) -goldenrod = _intern(r=0.854902,g=0.647059,b=0.125490) -darkgoldenrod = _intern(r=0.721569,g=0.525490,b=0.043137) -rosybrown = _intern(r=0.737255,g=0.560784,b=0.560784) -indianred = _intern(r=0.803922,g=0.360784,b=0.360784) -saddlebrown = _intern(r=0.545098,g=0.270588,b=0.074510) -sienna = _intern(r=0.627451,g=0.321569,b=0.176471) -peru = _intern(r=0.803922,g=0.521569,b=0.247059) -burlywood = _intern(r=0.870588,g=0.721569,b=0.529412) -beige = _intern(r=0.960784,g=0.960784,b=0.862745) -wheat = _intern(r=0.960784,g=0.870588,b=0.701961) -sandybrown = _intern(r=0.956863,g=0.643137,b=0.376471) -tan = _intern(r=0.823529,g=0.705882,b=0.549020) -chocolate = _intern(r=0.823529,g=0.411765,b=0.117647) -firebrick = _intern(r=0.698039,g=0.133333,b=0.133333) -brown = _intern(r=0.647059,g=0.164706,b=0.164706) -darksalmon = _intern(r=0.913725,g=0.588235,b=0.478431) -salmon = _intern(r=0.980392,g=0.501961,b=0.447059) -lightsalmon = _intern(r=1.000000,g=0.627451,b=0.478431) -orange = _intern(r=1.000000,g=0.647059,b=0.000000) -darkorange = _intern(r=1.000000,g=0.549020,b=0.000000) -coral = _intern(r=1.000000,g=0.498039,b=0.313725) -lightcoral = _intern(r=0.941176,g=0.501961,b=0.501961) -tomato = _intern(r=1.000000,g=0.388235,b=0.278431) -orangered = _intern(r=1.000000,g=0.270588,b=0.000000) -red = _intern(r=1.000000,g=0.000000,b=0.000000) -hotpink = _intern(r=1.000000,g=0.411765,b=0.705882) -deeppink = _intern(r=1.000000,g=0.078431,b=0.576471) -pink = _intern(r=1.000000,g=0.752941,b=0.796078) -lightpink = _intern(r=1.000000,g=0.713725,b=0.756863) -palevioletred = _intern(r=0.858824,g=0.439216,b=0.576471) -maroon = _intern(r=0.690196,g=0.188235,b=0.376471) -mediumvioletred = _intern(r=0.780392,g=0.082353,b=0.521569) -violetred = _intern(r=0.815686,g=0.125490,b=0.564706) -magenta = _intern(r=1.000000,g=0.000000,b=1.000000) -violet = _intern(r=0.933333,g=0.509804,b=0.933333) -plum = _intern(r=0.866667,g=0.627451,b=0.866667) -orchid = _intern(r=0.854902,g=0.439216,b=0.839216) -mediumorchid = _intern(r=0.729412,g=0.333333,b=0.827451) -darkorchid = _intern(r=0.600000,g=0.196078,b=0.800000) -darkviolet = _intern(r=0.580392,g=0.000000,b=0.827451) -blueviolet = _intern(r=0.541176,g=0.168627,b=0.886275) -purple = _intern(r=0.627451,g=0.125490,b=0.941176) -mediumpurple = _intern(r=0.576471,g=0.439216,b=0.858824) -thistle = _intern(r=0.847059,g=0.749020,b=0.847059) -snow1 = _intern(r=1.000000,g=0.980392,b=0.980392) -snow2 = _intern(r=0.933333,g=0.913725,b=0.913725) -snow3 = _intern(r=0.803922,g=0.788235,b=0.788235) -snow4 = _intern(r=0.545098,g=0.537255,b=0.537255) -seashell1 = _intern(r=1.000000,g=0.960784,b=0.933333) -seashell2 = _intern(r=0.933333,g=0.898039,b=0.870588) -seashell3 = _intern(r=0.803922,g=0.772549,b=0.749020) -seashell4 = _intern(r=0.545098,g=0.525490,b=0.509804) -antiquewhite1 = _intern(r=1.000000,g=0.937255,b=0.858824) -antiquewhite2 = _intern(r=0.933333,g=0.874510,b=0.800000) -antiquewhite3 = _intern(r=0.803922,g=0.752941,b=0.690196) -antiquewhite4 = _intern(r=0.545098,g=0.513725,b=0.470588) -bisque1 = _intern(r=1.000000,g=0.894118,b=0.768627) -bisque2 = _intern(r=0.933333,g=0.835294,b=0.717647) -bisque3 = _intern(r=0.803922,g=0.717647,b=0.619608) -bisque4 = _intern(r=0.545098,g=0.490196,b=0.419608) -peachpuff1 = _intern(r=1.000000,g=0.854902,b=0.725490) -peachpuff2 = _intern(r=0.933333,g=0.796078,b=0.678431) -peachpuff3 = _intern(r=0.803922,g=0.686275,b=0.584314) -peachpuff4 = _intern(r=0.545098,g=0.466667,b=0.396078) -navajowhite1 = _intern(r=1.000000,g=0.870588,b=0.678431) -navajowhite2 = _intern(r=0.933333,g=0.811765,b=0.631373) -navajowhite3 = _intern(r=0.803922,g=0.701961,b=0.545098) -navajowhite4 = _intern(r=0.545098,g=0.474510,b=0.368627) -lemonchiffon1 = _intern(r=1.000000,g=0.980392,b=0.803922) -lemonchiffon2 = _intern(r=0.933333,g=0.913725,b=0.749020) -lemonchiffon3 = _intern(r=0.803922,g=0.788235,b=0.647059) -lemonchiffon4 = _intern(r=0.545098,g=0.537255,b=0.439216) -cornsilk1 = _intern(r=1.000000,g=0.972549,b=0.862745) -cornsilk2 = _intern(r=0.933333,g=0.909804,b=0.803922) -cornsilk3 = _intern(r=0.803922,g=0.784314,b=0.694118) -cornsilk4 = _intern(r=0.545098,g=0.533333,b=0.470588) -ivory1 = _intern(r=1.000000,g=1.000000,b=0.941176) -ivory2 = _intern(r=0.933333,g=0.933333,b=0.878431) -ivory3 = _intern(r=0.803922,g=0.803922,b=0.756863) -ivory4 = _intern(r=0.545098,g=0.545098,b=0.513725) -honeydew1 = _intern(r=0.941176,g=1.000000,b=0.941176) -honeydew2 = _intern(r=0.878431,g=0.933333,b=0.878431) -honeydew3 = _intern(r=0.756863,g=0.803922,b=0.756863) -honeydew4 = _intern(r=0.513725,g=0.545098,b=0.513725) -lavenderblush1 = _intern(r=1.000000,g=0.941176,b=0.960784) -lavenderblush2 = _intern(r=0.933333,g=0.878431,b=0.898039) -lavenderblush3 = _intern(r=0.803922,g=0.756863,b=0.772549) -lavenderblush4 = _intern(r=0.545098,g=0.513725,b=0.525490) -mistyrose1 = _intern(r=1.000000,g=0.894118,b=0.882353) -mistyrose2 = _intern(r=0.933333,g=0.835294,b=0.823529) -mistyrose3 = _intern(r=0.803922,g=0.717647,b=0.709804) -mistyrose4 = _intern(r=0.545098,g=0.490196,b=0.482353) -azure1 = _intern(r=0.941176,g=1.000000,b=1.000000) -azure2 = _intern(r=0.878431,g=0.933333,b=0.933333) -azure3 = _intern(r=0.756863,g=0.803922,b=0.803922) -azure4 = _intern(r=0.513725,g=0.545098,b=0.545098) -slateblue1 = _intern(r=0.513725,g=0.435294,b=1.000000) -slateblue2 = _intern(r=0.478431,g=0.403922,b=0.933333) -slateblue3 = _intern(r=0.411765,g=0.349020,b=0.803922) -slateblue4 = _intern(r=0.278431,g=0.235294,b=0.545098) -royalblue1 = _intern(r=0.282353,g=0.462745,b=1.000000) -royalblue2 = _intern(r=0.262745,g=0.431373,b=0.933333) -royalblue3 = _intern(r=0.227451,g=0.372549,b=0.803922) -royalblue4 = _intern(r=0.152941,g=0.250980,b=0.545098) -blue1 = _intern(r=0.000000,g=0.000000,b=1.000000) -blue2 = _intern(r=0.000000,g=0.000000,b=0.933333) -blue3 = _intern(r=0.000000,g=0.000000,b=0.803922) -blue4 = _intern(r=0.000000,g=0.000000,b=0.545098) -dodgerblue1 = _intern(r=0.117647,g=0.564706,b=1.000000) -dodgerblue2 = _intern(r=0.109804,g=0.525490,b=0.933333) -dodgerblue3 = _intern(r=0.094118,g=0.454902,b=0.803922) -dodgerblue4 = _intern(r=0.062745,g=0.305882,b=0.545098) -steelblue1 = _intern(r=0.388235,g=0.721569,b=1.000000) -steelblue2 = _intern(r=0.360784,g=0.674510,b=0.933333) -steelblue3 = _intern(r=0.309804,g=0.580392,b=0.803922) -steelblue4 = _intern(r=0.211765,g=0.392157,b=0.545098) -deepskyblue1 = _intern(r=0.000000,g=0.749020,b=1.000000) -deepskyblue2 = _intern(r=0.000000,g=0.698039,b=0.933333) -deepskyblue3 = _intern(r=0.000000,g=0.603922,b=0.803922) -deepskyblue4 = _intern(r=0.000000,g=0.407843,b=0.545098) -skyblue1 = _intern(r=0.529412,g=0.807843,b=1.000000) -skyblue2 = _intern(r=0.494118,g=0.752941,b=0.933333) -skyblue3 = _intern(r=0.423529,g=0.650980,b=0.803922) -skyblue4 = _intern(r=0.290196,g=0.439216,b=0.545098) -lightskyblue1 = _intern(r=0.690196,g=0.886275,b=1.000000) -lightskyblue2 = _intern(r=0.643137,g=0.827451,b=0.933333) -lightskyblue3 = _intern(r=0.552941,g=0.713725,b=0.803922) -lightskyblue4 = _intern(r=0.376471,g=0.482353,b=0.545098) -slategray1 = _intern(r=0.776471,g=0.886275,b=1.000000) -slategray2 = _intern(r=0.725490,g=0.827451,b=0.933333) -slategray3 = _intern(r=0.623529,g=0.713725,b=0.803922) -slategray4 = _intern(r=0.423529,g=0.482353,b=0.545098) -lightsteelblue1 = _intern(r=0.792157,g=0.882353,b=1.000000) -lightsteelblue2 = _intern(r=0.737255,g=0.823529,b=0.933333) -lightsteelblue3 = _intern(r=0.635294,g=0.709804,b=0.803922) -lightsteelblue4 = _intern(r=0.431373,g=0.482353,b=0.545098) -lightblue1 = _intern(r=0.749020,g=0.937255,b=1.000000) -lightblue2 = _intern(r=0.698039,g=0.874510,b=0.933333) -lightblue3 = _intern(r=0.603922,g=0.752941,b=0.803922) -lightblue4 = _intern(r=0.407843,g=0.513725,b=0.545098) -lightcyan1 = _intern(r=0.878431,g=1.000000,b=1.000000) -lightcyan2 = _intern(r=0.819608,g=0.933333,b=0.933333) -lightcyan3 = _intern(r=0.705882,g=0.803922,b=0.803922) -lightcyan4 = _intern(r=0.478431,g=0.545098,b=0.545098) -paleturquoise1 = _intern(r=0.733333,g=1.000000,b=1.000000) -paleturquoise2 = _intern(r=0.682353,g=0.933333,b=0.933333) -paleturquoise3 = _intern(r=0.588235,g=0.803922,b=0.803922) -paleturquoise4 = _intern(r=0.400000,g=0.545098,b=0.545098) -cadetblue1 = _intern(r=0.596078,g=0.960784,b=1.000000) -cadetblue2 = _intern(r=0.556863,g=0.898039,b=0.933333) -cadetblue3 = _intern(r=0.478431,g=0.772549,b=0.803922) -cadetblue4 = _intern(r=0.325490,g=0.525490,b=0.545098) -turquoise1 = _intern(r=0.000000,g=0.960784,b=1.000000) -turquoise2 = _intern(r=0.000000,g=0.898039,b=0.933333) -turquoise3 = _intern(r=0.000000,g=0.772549,b=0.803922) -turquoise4 = _intern(r=0.000000,g=0.525490,b=0.545098) -cyan1 = _intern(r=0.000000,g=1.000000,b=1.000000) -cyan2 = _intern(r=0.000000,g=0.933333,b=0.933333) -cyan3 = _intern(r=0.000000,g=0.803922,b=0.803922) -cyan4 = _intern(r=0.000000,g=0.545098,b=0.545098) -darkslategray1 = _intern(r=0.592157,g=1.000000,b=1.000000) -darkslategray2 = _intern(r=0.552941,g=0.933333,b=0.933333) -darkslategray3 = _intern(r=0.474510,g=0.803922,b=0.803922) -darkslategray4 = _intern(r=0.321569,g=0.545098,b=0.545098) -aquamarine1 = _intern(r=0.498039,g=1.000000,b=0.831373) -aquamarine2 = _intern(r=0.462745,g=0.933333,b=0.776471) -aquamarine3 = _intern(r=0.400000,g=0.803922,b=0.666667) -aquamarine4 = _intern(r=0.270588,g=0.545098,b=0.454902) -darkseagreen1 = _intern(r=0.756863,g=1.000000,b=0.756863) -darkseagreen2 = _intern(r=0.705882,g=0.933333,b=0.705882) -darkseagreen3 = _intern(r=0.607843,g=0.803922,b=0.607843) -darkseagreen4 = _intern(r=0.411765,g=0.545098,b=0.411765) -seagreen1 = _intern(r=0.329412,g=1.000000,b=0.623529) -seagreen2 = _intern(r=0.305882,g=0.933333,b=0.580392) -seagreen3 = _intern(r=0.262745,g=0.803922,b=0.501961) -seagreen4 = _intern(r=0.180392,g=0.545098,b=0.341176) -palegreen1 = _intern(r=0.603922,g=1.000000,b=0.603922) -palegreen2 = _intern(r=0.564706,g=0.933333,b=0.564706) -palegreen3 = _intern(r=0.486275,g=0.803922,b=0.486275) -palegreen4 = _intern(r=0.329412,g=0.545098,b=0.329412) -springgreen1 = _intern(r=0.000000,g=1.000000,b=0.498039) -springgreen2 = _intern(r=0.000000,g=0.933333,b=0.462745) -springgreen3 = _intern(r=0.000000,g=0.803922,b=0.400000) -springgreen4 = _intern(r=0.000000,g=0.545098,b=0.270588) -green1 = _intern(r=0.000000,g=1.000000,b=0.000000) -green2 = _intern(r=0.000000,g=0.933333,b=0.000000) -green3 = _intern(r=0.000000,g=0.803922,b=0.000000) -green4 = _intern(r=0.000000,g=0.545098,b=0.000000) -chartreuse1 = _intern(r=0.498039,g=1.000000,b=0.000000) -chartreuse2 = _intern(r=0.462745,g=0.933333,b=0.000000) -chartreuse3 = _intern(r=0.400000,g=0.803922,b=0.000000) -chartreuse4 = _intern(r=0.270588,g=0.545098,b=0.000000) -olivedrab1 = _intern(r=0.752941,g=1.000000,b=0.243137) -olivedrab2 = _intern(r=0.701961,g=0.933333,b=0.227451) -olivedrab3 = _intern(r=0.603922,g=0.803922,b=0.196078) -olivedrab4 = _intern(r=0.411765,g=0.545098,b=0.133333) -darkolivegreen1 = _intern(r=0.792157,g=1.000000,b=0.439216) -darkolivegreen2 = _intern(r=0.737255,g=0.933333,b=0.407843) -darkolivegreen3 = _intern(r=0.635294,g=0.803922,b=0.352941) -darkolivegreen4 = _intern(r=0.431373,g=0.545098,b=0.239216) -khaki1 = _intern(r=1.000000,g=0.964706,b=0.560784) -khaki2 = _intern(r=0.933333,g=0.901961,b=0.521569) -khaki3 = _intern(r=0.803922,g=0.776471,b=0.450980) -khaki4 = _intern(r=0.545098,g=0.525490,b=0.305882) -lightgoldenrod1 = _intern(r=1.000000,g=0.925490,b=0.545098) -lightgoldenrod2 = _intern(r=0.933333,g=0.862745,b=0.509804) -lightgoldenrod3 = _intern(r=0.803922,g=0.745098,b=0.439216) -lightgoldenrod4 = _intern(r=0.545098,g=0.505882,b=0.298039) -lightyellow1 = _intern(r=1.000000,g=1.000000,b=0.878431) -lightyellow2 = _intern(r=0.933333,g=0.933333,b=0.819608) -lightyellow3 = _intern(r=0.803922,g=0.803922,b=0.705882) -lightyellow4 = _intern(r=0.545098,g=0.545098,b=0.478431) -yellow1 = _intern(r=1.000000,g=1.000000,b=0.000000) -yellow2 = _intern(r=0.933333,g=0.933333,b=0.000000) -yellow3 = _intern(r=0.803922,g=0.803922,b=0.000000) -yellow4 = _intern(r=0.545098,g=0.545098,b=0.000000) -gold1 = _intern(r=1.000000,g=0.843137,b=0.000000) -gold2 = _intern(r=0.933333,g=0.788235,b=0.000000) -gold3 = _intern(r=0.803922,g=0.678431,b=0.000000) -gold4 = _intern(r=0.545098,g=0.458824,b=0.000000) -goldenrod1 = _intern(r=1.000000,g=0.756863,b=0.145098) -goldenrod2 = _intern(r=0.933333,g=0.705882,b=0.133333) -goldenrod3 = _intern(r=0.803922,g=0.607843,b=0.113725) -goldenrod4 = _intern(r=0.545098,g=0.411765,b=0.078431) -darkgoldenrod1 = _intern(r=1.000000,g=0.725490,b=0.058824) -darkgoldenrod2 = _intern(r=0.933333,g=0.678431,b=0.054902) -darkgoldenrod3 = _intern(r=0.803922,g=0.584314,b=0.047059) -darkgoldenrod4 = _intern(r=0.545098,g=0.396078,b=0.031373) -rosybrown1 = _intern(r=1.000000,g=0.756863,b=0.756863) -rosybrown2 = _intern(r=0.933333,g=0.705882,b=0.705882) -rosybrown3 = _intern(r=0.803922,g=0.607843,b=0.607843) -rosybrown4 = _intern(r=0.545098,g=0.411765,b=0.411765) -indianred1 = _intern(r=1.000000,g=0.415686,b=0.415686) -indianred2 = _intern(r=0.933333,g=0.388235,b=0.388235) -indianred3 = _intern(r=0.803922,g=0.333333,b=0.333333) -indianred4 = _intern(r=0.545098,g=0.227451,b=0.227451) -sienna1 = _intern(r=1.000000,g=0.509804,b=0.278431) -sienna2 = _intern(r=0.933333,g=0.474510,b=0.258824) -sienna3 = _intern(r=0.803922,g=0.407843,b=0.223529) -sienna4 = _intern(r=0.545098,g=0.278431,b=0.149020) -burlywood1 = _intern(r=1.000000,g=0.827451,b=0.607843) -burlywood2 = _intern(r=0.933333,g=0.772549,b=0.568627) -burlywood3 = _intern(r=0.803922,g=0.666667,b=0.490196) -burlywood4 = _intern(r=0.545098,g=0.450980,b=0.333333) -wheat1 = _intern(r=1.000000,g=0.905882,b=0.729412) -wheat2 = _intern(r=0.933333,g=0.847059,b=0.682353) -wheat3 = _intern(r=0.803922,g=0.729412,b=0.588235) -wheat4 = _intern(r=0.545098,g=0.494118,b=0.400000) -tan1 = _intern(r=1.000000,g=0.647059,b=0.309804) -tan2 = _intern(r=0.933333,g=0.603922,b=0.286275) -tan3 = _intern(r=0.803922,g=0.521569,b=0.247059) -tan4 = _intern(r=0.545098,g=0.352941,b=0.168627) -chocolate1 = _intern(r=1.000000,g=0.498039,b=0.141176) -chocolate2 = _intern(r=0.933333,g=0.462745,b=0.129412) -chocolate3 = _intern(r=0.803922,g=0.400000,b=0.113725) -chocolate4 = _intern(r=0.545098,g=0.270588,b=0.074510) -firebrick1 = _intern(r=1.000000,g=0.188235,b=0.188235) -firebrick2 = _intern(r=0.933333,g=0.172549,b=0.172549) -firebrick3 = _intern(r=0.803922,g=0.149020,b=0.149020) -firebrick4 = _intern(r=0.545098,g=0.101961,b=0.101961) -brown1 = _intern(r=1.000000,g=0.250980,b=0.250980) -brown2 = _intern(r=0.933333,g=0.231373,b=0.231373) -brown3 = _intern(r=0.803922,g=0.200000,b=0.200000) -brown4 = _intern(r=0.545098,g=0.137255,b=0.137255) -salmon1 = _intern(r=1.000000,g=0.549020,b=0.411765) -salmon2 = _intern(r=0.933333,g=0.509804,b=0.384314) -salmon3 = _intern(r=0.803922,g=0.439216,b=0.329412) -salmon4 = _intern(r=0.545098,g=0.298039,b=0.223529) -lightsalmon1 = _intern(r=1.000000,g=0.627451,b=0.478431) -lightsalmon2 = _intern(r=0.933333,g=0.584314,b=0.447059) -lightsalmon3 = _intern(r=0.803922,g=0.505882,b=0.384314) -lightsalmon4 = _intern(r=0.545098,g=0.341176,b=0.258824) -orange1 = _intern(r=1.000000,g=0.647059,b=0.000000) -orange2 = _intern(r=0.933333,g=0.603922,b=0.000000) -orange3 = _intern(r=0.803922,g=0.521569,b=0.000000) -orange4 = _intern(r=0.545098,g=0.352941,b=0.000000) -darkorange1 = _intern(r=1.000000,g=0.498039,b=0.000000) -darkorange2 = _intern(r=0.933333,g=0.462745,b=0.000000) -darkorange3 = _intern(r=0.803922,g=0.400000,b=0.000000) -darkorange4 = _intern(r=0.545098,g=0.270588,b=0.000000) -coral1 = _intern(r=1.000000,g=0.447059,b=0.337255) -coral2 = _intern(r=0.933333,g=0.415686,b=0.313725) -coral3 = _intern(r=0.803922,g=0.356863,b=0.270588) -coral4 = _intern(r=0.545098,g=0.243137,b=0.184314) -tomato1 = _intern(r=1.000000,g=0.388235,b=0.278431) -tomato2 = _intern(r=0.933333,g=0.360784,b=0.258824) -tomato3 = _intern(r=0.803922,g=0.309804,b=0.223529) -tomato4 = _intern(r=0.545098,g=0.211765,b=0.149020) -orangered1 = _intern(r=1.000000,g=0.270588,b=0.000000) -orangered2 = _intern(r=0.933333,g=0.250980,b=0.000000) -orangered3 = _intern(r=0.803922,g=0.215686,b=0.000000) -orangered4 = _intern(r=0.545098,g=0.145098,b=0.000000) -red1 = _intern(r=1.000000,g=0.000000,b=0.000000) -red2 = _intern(r=0.933333,g=0.000000,b=0.000000) -red3 = _intern(r=0.803922,g=0.000000,b=0.000000) -red4 = _intern(r=0.545098,g=0.000000,b=0.000000) -deeppink1 = _intern(r=1.000000,g=0.078431,b=0.576471) -deeppink2 = _intern(r=0.933333,g=0.070588,b=0.537255) -deeppink3 = _intern(r=0.803922,g=0.062745,b=0.462745) -deeppink4 = _intern(r=0.545098,g=0.039216,b=0.313725) -hotpink1 = _intern(r=1.000000,g=0.431373,b=0.705882) -hotpink2 = _intern(r=0.933333,g=0.415686,b=0.654902) -hotpink3 = _intern(r=0.803922,g=0.376471,b=0.564706) -hotpink4 = _intern(r=0.545098,g=0.227451,b=0.384314) -pink1 = _intern(r=1.000000,g=0.709804,b=0.772549) -pink2 = _intern(r=0.933333,g=0.662745,b=0.721569) -pink3 = _intern(r=0.803922,g=0.568627,b=0.619608) -pink4 = _intern(r=0.545098,g=0.388235,b=0.423529) -lightpink1 = _intern(r=1.000000,g=0.682353,b=0.725490) -lightpink2 = _intern(r=0.933333,g=0.635294,b=0.678431) -lightpink3 = _intern(r=0.803922,g=0.549020,b=0.584314) -lightpink4 = _intern(r=0.545098,g=0.372549,b=0.396078) -palevioletred1 = _intern(r=1.000000,g=0.509804,b=0.670588) -palevioletred2 = _intern(r=0.933333,g=0.474510,b=0.623529) -palevioletred3 = _intern(r=0.803922,g=0.407843,b=0.537255) -palevioletred4 = _intern(r=0.545098,g=0.278431,b=0.364706) -maroon1 = _intern(r=1.000000,g=0.203922,b=0.701961) -maroon2 = _intern(r=0.933333,g=0.188235,b=0.654902) -maroon3 = _intern(r=0.803922,g=0.160784,b=0.564706) -maroon4 = _intern(r=0.545098,g=0.109804,b=0.384314) -violetred1 = _intern(r=1.000000,g=0.243137,b=0.588235) -violetred2 = _intern(r=0.933333,g=0.227451,b=0.549020) -violetred3 = _intern(r=0.803922,g=0.196078,b=0.470588) -violetred4 = _intern(r=0.545098,g=0.133333,b=0.321569) -magenta1 = _intern(r=1.000000,g=0.000000,b=1.000000) -magenta2 = _intern(r=0.933333,g=0.000000,b=0.933333) -magenta3 = _intern(r=0.803922,g=0.000000,b=0.803922) -magenta4 = _intern(r=0.545098,g=0.000000,b=0.545098) -orchid1 = _intern(r=1.000000,g=0.513725,b=0.980392) -orchid2 = _intern(r=0.933333,g=0.478431,b=0.913725) -orchid3 = _intern(r=0.803922,g=0.411765,b=0.788235) -orchid4 = _intern(r=0.545098,g=0.278431,b=0.537255) -plum1 = _intern(r=1.000000,g=0.733333,b=1.000000) -plum2 = _intern(r=0.933333,g=0.682353,b=0.933333) -plum3 = _intern(r=0.803922,g=0.588235,b=0.803922) -plum4 = _intern(r=0.545098,g=0.400000,b=0.545098) -mediumorchid1 = _intern(r=0.878431,g=0.400000,b=1.000000) -mediumorchid2 = _intern(r=0.819608,g=0.372549,b=0.933333) -mediumorchid3 = _intern(r=0.705882,g=0.321569,b=0.803922) -mediumorchid4 = _intern(r=0.478431,g=0.215686,b=0.545098) -darkorchid1 = _intern(r=0.749020,g=0.243137,b=1.000000) -darkorchid2 = _intern(r=0.698039,g=0.227451,b=0.933333) -darkorchid3 = _intern(r=0.603922,g=0.196078,b=0.803922) -darkorchid4 = _intern(r=0.407843,g=0.133333,b=0.545098) -purple1 = _intern(r=0.607843,g=0.188235,b=1.000000) -purple2 = _intern(r=0.568627,g=0.172549,b=0.933333) -purple3 = _intern(r=0.490196,g=0.149020,b=0.803922) -purple4 = _intern(r=0.333333,g=0.101961,b=0.545098) -mediumpurple1 = _intern(r=0.670588,g=0.509804,b=1.000000) -mediumpurple2 = _intern(r=0.623529,g=0.474510,b=0.933333) -mediumpurple3 = _intern(r=0.537255,g=0.407843,b=0.803922) -mediumpurple4 = _intern(r=0.364706,g=0.278431,b=0.545098) -thistle1 = _intern(r=1.000000,g=0.882353,b=1.000000) -thistle2 = _intern(r=0.933333,g=0.823529,b=0.933333) -thistle3 = _intern(r=0.803922,g=0.709804,b=0.803922) -thistle4 = _intern(r=0.545098,g=0.482353,b=0.545098) -gray00 = _intern(r=0.000000,g=0.000000,b=0.000000) -gray01 = _intern(r=0.011765,g=0.011765,b=0.011765) -gray02 = _intern(r=0.019608,g=0.019608,b=0.019608) -gray03 = _intern(r=0.031373,g=0.031373,b=0.031373) -gray04 = _intern(r=0.039216,g=0.039216,b=0.039216) -gray05 = _intern(r=0.050980,g=0.050980,b=0.050980) -gray06 = _intern(r=0.058824,g=0.058824,b=0.058824) -gray07 = _intern(r=0.070588,g=0.070588,b=0.070588) -gray08 = _intern(r=0.078431,g=0.078431,b=0.078431) -gray09 = _intern(r=0.090196,g=0.090196,b=0.090196) -gray10 = _intern(r=0.101961,g=0.101961,b=0.101961) -gray11 = _intern(r=0.109804,g=0.109804,b=0.109804) -gray12 = _intern(r=0.121569,g=0.121569,b=0.121569) -gray13 = _intern(r=0.129412,g=0.129412,b=0.129412) -gray14 = _intern(r=0.141176,g=0.141176,b=0.141176) -gray15 = _intern(r=0.149020,g=0.149020,b=0.149020) -gray16 = _intern(r=0.160784,g=0.160784,b=0.160784) -gray17 = _intern(r=0.168627,g=0.168627,b=0.168627) -gray18 = _intern(r=0.180392,g=0.180392,b=0.180392) -gray19 = _intern(r=0.188235,g=0.188235,b=0.188235) -gray20 = _intern(r=0.200000,g=0.200000,b=0.200000) -gray21 = _intern(r=0.211765,g=0.211765,b=0.211765) -gray22 = _intern(r=0.219608,g=0.219608,b=0.219608) -gray23 = _intern(r=0.231373,g=0.231373,b=0.231373) -gray24 = _intern(r=0.239216,g=0.239216,b=0.239216) -gray25 = _intern(r=0.250980,g=0.250980,b=0.250980) -gray26 = _intern(r=0.258824,g=0.258824,b=0.258824) -gray27 = _intern(r=0.270588,g=0.270588,b=0.270588) -gray28 = _intern(r=0.278431,g=0.278431,b=0.278431) -gray29 = _intern(r=0.290196,g=0.290196,b=0.290196) -gray30 = _intern(r=0.301961,g=0.301961,b=0.301961) -gray31 = _intern(r=0.309804,g=0.309804,b=0.309804) -gray32 = _intern(r=0.321569,g=0.321569,b=0.321569) -gray33 = _intern(r=0.329412,g=0.329412,b=0.329412) -gray34 = _intern(r=0.341176,g=0.341176,b=0.341176) -gray35 = _intern(r=0.349020,g=0.349020,b=0.349020) -gray36 = _intern(r=0.360784,g=0.360784,b=0.360784) -gray37 = _intern(r=0.368627,g=0.368627,b=0.368627) -gray38 = _intern(r=0.380392,g=0.380392,b=0.380392) -gray39 = _intern(r=0.388235,g=0.388235,b=0.388235) -gray40 = _intern(r=0.400000,g=0.400000,b=0.400000) -gray41 = _intern(r=0.411765,g=0.411765,b=0.411765) -gray42 = _intern(r=0.419608,g=0.419608,b=0.419608) -gray43 = _intern(r=0.431373,g=0.431373,b=0.431373) -gray44 = _intern(r=0.439216,g=0.439216,b=0.439216) -gray45 = _intern(r=0.450980,g=0.450980,b=0.450980) -gray46 = _intern(r=0.458824,g=0.458824,b=0.458824) -gray47 = _intern(r=0.470588,g=0.470588,b=0.470588) -gray48 = _intern(r=0.478431,g=0.478431,b=0.478431) -gray49 = _intern(r=0.490196,g=0.490196,b=0.490196) -gray50 = _intern(r=0.498039,g=0.498039,b=0.498039) -gray51 = _intern(r=0.509804,g=0.509804,b=0.509804) -gray52 = _intern(r=0.521569,g=0.521569,b=0.521569) -gray53 = _intern(r=0.529412,g=0.529412,b=0.529412) -gray54 = _intern(r=0.541176,g=0.541176,b=0.541176) -gray55 = _intern(r=0.549020,g=0.549020,b=0.549020) -gray56 = _intern(r=0.560784,g=0.560784,b=0.560784) -gray57 = _intern(r=0.568627,g=0.568627,b=0.568627) -gray58 = _intern(r=0.580392,g=0.580392,b=0.580392) -gray59 = _intern(r=0.588235,g=0.588235,b=0.588235) -gray60 = _intern(r=0.600000,g=0.600000,b=0.600000) -gray61 = _intern(r=0.611765,g=0.611765,b=0.611765) -gray62 = _intern(r=0.619608,g=0.619608,b=0.619608) -gray63 = _intern(r=0.631373,g=0.631373,b=0.631373) -gray64 = _intern(r=0.639216,g=0.639216,b=0.639216) -gray65 = _intern(r=0.650980,g=0.650980,b=0.650980) -gray66 = _intern(r=0.658824,g=0.658824,b=0.658824) -gray67 = _intern(r=0.670588,g=0.670588,b=0.670588) -gray68 = _intern(r=0.678431,g=0.678431,b=0.678431) -gray69 = _intern(r=0.690196,g=0.690196,b=0.690196) -gray70 = _intern(r=0.701961,g=0.701961,b=0.701961) -gray71 = _intern(r=0.709804,g=0.709804,b=0.709804) -gray72 = _intern(r=0.721569,g=0.721569,b=0.721569) -gray73 = _intern(r=0.729412,g=0.729412,b=0.729412) -gray74 = _intern(r=0.741176,g=0.741176,b=0.741176) -gray75 = _intern(r=0.749020,g=0.749020,b=0.749020) -gray76 = _intern(r=0.760784,g=0.760784,b=0.760784) -gray77 = _intern(r=0.768627,g=0.768627,b=0.768627) -gray78 = _intern(r=0.780392,g=0.780392,b=0.780392) -gray79 = _intern(r=0.788235,g=0.788235,b=0.788235) -gray80 = _intern(r=0.800000,g=0.800000,b=0.800000) -gray81 = _intern(r=0.811765,g=0.811765,b=0.811765) -gray82 = _intern(r=0.819608,g=0.819608,b=0.819608) -gray83 = _intern(r=0.831373,g=0.831373,b=0.831373) -gray84 = _intern(r=0.839216,g=0.839216,b=0.839216) -gray85 = _intern(r=0.850980,g=0.850980,b=0.850980) -gray86 = _intern(r=0.858824,g=0.858824,b=0.858824) -gray87 = _intern(r=0.870588,g=0.870588,b=0.870588) -gray88 = _intern(r=0.878431,g=0.878431,b=0.878431) -gray89 = _intern(r=0.890196,g=0.890196,b=0.890196) -gray90 = _intern(r=0.898039,g=0.898039,b=0.898039) -gray91 = _intern(r=0.909804,g=0.909804,b=0.909804) -gray92 = _intern(r=0.921569,g=0.921569,b=0.921569) -gray93 = _intern(r=0.929412,g=0.929412,b=0.929412) -gray94 = _intern(r=0.941176,g=0.941176,b=0.941176) -gray95 = _intern(r=0.949020,g=0.949020,b=0.949020) -gray96 = _intern(r=0.960784,g=0.960784,b=0.960784) -gray97 = _intern(r=0.968627,g=0.968627,b=0.968627) -gray98 = _intern(r=0.980392,g=0.980392,b=0.980392) -gray99 = _intern(r=0.988235,g=0.988235,b=0.988235) -gray100 = _intern(r=1.000000,g=1.000000,b=1.000000) -darkgray = _intern(r=0.662745,g=0.662745,b=0.662745) -darkblue = _intern(r=0.000000,g=0.000000,b=0.545098) -darkcyan = _intern(r=0.000000,g=0.545098,b=0.545098) -darkmagenta = _intern(r=0.545098,g=0.000000,b=0.545098) -darkred = _intern(r=0.545098,g=0.000000,b=0.000000) -lightgreen = _intern(r=0.564706,g=0.933333,b=0.564706) -default = black - -_name_table = None -def name_table(): - global _name_table - if not _name_table: - _name_table = pychart_util.symbol_lookup_table(globals(), standards) - return _name_table diff --git a/openerp/pychart/color_doc.py b/openerp/pychart/color_doc.py deleted file mode 100644 index c8f0e0317de..00000000000 --- a/openerp/pychart/color_doc.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -r(type:number) default="The intensity of red. The value is between 0 and 1.". -b(type:number) default="The intensity of blue. The value is between 0 and 1.". -g(type:number) default="The intensity of green. The value is between 0 and 1.". -""" - diff --git a/openerp/pychart/coord.py b/openerp/pychart/coord.py deleted file mode 100644 index f448ec8b038..00000000000 --- a/openerp/pychart/coord.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -class T(object): - def get_canvas_pos(self, size, val, min, max): - """ - Compute the screen location at which a sample value would be drawn. - ``size`` is the width or height of the chart, in points. - ``val`` is the sample value. - ``min`` and ``max`` are the minimum and maximum sample values that - are to be displayed over the length of ``size``. - - For example, suppose the width of a chart is 200 points and the - minimum and maximum X values in the sample data are 100 and 150 - respectively. When Pychart wants to draw a sample point at the X - value of 120, it will call - area.T.x_coord.get_canvas_pos(size = 200, val = 120, min = 100, max = 150). - """ - raise Exception - - def get_tics(self, min, max, interval): - """Generate the list of places for drawing tick marks.""" - raise Exception - - def get_min_max(self, min, max, interval): - """Compute the min/max values to be displayed in the chart. - Parameters ``min`` and ``max`` are the minimum and maximum values - of the sample data passed to the plots. Parameter ``interval`` is - the value of attribute area.T.x_grid_interval (or y_grid_interval). - It is None if these attributes are non-specified. - - This method must return tuple (dmin, dmax, dinterval). - dmin should be ``min`` rounded down to some good number. - dmax should be ``max`` rounded up to some good number. - dinterval should be ``interval`` if it is non-None. Otherwise, the - method must compute some good value. - """ - - raise Exception diff --git a/openerp/pychart/doc_support.py b/openerp/pychart/doc_support.py deleted file mode 100644 index 9d4e0f84cc7..00000000000 --- a/openerp/pychart/doc_support.py +++ /dev/null @@ -1,123 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import string -import sys -import re -import os.path -from pychart import * -from types import * -from pychart.pychart_types import * - -oldstdout = sys.stdout -if os.path.exists("/dev/null"): - sys.stdout = open("/dev/null", "w") - -modules = {} -values = [] - -sys.stdout = oldstdout -g = globals() -for mod in g.keys(): - val = g[mod] - if type(val) == ModuleType: - dic = {} - for name in val.__dict__.keys(): - v = val.__dict__[name] - if name[0] != '_': - values.append((v, mod + "." + name)) - if type(v) == type and issubclass(v, chart_object.T): - dic[name] = v - modules[mod] = dic - -def stringify_type(t): - s = str(t) - if t == AnyType: - return "any" - if t == ShadowType: - return "(xoff,yoff,fill)" - elif re.search("NumType", s): - return "number" - elif re.search("UnitType", s): - return "length in points (\\\\xref{unit})" - elif re.search("CoordType", s): - return "(x,y)" - elif re.search("CoordSystemType", s): - return "['linear'|'log'|'category']" - elif re.search("CoordOrNoneType", s): - return "(x,y) or None" - elif re.search("TextAlignType", s): - return "['R'|'L'|'C'|None]" - elif re.search("FormatType", s): - return "printf format string" - elif re.search("IntervalType", s): - return "Number or function" - - mo = re.match("<type '([^']+)'>", s) - if mo: - return mo.group(1) - mo = re.match("<class 'pychart\.([^']+)'>", s) - if mo: - return mo.group(1) - mo = re.match("<class '([^']+)'>", s) - if mo: - return mo.group(1) - mo = re.match("pychart\\.(.*)", s) - if mo: - return mo.group(1) - return s - -def stringify_value(val): - t = type(val) - if t == StringType: - return '"' + val + '"' - if t == bool: - if val: return "True" - else: return "False" - - if t in (IntType, LongType, FloatType): - return str(val) - if val == None: - return "None" - if type(val) == ListType: - return map(stringify_value, val) - for pair in values: - if pair[0] == val: - return pair[1] - return str(val) - -def break_string(name): - max_len = 10 - if len(name) < max_len: - return name - - name = re.sub("(\\d\\d)([^\\d])", "\\1-\n\\2", name) - name = re.sub("black(.)", "black-\n\\1", name) - - elems = string.split(name, "\n") - while 1: - broken = 0 - for i in range(len(elems)): - elem = elems[i] - if len(elem) < max_len: - continue - broken = 1 - elem1 = elem[0:len(elem)/2] - elem2 = elem[len(elem)/2:] - elems[i:i+1] = [elem1, elem2] - break - if not broken: - break - name = "\n".join(elems) - return name diff --git a/openerp/pychart/empty_docs.py b/openerp/pychart/empty_docs.py deleted file mode 100644 index b7b4e239534..00000000000 --- a/openerp/pychart/empty_docs.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# - -def generate_doc(name, suffix="", append = 0): - if append: - fp = open(name + "_doc.py", "a+") - else: - fp = open(name + "_doc.py", "w") - fp.write("# automatically generated by generate_docs.py.\n") - fp.write("doc" + suffix + "=\" \"\n") - fp.close() - -generate_doc( "area") -generate_doc( "arrow") -generate_doc( "axis", "_x") -generate_doc( "axis", "_y", 1) -generate_doc( "bar_plot") -generate_doc( "color") -generate_doc( "error_bar","_1") -generate_doc( "error_bar", "_2", 1) -generate_doc( "error_bar", "_3", 1) -generate_doc( "error_bar", "_4", 1) -generate_doc( "error_bar", "_5", 1) -generate_doc( "error_bar", "_6", 1) -generate_doc( "fill_style") -generate_doc("line_plot") -generate_doc("pie_plot") -generate_doc("text_box") -generate_doc("range_plot") -generate_doc("legend") -generate_doc("legend", "_entry", 1) -generate_doc("line_style") -generate_doc("tick_mark") diff --git a/openerp/pychart/error_bar.py b/openerp/pychart/error_bar.py deleted file mode 100644 index 7ff7923b60f..00000000000 --- a/openerp/pychart/error_bar.py +++ /dev/null @@ -1,160 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import tick_mark -import line_style -import pychart_util -import chart_object -import fill_style -import types -import error_bar_doc -import object_set -from pychart_types import * - -__doc__ = """Pychart offers several styles of error bars. Some of them -only displays the min/max confidence interval, while others can display -quartiles in addition to min/max.""" - -class T(chart_object.T): - keys = {} -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - pass - -# Two horizontal lines at min & max locations. -class error_bar1(T): - __doc__ = error_bar_doc.doc_1 - keys = {"tic_len" : (UnitType, 10, "Length of the horizontal bars"), - "line_style": (line_style.T, line_style.default, "") - } -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def draw(self, can, loc, min, max, qmin = None, qmax = None): - x = loc[0] - y = min - can.line(self.line_style, x-self.tic_len/2.0, y, x+self.tic_len/2.0, y) - y = max - can.line(self.line_style, x-self.tic_len/2.0, y, x+self.tic_len/2.0, y) - -class error_bar2(T): - __doc__ = error_bar_doc.doc_2 - keys = {"tic_len" : (UnitType, 3, - "The length of the horizontal bars"), - "hline_style": (line_style.T, line_style.default, - "The style of the horizontal bars."), - "vline_style": (line_style.T, None, - "The style of the vertical bar.") - } - -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def draw(self, can, loc, min, max, qmin = None, qmax = None): - vline_style = self.vline_style - if not vline_style: - vline_style = self.hline_style - x = loc[0] - y1 = min - can.line(self.hline_style, x-self.tic_len/2.0, y1, x+self.tic_len/2.0, y1) - y2 = max - can.line(self.hline_style, x-self.tic_len/2.0, y2, x+self.tic_len/2.0, y2) - can.line(vline_style, x, y1, x, y2) - -class error_bar3(T): - # Tufte style - __doc__ = "This style is endorsed by the Tufte's books. " \ - + error_bar_doc.doc_3 - keys = { "line_style": (line_style.T, line_style.default, "") - } - -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def draw(self, can, loc, min, max, qmin, qmax): - x = loc[0] - can.line(self.line_style, x, min, x, qmin) - can.line(self.line_style, x, qmax, x, max) - -class error_bar4(T): - __doc__ = error_bar_doc.doc_4 - keys = { "line_style": (line_style.T, line_style.default, ""), - "fill_style": (fill_style.T, fill_style.gray70, ""), - "box_width": (UnitType, 4, ""), - "tic_len": (UnitType, 4, "") - } -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def draw(self, can, loc, min, max, qmin, qmax): - x = loc[0] - style = self.line_style - y1 = min - can.line(style, x-self.tic_len/2.0, y1, x+self.tic_len/2.0, y1) - y2 = max - can.line(style, x-self.tic_len/2.0, y2, x+self.tic_len/2.0, y2) - can.line(style, x, y1, x, y2) - - can.rectangle(style, self.fill_style, - x-self.box_width/2.0, qmin, - x+self.box_width/2.0, qmax) - -# vertical line -class error_bar5(T): - __doc__ = error_bar_doc.doc_5 - keys = { "line_style": (line_style.T, line_style.default, "") - } -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def draw(self, can, loc, min, max, qmin = None, qmax = None): - x = loc[0] - y = loc[1] - - min = (min - y) *1 + y - max = (max - y) *1+ y - can.line(self.line_style, x, min, x, max) - -# a box -class error_bar6(T): - __doc__ = error_bar_doc.doc_6 - keys = { "line_style": (line_style.T, line_style.default, ""), - "fill_style": (fill_style.T, fill_style.gray70, ""), - "center_line_style": (line_style.T, line_style.T(width=0.5), ""), - "box_width": (UnitType, 4, ""), - } -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def draw(self, can, loc, min, max, qmin = None, qmax = None): - x = loc[0] - y = loc[1] - - can.rectangle(self.line_style, self.fill_style, - x - self.box_width / 2.0, min, - x + self.box_width / 2.0, max) - can.line(self.center_line_style, - x - self.box_width/2.0, (min+max)/2.0, - x + self.box_width/2.0, (min+max)/2.0) - -bar1 = error_bar1() -bar2 = error_bar2() -bar3 = error_bar3() -bar4 = error_bar4() -bar5 = error_bar5() -bar6 = error_bar6() - -standards = object_set.T(bar1, bar2, bar3, bar4, bar5, bar6) - diff --git a/openerp/pychart/error_bar_doc.py b/openerp/pychart/error_bar_doc.py deleted file mode 100644 index 5218b1c3e5b..00000000000 --- a/openerp/pychart/error_bar_doc.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc_1="""Attributes supported by this class are: -line_style(type:line_style.T) default="". -tic_len(type:length in points (\\xref{unit})) default="Length of the horizontal bars". -""" - -doc_2="""Attributes supported by this class are: -vline_style(type:line_style.T) default="The style of the vertical bar.". -hline_style(type:line_style.T) default="The style of the horizontal bars.". -tic_len(type:length in points (\\xref{unit})) default="The length of the horizontal bars". -""" - -doc_3="""Attributes supported by this class are: -line_style(type:line_style.T) default="". -""" - -doc_4="""Attributes supported by this class are: -line_style(type:line_style.T) default="". -box_width(type:length in points (\\xref{unit})) default="". -tic_len(type:length in points (\\xref{unit})) default="". -fill_style(type:fill_style.T) default="". -""" - -doc_5="""Attributes supported by this class are: -line_style(type:line_style.T) default="". -""" - -doc_6="""Attributes supported by this class are: -box_width(type:length in points (\\xref{unit})) default="". -line_style(type:line_style.T) default="". -center_line_style(type:line_style.T) default="". -fill_style(type:fill_style.T) default="". -""" - diff --git a/openerp/pychart/fill_style.py b/openerp/pychart/fill_style.py deleted file mode 100644 index 08f73177d24..00000000000 --- a/openerp/pychart/fill_style.py +++ /dev/null @@ -1,286 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import pychart_util -import color -import line_style -import chart_object -import object_set -import types -import theme -import fill_style_doc -from pychart_types import * -from scaling import * - -_keys = { - "bgcolor" : (color.T, color.white, "The background color."), - "line_style": (line_style.T, line_style.default, - pychart_util.line_desc), - "line_interval": (NumType, 3, - "The interval between successive stitch lines.") - } - -class T(chart_object.T): - __doc__ = fill_style_doc.doc - keys = _keys -##AUTOMATICALLY GENERATED -##END AUTOMATICALLY GENERATED - def __str__(self): - s = name_table().lookup(self) - if s: - return s - return "<fillstyle: bg=%s line=%s interval=%s>" % \ - (self.bgcolor, self.line_style, self.line_interval) - -class Plain(T): - """This class just fills the region with solid background color. -Attributes line_style and line_interval are ignored.""" - def draw(self, can, x1, y1, x2, y2): - pass - -class Diag(T): - "This class fills the region with diagonal lines." - - def draw(self, can, x1, y1, x2, y2): - line_width = self.line_style.width - interval = self.line_interval * 1.414 - x1 -= line_width - y1 -= line_width - x2 += line_width - y2 += line_width - len = max(y2 - y1, x2 - x1) - curx = x1 - len - while curx < x2: - can.line(self.line_style, curx, y1, curx+len, y1+len) - curx += interval - -class Rdiag(T): - """Fills the region with diagonal lines, but tilted in the opposite -direction from fill_style.Diag.""" - def draw(self, can, x1, y1, x2, y2): - line_width = self.line_style.width - interval = self.line_interval * 1.414 - x1 -= line_width - y1 -= line_width - x2 += line_width - y2 += line_width - len = max(y2 - y1, x2 - x1) - curx = x1 - while curx < x2 + len: - can.line(self.line_style, curx, y1, curx-len, y1+len) - curx += interval - -class Vert(T): - "Fills the region with vertical lines" - def draw(self, can, x1, y1, x2, y2): - interval = self.line_interval - curx = x1 - while curx < x2: - can.line(self.line_style, curx, y1, curx, y2) - curx += interval - -class Horiz(T): - "Fills the region with horizontal lines" - def draw(self, can, x1, y1, x2, y2): - interval = self.line_interval - cury = y1 - while cury < y2: - can.line(self.line_style, x1, cury, x2, cury) - cury += interval - -class Stitch(T): - "Fills the region with horizontal and vertical lines." - def draw(self, can, x1, y1, x2, y2): - interval = self.line_interval - cury = y1 - while cury < y2: - can.line(self.line_style, x1, cury, x2, cury) - cury += interval - curx = x1 - while curx < x2: - can.line(self.line_style, curx, y1, curx, y2) - curx += interval - -class Wave(T): - "Fills the region with horizontal wavy lines." - def draw(self, can, x1, y1, x2, y2): - x1 = xscale(x1) - x2 = xscale(x2) - y1 = yscale(y1) - y2 = yscale(y2) - line_width = nscale(self.line_style.width) - interval = nscale(self.line_interval) - - can.set_line_style(self.line_style) - x1 -= line_width - x2 += line_width - cury = y1 - half = interval/2.0 - while cury < y2: - curx = x1 - can.newpath() - can.moveto(curx, cury) - while curx < x2: - can.lineto(curx + half, cury + half) - can.lineto(curx + interval, cury) - curx += interval - can.stroke() - cury += interval - -class Vwave(T): - """Fills the region with vertical wavy lines.""" - def draw(self, can, x1, y1, x2, y2): - x1 = xscale(x1) - x2 = xscale(x2) - y1 = yscale(y1) - y2 = yscale(y2) - line_width = nscale(self.line_style.width) - interval = nscale(self.line_interval) - - can.set_line_style(self.line_style) - y1 -= line_width - y2 += line_width - curx = x1 - half = interval/2.0 - while curx < x2: - cury = y1 - can.newpath() - can.moveto(curx, cury) - while cury < y2: - can.lineto(curx + half, cury + half) - can.lineto(curx, cury + interval) - cury += interval - can.stroke() - curx += interval - -class Lines(T): - """Fills the region with a series of short line segments.""" - def draw(self, can, x1, y1, x2, y2): - interval = nscale(self.line_interval) - cury = y1 - j = 0 - while cury < y2: - curx = x1 - if j % 2 == 1: - curx += interval/2.0 - while curx < x2: - can.line(self.line_style, curx, cury, curx+interval/2.0, cury) - curx += interval * 1.5 - j += 1 - cury += interval - -default = Plain() - -color_standards = object_set.T() -grayscale_standards = object_set.T() - -def _intern_both(style): - global color_standards, grayscale_standards - color_standards.add(style) - grayscale_standards.add(style) - return style - -def _intern_color(style): - global color_standards, grayscale_standards - color_standards.add(style) - return style - -def _intern_grayscale(style): - global color_standards, grayscale_standards - grayscale_standards.add(style) - return style - -black = _intern_both(Plain(bgcolor=color.gray_scale(0.0), line_style=None)) - -red = _intern_color(Plain(bgcolor=color.red)) -darkseagreen = _intern_color(Plain(bgcolor=color.darkseagreen)) -blue = _intern_color(Plain(bgcolor=color.blue)) -aquamarine1 = _intern_color(Plain(bgcolor=color.aquamarine1)) -gray70 = _intern_both(Plain(bgcolor=color.gray70, line_style=None)) -brown = _intern_color(Plain(bgcolor=color.brown)) -darkorchid = _intern_color(Plain(bgcolor=color.darkorchid)) -diag = _intern_both(Diag(line_style=line_style.T(cap_style=2))) -green = _intern_color(Plain(bgcolor=color.green)) -gray50 = _intern_both(Plain(bgcolor=color.gray50, line_style=None)) -white = _intern_both(Plain(bgcolor=color.gray_scale(1.0), line_style=None)) -goldenrod = _intern_color(Plain(bgcolor=color.goldenrod)) -rdiag = _intern_both(Rdiag(line_style=line_style.T(cap_style=2))) -vert = _intern_both(Vert(line_interval=1.8)) - -gray30 = _intern_both(Plain(bgcolor=color.gray30, line_style=None)) -gray20 = _intern_both(Plain(bgcolor=color.gray20, line_style=None)) -gray10 = _intern_both(Plain(bgcolor=color.gray10, line_style=None)) -diag2 = _intern_both(Diag(line_style=line_style.T(width=3, cap_style=2), - line_interval=6)) -rdiag2 = _intern_both(Rdiag(line_style=line_style.T(width=3, cap_style=2), - line_interval=6)) -yellow = _intern_color(Plain(bgcolor=color.yellow)) -diag3 = _intern_both(Diag(line_style=line_style.T(width=3, color=color.gray50, cap_style=2), - line_interval=6)) -horiz = _intern_both(Horiz(line_interval=1.8)) -gray90 = _intern_both(Plain(bgcolor=color.gray90, line_style=None)) -rdiag3 = _intern_both(Rdiag(line_style=line_style.T(width=3, - color=color.gray50, - cap_style=2), - line_interval=6)) - -wave = _intern_both(Wave(line_style=line_style.T(cap_style=2, join_style=1))) -vwave = _intern_both(Vwave(line_style=line_style.T(cap_style=2, join_style=1))) -stitch = _intern_both(Stitch(line_style=line_style.T(cap_style=2, join_style=1))) -lines = _intern_both(Lines(line_style=line_style.T())) - -diag_fine = _intern_both(Diag(line_style=line_style.T(width=0.75,cap_style=2), - line_interval = 1.5)) -diag2_fine = _intern_both(Diag(line_style=line_style.T(width=0.75, cap_style=2), - line_interval=1.5)) -diag3_fine = _intern_both(Diag(line_style=line_style.T(width=0.75, - color = color.gray50, - cap_style=2), - line_interval=1.5)) -rdiag_fine = _intern_both(Rdiag(line_style=line_style.T(width=0.75,cap_style=2), - line_interval = 1.5)) -rdiag2_fine = _intern_both(Rdiag(line_style=line_style.T(width=0.75, cap_style=2), - line_interval=1.5)) -rdiag3_fine = _intern_both(Rdiag(line_style=line_style.T(width=0.75, - color = color.gray50, - cap_style=2), - line_interval=1.5)) - -horiz_fine = _intern_both(Horiz(line_interval=1.5)) -vert_fine = _intern_both(Vert(line_interval=1.5)) - -# -# Fill styles for color charts. -# - -standards = None -_name_table = None - -def init(): - global standards, _name_table - if theme.use_color: - standards = color_standards - else: - standards = grayscale_standards - _name_table = None - -def name_table(): - global _name_table - if not _name_table: - _name_table = pychart_util.symbol_lookup_table(globals(), standards) - return _name_table - -init() -theme.add_reinitialization_hook(init) - diff --git a/openerp/pychart/fill_style_doc.py b/openerp/pychart/fill_style_doc.py deleted file mode 100644 index dc6cd5ed7c1..00000000000 --- a/openerp/pychart/fill_style_doc.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -bgcolor(type:color.T) default="The background color.". -line_style(type:line_style.T) default="The style of the line. ". -line_interval(type:number) default="The interval between successive stitch lines.". -""" - diff --git a/openerp/pychart/font.py b/openerp/pychart/font.py deleted file mode 100644 index c2a54144d06..00000000000 --- a/openerp/pychart/font.py +++ /dev/null @@ -1,455 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import color -import string -import pychart_util -import re -import theme -import afm.dir - - -__doc__ = """The module for manipulating texts and their attributes. - -Pychart supports extensive sets of attributes in texts. All attributes -are specified via "escape sequences", starting from letter "/". For -example, the below examples draws string "Hello" using a 12-point font -at 60-degree angle: - -/12/a60{}Hello - -List of attributes: - -/hA - Specifies horizontal alignment of the text. A is one of L (left - alignment), R (right alignment), or C (center alignment). -/vA - Specifies vertical alignment of the text. A is one of "B" - (bottom), "T" (top), " M" (middle). - -/F{FONT} - Switch to FONT font family. -/T - Shorthand of /F{Times-Roman}. -/H - Shorthand of /F{Helvetica}. -/C - Shorthand of /F{Courier}. -/B - Shorthand of /F{Bookman-Demi}. -/A - Shorthand of /F{AvantGarde-Book}. -/P - Shorthand of /F{Palatino}. -/S - Shorthand of /F{Symbol}. -/b - Switch to bold typeface. -/i - Switch to italic typeface. -/o - Switch to oblique typeface. -/DD - Set font size to DD points. - - /20{}2001 space odyssey! - -/cDD - Set gray-scale to 0.DD. Gray-scale of 00 means black, 99 means white. - -//, /{, /} - Display `/', `@', or `@{'. - -{ ... } - Limit the effect of escape sequences. For example, the below - example draws "Foo" at 12pt, "Bar" at 8pt, and "Baz" at 12pt. - - /12Foo{/8Bar}Baz -\n - Break the line. -""" - -# List of fonts for which their absence have been already warned. -_undefined_font_warned = {} - -def _intern_afm(font, text): - global _undefined_font_warned - font2 = _font_aliases.has_key(font) and _font_aliases[font] - if afm.dir.afm.has_key(font): - return afm.dir.afm[font] - if afm.dir.afm.has_key(font2): - return afm.dir.afm[font2] - - try: - exec("import pychart.afm.%s" % re.sub("-", "_", font)) - return afm.dir.afm[font] - except: - if not font2 and not _undefined_font_warned.has_key(font): - pychart_util.warn("Warning: unknown font '%s' while parsing '%s'" % (font, text)) - _undefined_font_warned[font] = 1 - - if font2: - try: - exec("import pychart.afm.%s" % re.sub("-", "_", font2)) - return afm.dir.afm[font2] - except: - if not _undefined_font_warned.has_key(font): - pychart_util.warn("Warning: unknown font '%s' while parsing '%s'" % (font, text)) - _undefined_font_warned[font] = 1 - return None -def line_width(font, size, text): - table = _intern_afm(font, text) - if not table: - return 0 - - width = 0 - for ch in text: - code = ord(ch) - if code < len(table): - width += table[code] - else: - width += 10000 - - width = float(width) * size / 1000.0 - return width - -_font_family_map = {'T': "Times", - 'H': "Helvetica", - 'C': "Courier", - 'N': "Helvetica-Narrow", - 'B': "Bookman-Demi", - 'A': "AvantGarde-Book", - 'P': "Palatino", - 'S': "Symbol"} - -# Aliases for ghostscript font names. - -_font_aliases = { - 'Bookman-Demi': "URWBookmanL-DemiBold%I", - 'Bookman-DemiItalic': "URWBookmanL-DemiBoldItal", - 'Bookman-Demi-Italic': "URWBookmanL-DemiBoldItal", - 'Bookman-Light': "URWBookmanL-Ligh", - 'Bookman-LightItalic': "URWBookmanL-LighItal", - 'Bookman-Light-Italic': "URWBookmanL-LighItal", - 'Courier': "NimbusMonL-Regu", - 'Courier-Oblique': "NimbusMonL-ReguObli", - 'Courier-Bold': "NimbusMonL-Bold", - 'Courier-BoldOblique': "NimbusMonL-BoldObli", - 'AvantGarde-Book': "URWGothicL-Book", - 'AvantGarde-BookOblique': "URWGothicL-BookObli", - 'AvantGarde-Book-Oblique': "URWGothicL-BookObli", - 'AvantGarde-Demi': "URWGothicL-Demi", - 'AvantGarde-DemiOblique': "URWGothicL-DemiObli", - 'AvantGarde-Demi-Oblique': "URWGothicL-DemiObli", - 'Helvetica': "NimbusSanL-Regu", - 'Helvetica-Oblique': "NimbusSanL-ReguItal", - 'Helvetica-Bold': "NimbusSanL-Bold", - 'Helvetica-BoldOblique': "NimbusSanL-BoldItal", - 'Helvetica-Narrow': "NimbusSanL-ReguCond", - 'Helvetica-Narrow-Oblique': "NimbusSanL-ReguCondItal", - 'Helvetica-Narrow-Bold': "NimbusSanL-BoldCond", - 'Helvetica-Narrow-BoldOblique': "NimbusSanL-BoldCondItal", - 'Palatino-Roman': "URWPalladioL-Roma", - 'Palatino': "URWPalladioL-Roma", - 'Palatino-Italic': "URWPalladioL-Ital", - 'Palatino-Bold': "URWPalladioL-Bold", - 'Palatino-BoldItalic': "URWPalladioL-BoldItal", - 'NewCenturySchlbk-Roman': "CenturySchL-Roma", - 'NewCenturySchlbk': "CenturySchL-Roma", - 'NewCenturySchlbk-Italic': "CenturySchL-Ital", - 'NewCenturySchlbk-Bold': "CenturySchL-Bold", - 'NewCenturySchlbk-BoldItalic': "CenturySchL-BoldItal", - 'Times-Roman': "NimbusRomNo9L-Regu", - 'Times': "NimbusRomNo9L-Regu", - 'Times-Italic': "NimbusRomNo9L-ReguItal", - 'Times-Bold': "NimbusRomNo9L-Medi", - 'Times-BoldItalic': "NimbusRomNo9L-MediItal", - 'Symbol': "StandardSymL", - 'ZapfChancery-MediumItalic': "URWChanceryL-MediItal", - 'ZapfChancery-Medium-Italic': "URWChanceryL-MediItal", - 'ZapfDingbats': "Dingbats" -} - - -class text_state: - def copy(self): - ts = text_state() - ts.family = self.family - ts.modifiers = list(self.modifiers) - ts.size = self.size - ts.line_height = self.line_height - ts.color = self.color - ts.halign = self.halign - ts.valign = self.valign - ts.angle = self.angle - return ts - def __init__(self): - self.family = theme.default_font_family - self.modifiers = [] # 'b' for bold, 'i' for italic, 'o' for oblique. - self.size = theme.default_font_size - self.line_height = theme.default_line_height or theme.default_font_size - self.color = color.default - self.halign = theme.default_font_halign - self.valign = theme.default_font_valign - self.angle = theme.default_font_angle - -class text_iterator: - def __init__(self, s): - self.str = str(s) - self.i = 0 - self.ts = text_state() - self.stack = [] - def reset(self, s): - self.str = str(s) - self.i = 0 - - def __return_state(self, ts, str): - font_name = ts.family - - if ts.modifiers != []: - is_bold = 0 - if 'b' in ts.modifiers: - is_bold = 1 - font_name += "-Bold" - if 'o' in ts.modifiers: - if not is_bold: - font_name += "-" - font_name += "Oblique" - elif 'i' in ts.modifiers: - if not is_bold: - font_name += "-" - font_name += "Italic" - elif font_name in ("Palatino", "Times", "NewCenturySchlbk"): - font_name += "-Roman" - - return (font_name, ts.size, ts.line_height, ts.color, - ts.halign, ts.valign, ts.angle, str) - def __parse_float(self): - istart = self.i - while self.i < len(self.str) and self.str[self.i] in string.digits or self.str[self.i] == '.': - self.i += 1 - return float(self.str[istart:self.i]) - - def __parse_int(self): - istart = self.i - while self.i < len(self.str) and \ - (self.str[self.i] in string.digits or - self.str[self.i] == '-'): - self.i += 1 - return int(self.str[istart:self.i]) - def next(self): - "Get the next text segment. Return an 8-element array: (FONTNAME, SIZE, LINEHEIGHT, COLOR, H_ALIGN, V_ALIGN, ANGLE, STR." - l = [] - changed = 0 - self.old_state = self.ts.copy() - - while self.i < len(self.str): - if self.str[self.i] == '/': - self.i = self.i+1 - ch = self.str[self.i] - self.i = self.i+1 - self.old_state = self.ts.copy() - if ch == '/' or ch == '{' or ch == '}': - l.append(ch) - elif _font_family_map.has_key(ch): - self.ts.family = _font_family_map[ch] - changed = 1 - elif ch == 'F': - # /F{font-family} - if self.str[self.i] != '{': - raise Exception, "'{' must follow /F in \"%s\"" % self.str - self.i += 1 - istart = self.i - while self.str[self.i] != '}': - self.i += 1 - if self.i >= len(self.str): - raise Exception, "Expecting /F{...}. in \"%s\"" % self.str - self.ts.family = self.str[istart:self.i] - self.i += 1 - changed = 1 - - elif ch in string.digits: - self.i -= 1 - self.ts.size = self.__parse_int() - self.ts.line_height = self.ts.size - changed = 1 - elif ch == 'l': - self.ts.line_height = self.__parse_int() - changed = 1 - elif ch == 'b': - self.ts.modifiers.append('b') - changed = 1 - elif ch == 'i': - self.ts.modifiers.append('i') - changed = 1 - elif ch == 'o': - self.ts.modifiers.append('q') - changed = 1 - elif ch == 'c': - self.ts.color = color.gray_scale(self.__parse_float()) - elif ch == 'v': - if self.str[self.i] not in "BTM": - raise Exception, "Undefined escape sequence: /v%c (%s)" % (self.str[self.i], self.str) - self.ts.valign = self.str[self.i] - self.i += 1 - changed = 1 - elif ch == 'h': - if self.str[self.i] not in "LRC": - raise Exception, "Undefined escape sequence: /h%c (%s)" % (self.str[self.i], self.str) - self.ts.halign = self.str[self.i] - self.i += 1 - changed = 1 - elif ch == 'a': - self.ts.angle = self.__parse_int() - changed = 1 - else: - raise Exception, "Undefined escape sequence: /%c (%s)" % (ch, self.str) - elif self.str[self.i] == '{': - self.stack.append(self.ts.copy()) - self.i += 1 - elif self.str[self.i] == '}': - if len(self.stack) == 0: - raise ValueError, "unmatched '}' in \"%s\"" % (self.str) - self.ts = self.stack[-1] - del self.stack[-1] - self.i += 1 - changed = 1 - else: - l.append(self.str[self.i]) - self.i += 1 - - if changed and len(l) > 0: - return self.__return_state(self.old_state, ''.join(l)) - else: - # font change in the beginning of the sequence doesn't count. - self.old_state = self.ts.copy() - changed = 0 - if len(l) > 0: - return self.__return_state(self.old_state, ''.join(l)) - else: - return None - -# -# - -def unaligned_get_dimension(text): - """Return the bounding box of the text, assuming that the left-bottom corner - of the first letter of the text is at (0, 0). This procedure ignores - /h, /v, and /a directives when calculating the BB; it just returns the - alignment specifiers as a part of the return value. The return value is a - tuple (width, height, halign, valign, angle).""" - - xmax = 0 - ymax = 0 - ymax = 0 - angle = None - halign = None - valign = None - - itr = text_iterator(None) - for line in str(text).split("\n"): - cur_height = 0 - cur_width = 0 - itr.reset(line) - while 1: - elem = itr.next() - if not elem: - break - (font, size, line_height, color, new_h, new_v, new_a, chunk) = elem - if halign != None and new_h != halign: - raise Exception, "Only one /h can appear in string '%s'." % str(text) - if valign != None and new_v != valign: - raise Exception, "Only one /v can appear in string '%s'." % str(text) - if angle != None and new_a != angle: - raise Exception, "Only one /a can appear in string '%s'." % str(text) - halign = new_h - valign = new_v - angle = new_a - cur_width += line_width(font, size, chunk) - cur_height = max(cur_height, line_height) - xmax = max(cur_width, xmax) - ymax += cur_height - return (xmax, ymax, - halign or theme.default_font_halign, - valign or theme.default_font_valign, - angle or theme.default_font_angle) - -def get_dimension(text): - """Return the bounding box of the <text>, - assuming that the left-bottom corner - of the first letter of the text is at (0, 0). This procedure ignores - /h, /v, and /a directives when calculating the boundingbox; it just returns the - alignment specifiers as a part of the return value. The return value is a - tuple (width, height, halign, valign, angle).""" - (xmax, ymax, halign, valign, angle) = unaligned_get_dimension(text) - xmin = ymin = 0 - if halign == "C": - xmin = -xmax / 2.0 - xmax = xmax / 2.0 - elif halign == "R": - xmin = -xmax - xmax = 0 - if valign == "M": - ymin = -ymax / 2.0 - ymax = ymax / 2.0 - elif valign == "T": - ymin = -ymax - ymax = 0 - if angle != 0: - (x0, y0) = pychart_util.rotate(xmin, ymin, angle) - (x1, y1) = pychart_util.rotate(xmax, ymin, angle) - (x2, y2) = pychart_util.rotate(xmin, ymax, angle) - (x3, y3) = pychart_util.rotate(xmax, ymax, angle) - xmax = max(x0, x1, x2, x3) - xmin = min(x0, x1, x2, x3) - ymax = max(y0, y1, y2, y3) - ymin = min(y0, y1, y2, y3) - return (xmin, xmax, ymin, ymax) - return (xmin, xmax, ymin, ymax) - -def unaligned_text_width(text): - x = unaligned_get_dimension(text) - return x[0] - -def text_width(text): - """Return the width of the <text> in points.""" - (xmin, xmax, d1, d2) = get_dimension(text) - return xmax-xmin - -def unaligned_text_height(text): - x = unaligned_get_dimension(text) - return x[1] - -def text_height(text): - """Return the total height of the <text> and the length from the - base point to the top of the text box.""" - (d1, d2, ymin, ymax) = get_dimension(text) - return (ymax-ymin, ymax) - -def get_align(text): - "Return (halign, valign, angle) of the <text>." - (x1, x2, h, v, a) = unaligned_get_dimension(text) - return (h, v, a) - -def quotemeta(text): - """Quote letters with special meanings in pychart so that <text> will display - as-is when passed to canvas.show(). - ->>> font.quotemeta("foo/bar") -"foo//bar" -""" - text = re.sub("/", "//", text) - text = re.sub("\\{", "/{", text) - text = re.sub("\\}", "/}", text) - return text diff --git a/openerp/pychart/generate_docs.py b/openerp/pychart/generate_docs.py deleted file mode 100644 index 0d9646677cf..00000000000 --- a/openerp/pychart/generate_docs.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import string -import doc_support -import sys -import re -import os - -import area -import arrow -import axis -import bar_plot -import line_plot -import pie_plot -import color -import error_bar -import fill_style -import font -import text_box -import line_style -import legend -import range_plot -import tick_mark - -indent = 4 -max_line_len = 64 - -def format_paragraph(fp, str): - line_len = indent - fp.write(" " * indent) - for word in str.split(): - if line_len >= max_line_len: - fp.write("\n") - fp.write(" " * indent) - line_len = indent - fp.write(word + " ") - line_len += len(word) + 1 - -def format_string(fp, str): - str = re.sub("<<([^>]+)>>", "See also pychart.\\1", str) - - str2 = "" - in_example = 0 - for l in str.split("\n"): - if re.match("@example", l): - in_example = 1 - if re.match("@end example", l): - in_example = 0 - if in_example: - str2 += l - else: - l = re.sub("^[ \t]*", "", l) - str2 += l - str2 += "\n" - fname = os.tempnam() - out_fp = open(fname, "w") - out_fp.write(str2) - out_fp.close() - - in_fp = os.popen("makeinfo --fill-column=64 --no-headers " + fname, "r") - for l in in_fp.readlines(): - fp.write(" " * indent) - fp.write(l) - in_fp.close() - os.remove(fname) - -def generate_doc(c, name, suffix="", append = 0): - if append: - fp = open(name + "_doc.py", "a+") - else: - fp = open(name + "_doc.py", "w") - fp.write("# automatically generated by generate_docs.py.\n") - - fp.write("doc" + suffix + "=\"\"\"Attributes supported by this class are:\n") - for key in c.keys.keys(): - val=c.keys[key] - desc = "" - defaultValDesc = None - if len(val) > 3: - desc = val[3] - if len(val) > 4: - defaultValDesc = val[4] - - fp.write(key + "(type:" + doc_support.stringify_type(val[0])) - if defaultValDesc: - fp.write(") default:" + defaultValDesc) - else: - fp.write(") default=" + str(doc_support.stringify_value(val[2])) + ".\n") - format_string(fp, desc) - fp.write("\"\"\"\n\n") - fp.close() - - -generate_doc(arrow.T, "arrow") -generate_doc(area.T, "area") -generate_doc(axis.X, "axis", "_x") -generate_doc(axis.Y, "axis", "_y", 1) -generate_doc(bar_plot.T, "bar_plot") -generate_doc(line_plot.T, "line_plot") -generate_doc(pie_plot.T, "pie_plot") -generate_doc(color.T, "color") -generate_doc(error_bar.error_bar1, "error_bar","_1") -generate_doc(error_bar.error_bar2, "error_bar", "_2", 1) -generate_doc(error_bar.error_bar3, "error_bar", "_3", 1) -generate_doc(error_bar.error_bar4, "error_bar", "_4", 1) -generate_doc(error_bar.error_bar5, "error_bar", "_5", 1) -generate_doc(error_bar.error_bar6, "error_bar", "_6", 1) -generate_doc(fill_style.T, "fill_style") -generate_doc(text_box.T, "text_box") -generate_doc(range_plot.T, "range_plot") -generate_doc(legend.T, "legend") -generate_doc(legend.Entry, "legend", "_entry", 1) -generate_doc(line_style.T, "line_style") -generate_doc(tick_mark.T, "tick_mark") diff --git a/openerp/pychart/gs_frontend.py b/openerp/pychart/gs_frontend.py deleted file mode 100644 index 8e587b99689..00000000000 --- a/openerp/pychart/gs_frontend.py +++ /dev/null @@ -1,88 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import pychart_util -import theme -import sys -import os -import os.path -import pscanvas -import tempfile -import string -import basecanvas -from scaling import * - -def get_gs_path(): - """Guess where the Ghostscript executable is - and return its absolute path name.""" - path = os.defpath - if os.environ.has_key("PATH"): - path = os.environ["PATH"] - for dir in path.split(os.pathsep): - for name in ("gs", "gs.exe", "gswin32c.exe"): - g = os.path.join(dir, name) - if os.path.exists(g): - return g - raise Exception, "Ghostscript not found." - -class T(pscanvas.T): - def __write_contents(self, fp): - fp.write(pscanvas.preamble_text) - for name, id in self.__font_ids.items(): - fp.write("/%s {/%s findfont SF} def\n" % (id, name)) - fp.write("%d %d translate\n" % (-self.bbox[0], -self.bbox[1])) - fp.writelines(self.__output_lines) - fp.write("showpage end\n") - fp.flush() - - def close(self): - # Don't call pscanvas.T.close, as it creates a - # ps file. - basecanvas.T.close(self) - - def start_gs(self, arg): - self.bbox = theme.adjust_bounding_box([xscale(self.__xmin), - yscale(self.__ymin), - xscale(self.__xmax), - yscale(self.__ymax)]) - - gs_path = get_gs_path() - self.pipe_fp = None - if self.__output_lines == []: - return - - if sys.platform != "win32" and hasattr(os, "popen"): - # UNIX-like systems - cmdline = "\"%s\" -q %s -g%dx%d -q >/dev/null 2>&1" % \ - (gs_path, arg, - self.bbox[2] - self.bbox[0], - self.bbox[3] - self.bbox[1]) - self.pipe_fp = os.popen(cmdline, "w") - self.__write_contents(self.pipe_fp) - else: - # XXX should use mktemp, but need to support python<=2.2 as well. - fname = tempfile.mktemp("xxx") - fp = open(fname, "wb") - self.__write_contents(fp) - fp.close() - cmdline = "\"%s\" -q %s -g%dx%d -q <%s >NUL" % \ - (gs_path, arg, - self.bbox[2] - self.bbox[0], - self.bbox[3] - self.bbox[1], fname) - os.system(cmdline) - os.unlink(fname) - def close_gs(self): - if self.pipe_fp: - self.pipe_fp.close() - self.pipe_fp = None diff --git a/openerp/pychart/interval_bar_plot.py b/openerp/pychart/interval_bar_plot.py deleted file mode 100644 index 5fb1bd138d4..00000000000 --- a/openerp/pychart/interval_bar_plot.py +++ /dev/null @@ -1,229 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import line_style -import fill_style -import pychart_util -import chart_object -import legend -import bar_plot_doc -import theme -from types import * -from pychart_types import * - -fill_styles = None - -_keys = { - "direction" : (StringType, "vertical", - """The direction the growth of the bars. The value is either 'horizontal' - or 'vertical'."""), - "data" : (AnyType, None, """Specifes data points. Unlike other types - of charts, the "hcol"th column of the data must be a sequence of - numbers, not just a single number. See also the description of - "hcol".""" - ), - "data_label_offset": (CoordType, (0, 5), - "The location of data labels relative to the sample point. See also attribute data_label_format."), - - "data_label_format": (FormatType, None, """The - format string for the label displayed besides each - bar. It can be a `printf' style format - string, or a two-parameter function that - takes (x,y) values and returns a string. """ - + pychart_util.string_desc), - - "label": (StringType, "???", pychart_util.label_desc), - "bcol" : (IntType, 0, - """Specifies the column from which base values (i.e., X values when attribute "direction" is "vertical", Y values otherwise) are extracted. -The - combination of "data", "bcol", and "hcol" attributes defines - the set of boxes drawn by this chart. - See also the descriptions of the 'bcol' and 'data' attributes. - """), - "hcol": (IntType, 1, - """The column from which the base and height of - bars are extracted. See the below example: - -@example - d = [[5,[10,15,22]], [7,[22,23,5,10]], [8,[25,3]]] - p = interval_bar_plot.T(data = d, bcol = 0, hcol = 1) -@end example - - Here, three sequence of bars will be drawn. - The X locations of the bars - will be 5, 7, and 8. For example, at location X=7, - three bars are drawn, - one corresponding to Y values of 22 to 45 (=22+23), - and the second one for values 45 to 50, and the third one - for values 50 to 60. The line and fill styles of the bars - are picked in a round-robin fashion - from attributes "line_styles" and - "fill_styles". - """), - "line_styles": (ListType, [line_style.default, None], - """The list of line styles for bars. - The style of each bar is chosen in a round-robin fashion, if the - number of elements in "line_styles" is smaller than - actual number of boxes."""), - "fill_styles": (ListType, [lambda: fill_styles.next(), None], - """List of fill styles for bars. - The style of each bar is chosen in a round-robin fashion, if the - number of elements in "line_styles" is smaller than - actual number of boxes. - If this attribute is omitted, - a style is picked from standard styles round-robin. <<fill_style>>."""), - "cluster": (TupleType, (0, 1), """This attribute is used to - cluster multiple bar plots side by side in a single chart. - The value should be a tuple of two integers. The second value should be equal to the total number of bar plots in the chart. The first value should be the relative position of this chart; 0 places this chart the leftmost, and N-1 - (where N is the 2nd value of this attribute) places this chart the rightmost. Consider the below example: - -@example - a = area.T(...) - p1 = interval_bar_plot.T(data = [[1, [20,10]][2,[30,5]]], cluster=(0,2)) - p2 = interval_bar_plot.T(data = [[1,[25,11,2]],[2,[10,5,3]]], cluster=(1,2)) - a.add_plot(p1, p2) - a.draw() -@end example - - In this example, one group of bars will be drawn side-by-side at - position x=1. - Other two bars will be drawn side by side at position x=2. - See also the description of attribute "cluster" for bar_plot.T. - """), - "width": (UnitType, 5, """Width of each box. The unit is in points. -@cindex width, bar chart -@cindex size, bar chart -"""), - "cluster_sep": (UnitType, 0, """The separation between - clustered boxes. The unit is points."""), - "stack_on": (AnyType, None, - "The value must be either None or bar_plot.T. If not None, bars of this plot are stacked on top of another bar plot."), - } - -class T(chart_object.T): - __doc__ = bar_plot_doc.doc - keys = _keys - def check_integrity(self): - self.type_check() - def get_value(self, bval): - for pair in self.data: - if pair[self.bcol] == bval: - return pair[self.hcol] - raise ValueError, str(bval) + ": can't find the xval" - - def __get_data_range(self, col): - gmin = 99999999 - gmax = -99999999 - for item in self.data: - seq = item[col] - if seq[0] < gmin: gmin = seq[0] - max = 0 - for v in seq: - max += v - if max > gmax: gmax = max - return (gmin, gmax) - - def get_data_range(self, which): - if self.direction == 'vertical': - if which == 'X': - return pychart_util.get_data_range(self.data, self.bcol) - else: - return self.__get_data_range(self.hcol) - else: - assert self.direction == 'horizontal' - if which == 'Y': - return pychart_util.get_data_range(self.data, self.bcol) - else: - return self.__get_data_range(self.hcol) - - def get_style(self, nth): - line_style = self.line_styles[nth % len(self.line_styles)] - fill_style = self.fill_styles[nth % len(self.fill_styles)] - return (line_style, fill_style) - - def draw_vertical(self, ar, can): - for pair in self.data: - xval = pair[self.bcol] - yvals = pychart_util.get_sample_val(pair, self.hcol) - - if None in (xval, yvals): continue - - ybot = 0 - - totalWidth = (self.width+self.cluster_sep) * self.cluster[1] - self.cluster_sep - firstX = ar.x_pos(xval) - totalWidth/2.0 - thisX = firstX + (self.width+self.cluster_sep) * self.cluster[0] - self.cluster_sep - - cury = yvals[0] - n = 0 - - for yval in yvals[1:]: - (line_style, fill_style) = self.get_style(n) - can.rectangle(line_style, fill_style, - thisX, ar.y_pos(cury), thisX+self.width, - ar.y_pos(cury + yval)) - cury += yval - n += 1 - - if self.data_label_format: - can.show(thisX + self.width/2.0 + self.data_label_offset[0], - ar.y_pos(cury) + self.data_label_offset[1], - "/hC" + pychart_util.apply_format(self.data_label_format, (pair[self.bcol], pair[self.hcol]), 1)) - - def draw_horizontal(self, ar, can): - for pair in self.data: - yval = pair[self.bcol] - xvals = pychart_util.get_sample_val(pair, self.hcol) - - if None in (xvals, yval): continue - - totalWidth = (self.width+self.cluster_sep) * self.cluster[1] - self.cluster_sep - firstY = ar.y_pos(yval) - totalWidth/2.0 - thisY = firstY + (self.width+self.cluster_sep) * self.cluster[0] - self.cluster_sep - - curx = xvals[0] - n = 0 - for xval in xvals[1:]: - line_style, fill_style = self.get_style(n) - can.rectangle(line_style, fill_style, - ar.x_pos(curx), thisY, - ar.x_pos(xval), thisY+self.width) - curx = xval - n += 1 - - def get_legend_entry(self): - if self.label: - return legend.Entry(line_style=self.line_styles[0], - fill_style=self.fill_styles[0], - label=self.label) - return None - - def draw(self, ar, can): - self.type_check() - can.clip(ar.loc[0], ar.loc[1], - ar.loc[0] + ar.size[0], ar.loc[1] + ar.size[1]) - - if self.direction == "vertical": - self.draw_vertical(ar, can) - else: - self.draw_horizontal(ar, can) - - can.endclip() - -def init(): - global fill_styles - fill_styles = fill_style.standards.iterate() - -theme.add_reinitialization_hook(init) - diff --git a/openerp/pychart/legend.py b/openerp/pychart/legend.py deleted file mode 100644 index 8cd7e230921..00000000000 --- a/openerp/pychart/legend.py +++ /dev/null @@ -1,182 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import tick_mark -import font -import line_style -import color -import fill_style -import chart_object -import pychart_util -import types -import legend_doc -import theme - -from pychart_types import * -from types import * - -class Entry(chart_object.T): - keys = {"line_len" : (UnitType, None, - "Length of the sample line for line plots. If omitted, it is set to be theme.default_font_size"), - "rect_size" : (UnitType, None, - "Size of the sample 'blob' for bar range charts. If omitted, it is set to be 70% of theme.default_size"), - "tick_mark": (tick_mark.T, None, ""), - "line_style": (line_style.T, None, ""), - "fill_style": (fill_style.T, None, ""), - "label": (StringType, "???", ""), - } - __doc__ = legend_doc.doc_entry -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - - def label_width(self): - return font.text_width(" " + self.label) - def get_line_len(self): - return self.line_len or theme.default_font_size - def get_rect_size(self): - return self.rect_size or theme.default_font_size * 7 / 10.0 - - def sample_width(self): - w = 0 - if self.fill_style != None: - w += self.get_line_len() - elif self.line_style != None: - w += self.get_line_len() - elif self.tick_mark != None: - w += self.tick_mark.size - return w - def height(self): - h = font.text_height(self.label)[0] - return h - - def draw(self, ar, can, x_tick, x_label, y): - """Draw a legend entry. X_TICK and X_LABEL are the X location \ - (in points) of where the sample and label are drawn.""" - - rect_size = self.get_rect_size() - line_len = self.get_line_len() - - nr_lines = len(self.label.split("\n")) - text_height = font.text_height(self.label)[0] - line_height = text_height / float(nr_lines) - y_center = y + text_height - line_height/1.5 - - if self.fill_style != None: - can.rectangle(self.line_style, self.fill_style, - x_tick, y_center - rect_size/2.0, - x_tick + rect_size, - y_center + rect_size/2.0) - elif self.line_style != None: - can.line(self.line_style, x_tick, y_center, - x_tick + line_len, y_center) - if self.tick_mark != None: - self.tick_mark.draw(can, x_tick + line_len/2.0, y_center) - elif self.tick_mark != None: - self.tick_mark.draw(can, x_tick, y_center) - - can.show(x_label, y, self.label) - -__doc__ = """Legend is a rectangular box drawn in a chart to describe -the meanings of plots. The contents of a legend box is extracted from -plots' "label", "line-style", and "tick-mark" attributes. - -This module exports a single class, legend.T. Legend.T is a part of -an area.T object, and is drawn automatically when area.draw() method -is called. """ - -class T(chart_object.T): - __doc__ = legend_doc.doc - keys = { - "inter_row_sep": (UnitType, 0, - "Space between each row in the legend."), - "inter_col_sep": (UnitType, 0, - "Space between each column in the legend."), - "frame_line_style": (line_style.T, line_style.default, ""), - "frame_fill_style": (fill_style.T, fill_style.white, ""), - "top_fudge": (UnitType, 0, - "Amount of space above the first line."), - "bottom_fudge": (UnitType, 3, - "Amount of space below the last line."), - "left_fudge": (UnitType, 5, - "Amount of space left of the legend."), - "right_fudge": (UnitType, 5, - "Amount of space right of the legend."), - "loc": (CoordType, None, - """Bottom-left corner of the legend. - The default location of a legend is the bottom-right end of the chart."""), - "shadow": (ShadowType, None, pychart_util.shadow_desc), - "nr_rows": (IntType, 9999, "Number of rows in the legend. If the number of plots in a chart is larger than nr_rows, multiple columns are created in the legend."), - - } -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def draw(self, ar, entries, can): - if not self.loc: - x = ar.loc[0] + ar.size[0] * 1.1 - y = ar.loc[1] - else: - x = self.loc[0] - y = self.loc[1] - - nr_rows = min(self.nr_rows, len(entries)) - nr_cols = (len(entries)-1) / nr_rows + 1 - - ymin = y - max_label_width = [0] * nr_cols - max_sample_width = [0] * nr_cols - heights = [0] * nr_rows - - for i in range(len(entries)): - l = entries[i] - (col, row) = divmod(i, nr_rows) - max_label_width[col] = max(l.label_width(), max_label_width[col]) - max_sample_width[col] = max(l.sample_width(), max_sample_width[col]) - heights[row] = max(l.height(), heights[row]) - - for h in heights: - y += h - y += self.inter_row_sep * (nr_rows - 1) - ymax = y - - tot_width = self.inter_col_sep * (nr_cols -1) - for w in max_label_width: - tot_width += w - for w in max_sample_width: - tot_width += w - - can.rectangle(self.frame_line_style, self.frame_fill_style, - x - self.left_fudge, - ymin - self.bottom_fudge, - x + tot_width + self.right_fudge, - ymax + self.top_fudge, - self.shadow) - - for col in range(nr_cols): - this_y = y - this_x = x - for row in range(nr_rows): - idx = col * nr_rows + row - if idx >= len(entries): - continue - this_y -= heights[row] - l = entries[idx] - if row != 0: - this_y -= self.inter_row_sep - - l.draw(ar, can, this_x, this_x + max_sample_width[col], this_y) - x += max_label_width[col] + max_sample_width[col] + self.inter_col_sep - - diff --git a/openerp/pychart/legend_doc.py b/openerp/pychart/legend_doc.py deleted file mode 100644 index dacbdafa9c6..00000000000 --- a/openerp/pychart/legend_doc.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -inter_col_sep(type:length in points (\\xref{unit})) default="Space between each column in the legend.". -loc(type:(x,y)) default="Bottom-left corner of the legend. - The default location of a legend is the bottom-right end of the chart.". -bottom_fudge(type:length in points (\\xref{unit})) default="Amount of space below the last line.". -frame_line_style(type:line_style.T) default="". -nr_rows(type:int) default="Number of rows in the legend. If the number of plots in a chart is larger than nr_rows, multiple columns are created in the legend.". -right_fudge(type:length in points (\\xref{unit})) default="Amount of space right of the legend.". -inter_row_sep(type:length in points (\\xref{unit})) default="Space between each row in the legend.". -top_fudge(type:length in points (\\xref{unit})) default="Amount of space above the first line.". -left_fudge(type:length in points (\\xref{unit})) default="Amount of space left of the legend.". -shadow(type:<function ShadowType at 0xb7d4db8c>) default="The value is either None or a tuple. When non-None, -a drop-shadow is drawn beneath the object. X-off, and y-off specifies the -offset of the shadow relative to the object, and fill specifies the -style of the shadow (@pxref{module-fill-style}).". -frame_fill_style(type:fill_style.T) default="". -""" - -doc_entry="""Attributes supported by this class are: -line_len(type:length in points (\\xref{unit})) default="Length of the sample line for line plots. If omitted, it is set to be theme.default_font_size". -label(type:str) default="". -rect_size(type:length in points (\\xref{unit})) default="Size of the sample 'blob' for bar range charts. If omitted, it is set to be 70% of theme.default_size". -tick_mark(type:tick_mark.T) default="". -line_style(type:line_style.T) default="". -fill_style(type:fill_style.T) default="". -""" - diff --git a/openerp/pychart/line_plot.py b/openerp/pychart/line_plot.py deleted file mode 100644 index d80d5d69231..00000000000 --- a/openerp/pychart/line_plot.py +++ /dev/null @@ -1,151 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import tick_mark -import line_style -import pychart_util -import error_bar -import chart_object -import legend -import object_set -import line_plot_doc -import theme -from pychart_types import * -from types import * - -default_width = 1.2 -line_style_itr = None - - -_keys = { - "data" : (AnyType, None, pychart_util.data_desc), - "label": (StringType, "???", pychart_util.label_desc), - "data_label_offset": (CoordType, (0, 5), - """The location of data labels relative to the sample point. Meaningful only when data_label_format != None."""), - "data_label_format": (FormatType, None, - """The format string for the label printed - beside a sample point. - It can be a `printf' style format string, or - a two-parameter function that takes the (x, y) - values and returns a string. """ - + pychart_util.string_desc), - "xcol" : (IntType, 0, pychart_util.xcol_desc), - "ycol": (IntType, 1, pychart_util.ycol_desc), - "y_error_minus_col": (IntType, 2, - """The column (within "data") from which the depth of the errorbar is extracted. Meaningful only when error_bar != None. <<error_bar>>"""), - "y_error_plus_col": (IntType, -1, - """The column (within "data") from which the height of the errorbar is extracted. Meaningful only when error_bar != None. <<error_bar>>"""), - "y_qerror_minus_col": (IntType, -1, "<<error_bar>>"), - "y_qerror_plus_col": (IntType, -1, "<<error_bar>>"), - - "line_style": (line_style.T, lambda: line_style_itr.next(), pychart_util.line_desc, - "By default, a style is picked from standard styles round-robin. <<line_style>>"), - - "tick_mark": (tick_mark.T, None, pychart_util.tick_mark_desc), - "error_bar": (error_bar.T, None, - "The style of the error bar. <<error_bar>>"), - } - -class T(chart_object.T): - __doc__ = line_plot_doc.doc - keys = _keys - def check_integrity(self): - self.type_check() - -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def get_data_range(self, which): - if which == 'X': - return pychart_util.get_data_range(self.data, self.xcol) - else: - return pychart_util.get_data_range(self.data, self.ycol) - def get_legend_entry(self): - if self.label: - return legend.Entry(line_style=self.line_style, - tick_mark=self.tick_mark, - fill_style=None, - label=self.label) - return None - - def draw(self, ar, can): - - # Draw the line - - clipbox = theme.adjust_bounding_box([ar.loc[0], ar.loc[1], - ar.loc[0] + ar.size[0], - ar.loc[1] + ar.size[1]]); - - can.clip(clipbox[0],clipbox[1],clipbox[2],clipbox[3]) - if self.line_style: - points = [] - for pair in self.data: - yval = pychart_util.get_sample_val(pair, self.ycol) - xval = pair[self.xcol] - if None not in (xval, yval): - points.append((ar.x_pos(xval), ar.y_pos(yval))) - can.lines(self.line_style, points) - can.endclip() - - # Draw tick marks and error bars - can.clip(ar.loc[0] - 10, ar.loc[1] - 10, - ar.loc[0] + ar.size[0] + 10, - ar.loc[1] + ar.size[1] + 10) - for pair in self.data: - x = pair[self.xcol] - y = pychart_util.get_sample_val(pair, self.ycol) - if None in (x, y): continue - - x_pos = ar.x_pos(x) - y_pos = ar.y_pos(y) - - if self.error_bar: - plus = pair[self.y_error_plus_col or self.y_error_minus_col] - minus = pair[self.y_error_minus_col or self.y_error_plus_col] - if self.y_qerror_minus_col or self.y_qerror_plus_col: - q_plus = pair[self.y_qerror_plus_col or self.y_qerror_minus_col] - q_minus = pair[self.y_qerror_minus_col or self.y_qerror_plus_col] - if None not in (minus,plus,q_minus,q_plus): - self.error_bar.draw(can, (x_pos, y_pos), - ar.y_pos(y - minus), - ar.y_pos(y + plus), - ar.y_pos(y - q_minus), - ar.y_pos(y + q_plus)) - else: - if None not in (minus,plus): #PDS - self.error_bar.draw(can, (x_pos, y_pos), - ar.y_pos(y - minus), - ar.y_pos(y + plus)) - - if self.tick_mark: - self.tick_mark.draw(can, x_pos, y_pos) - if self.data_label_format: - can.show(x_pos + self.data_label_offset[0], - y_pos + self.data_label_offset[1], - "/hC" + pychart_util.apply_format(self.data_label_format, (x, y), 1)) - - can.endclip() - -def init(): - global line_style_itr - line_styles = object_set.T() - for org_style in line_style.standards.list(): - style = line_style.T(width = default_width, color = org_style.color, - dash = org_style.dash) - line_styles.add(style) - - line_style_itr = line_styles.iterate() - -theme.add_reinitialization_hook(init) - diff --git a/openerp/pychart/line_plot_doc.py b/openerp/pychart/line_plot_doc.py deleted file mode 100644 index ac6ff3b21c7..00000000000 --- a/openerp/pychart/line_plot_doc.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -y_qerror_minus_col(type:int) default="<<error_bar>>". -xcol(type:int) default="The column, within attribute "data", from which the X values of sample points are extracted. <<chart_data>>". -error_bar(type:error_bar.T) default="The style of the error bar. <<error_bar>>". -data_label_format(type:printf format string) default="The format string for the label printed - beside a sample point. - It can be a `printf' style format string, or - a two-parameter function that takes the (x, y) - values and returns a string. The appearance of the string produced here can be -controlled using escape sequences. <<font>>". -ycol(type:int) default="The column, within attribute "data", from which the Y values of sample points are extracted. <<chart_data>>". -label(type:str) default="The label to be displayed in the legend. <<legend>>, <<font>>". -line_style(type:line_style.T) default="The style of the line. ". - By default, a style is picked from standard styles round-robin. - See also pychart.line_style - -y_error_plus_col(type:int) default="The column (within "data") from which the height of the errorbar is extracted. Meaningful only when error_bar != None. <<error_bar>>". -tick_mark(type:tick_mark.T) default="Tick marks to be displayed at each sample point. <<tick_mark>>". -y_error_minus_col(type:int) default="The column (within "data") from which the depth of the errorbar is extracted. Meaningful only when error_bar != None. <<error_bar>>". -data_label_offset(type:(x,y)) default="The location of data labels relative to the sample point. Meaningful only when data_label_format != None.". -data(type:any) default="Specifies the data points. <<chart_data>>". -y_qerror_plus_col(type:int) default="<<error_bar>>". -""" - diff --git a/openerp/pychart/line_style.py b/openerp/pychart/line_style.py deleted file mode 100644 index 861ddc74355..00000000000 --- a/openerp/pychart/line_style.py +++ /dev/null @@ -1,159 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import color -import pychart_util -import chart_object -import object_set -import theme -import line_style_doc -from pychart_types import * -from types import * - -_keys = { - "width" : (UnitType, theme.default_line_width, "Width of the line, in points."), - "color": (color.T, color.default, "The color of the line."), - "dash" : (TupleType, None, - """The value - of None will draw a solid line. Otherwise, this - attribute specifies the style of dashed lines. - The 2N'th value specifies the length of the line (in points), - and 2N+1'th value specifies the length of the blank. - - For example, the dash style of (3,2,4,1) draws a dashed line that - looks like @samp{---__----_---__----_...}. - """), - "cap_style": (IntType, 0, - """Defines the style of the tip of the line segment. - 0: butt cap (square cutoff, with no projection beyond), - 1: round cap (arc), 2: projecting square cap - (square cutoff, but the line extends half the line width). - See also Postscript/PDF reference manual."""), - "join_style": (IntType, 0, - """Join style. 0: Miter join (sharp, pointed corners), - 1: round join (rounded corners), - 2: bevel join (flattened corners). - See also Postscript/PDF reference manual.""") - } - -class T(chart_object.T): - __doc__ = line_style_doc.doc - keys = _keys -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def __str__(self): - s = name_table().lookup(self) - if s: - return s - return "<linestyle: width=%s, color=%s, dash=%s, cap=%d, join=%d>" \ - % (self.width, self.color, self.dash, self.cap_style, self.join_style) - -default = T(color=color.default) - -dash1 = 1.5,1.5 # - - - - -dash2 = 5,2,5,2 # -- -- -- -- -dash3 = 1,1 - -black = T(color=color.black) -black_dash1 = T(color=color.black, dash=dash1) -black_dash2 = T(color=color.black, dash=dash2) -black_dash3 = T(color=color.black, dash=dash3) - -gray70 = T(color=color.gray70) -gray70_dash1 = T(color=color.gray70, dash=dash1) -gray70_dash2 = T(color=color.gray70, dash=dash2) -gray70_dash3 = T(color=color.gray70, dash=dash3) - -gray10 = T(color=color.gray10) -gray10_dash1 = T(color=color.gray10, dash=dash1) -gray10_dash2 = T(color=color.gray10, dash=dash2) -gray10_dash3 = T(color=color.gray10, dash=dash3) - -gray50 = T(color=color.gray50) -gray50_dash1 = T(color=color.gray50, dash=dash1) -gray50_dash2 = T(color=color.gray50, dash=dash2) -gray50_dash3 = T(color=color.gray50, dash=dash3) - -gray60 = T(color=color.gray60) -gray60_dash1 = T(color=color.gray60, dash=dash1) -gray60_dash2 = T(color=color.gray60, dash=dash2) -gray60_dash3 = T(color=color.gray60, dash=dash3) - -gray90 = T(color=color.gray90) -gray90_dash1 = T(color=color.gray90, dash=dash1) -gray90_dash2 = T(color=color.gray90, dash=dash2) -gray90_dash3 = T(color=color.gray90, dash=dash3) - -gray30 = T(color=color.gray30) -gray30_dash1 = T(color=color.gray30, dash=dash1) -gray30_dash2 = T(color=color.gray30, dash=dash2) -gray30_dash3 = T(color=color.gray30, dash=dash3) - -white = T(color=color.white) -default = black - -red = T(color=color.red) -darkblue = T(color=color.darkblue) -darkseagreen = T(color=color.darkseagreen) -darkkhaki = T(color = color.darkkhaki) - -blue = T(color=color.blue) -green = T(color=color.green) - -red_dash1 = T(color=color.red, dash=dash1) -darkblue_dash1 = T(color=color.darkblue, dash=dash1) -darkseagreen_dash1 = T(color=color.darkseagreen, dash=dash1) -darkkhaki_dash1 = T(color=color.darkkhaki, dash=dash1) - -red_dash2 = T(color=color.red, dash=dash2) -darkblue_dash2 = T(color=color.darkblue, dash=dash2) -darkseagreen_dash2 = T(color=color.darkseagreen, dash=dash2) -darkkhaki_dash2 = T(color=color.darkkhaki, dash=dash2) - -standards = None -_name_table = None - -def init(): - global standards, _name_table - standards = object_set.T() - - if theme.use_color: - standards.add(black, red, darkblue, gray70, darkseagreen, - darkkhaki, gray30, - black_dash1, red_dash1, darkblue_dash1, gray70_dash1, - darkseagreen_dash1, darkkhaki_dash1, gray30_dash1, - black_dash2, red_dash2, darkblue_dash2, gray70_dash2, - darkseagreen_dash2, darkkhaki_dash2, gray30_dash2) - else: - standards.add(black, black_dash1, black_dash2, - gray70, gray70_dash1, gray70_dash2, - gray10, gray10_dash1, gray10_dash2, - gray50, gray50_dash1, gray50_dash2, - gray90, gray90_dash1, gray90_dash2, - gray30, gray30_dash1, gray30_dash2, - black_dash3, - gray70_dash3, gray10_dash3, gray50_dash3, gray90_dash3) - for style in standards.list(): - style.width = theme.default_line_width - _name_table = None - -def name_table(): - global _name_table - if not _name_table: - _name_table = pychart_util.symbol_lookup_table(globals(), standards) - return _name_table - -init() -theme.add_reinitialization_hook(init) diff --git a/openerp/pychart/line_style_doc.py b/openerp/pychart/line_style_doc.py deleted file mode 100644 index e7dc4e7f379..00000000000 --- a/openerp/pychart/line_style_doc.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -color(type:color.T) default="The color of the line.". -width(type:length in points (\\xref{unit})) default="Width of the line, in points.". -dash(type:tuple) default="The value - of None will draw a solid line. Otherwise, this - attribute specifies the style of dashed lines. - The 2N'th value specifies the length of the line (in points), - and 2N+1'th value specifies the length of the blank. - - For example, the dash style of (3,2,4,1) draws a dashed line that - looks like @samp{---__----_---__----_...}. - ". -cap_style(type:int) default="Defines the style of the tip of the line segment. - 0: butt cap (square cutoff, with no projection beyond), - 1: round cap (arc), 2: projecting square cap - (square cutoff, but the line extends half the line width). - See also Postscript/PDF reference manual.". -join_style(type:int) default="Join style. 0: Miter join (sharp, pointed corners), - 1: round join (rounded corners), - 2: bevel join (flattened corners). - See also Postscript/PDF reference manual.". -""" - diff --git a/openerp/pychart/linear_coord.py b/openerp/pychart/linear_coord.py deleted file mode 100644 index b21075c1860..00000000000 --- a/openerp/pychart/linear_coord.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import coord -import math -import pychart_util - -class T(coord.T): - def get_canvas_pos(self, size, val, min, max2): - return size * (val - min) / max(float(max2 - min),0.01) - - def get_tics(self, min, max, interval): - v = [] - x = min - while x <= max: - v.append(x) - x += interval - return v - def get_min_max(self, dmin, dmax, interval): - if not interval: - if dmax == dmin: - interval = 10 - else: - interval = 10 ** (float(int(math.log(dmax-dmin)/math.log(10)))) - dmin = min(dmin, pychart_util.round_down(dmin, interval)) - dmax = max(dmax, pychart_util.round_up(dmax, interval) + interval/2.0) - return dmin, dmax, interval diff --git a/openerp/pychart/log_coord.py b/openerp/pychart/log_coord.py deleted file mode 100644 index 22a5b22c8f8..00000000000 --- a/openerp/pychart/log_coord.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import coord -import math - -class T(coord.T): - def get_canvas_pos(self, size, val, min, max): - if val <= 0: - return 0 - xminl = math.log(min) - xmaxl = math.log(max) - vl = math.log(val) - return size * (vl-xminl) / float(xmaxl-xminl) - def get_tics(self, min, max, interval): - "Generate the list of places for drawing tick marks." - v = [] - if min <= 0: - raise Exception, "Min value (%s) < 0 in a log coordinate." % min - x = min - while x <= max: - v.append(x) - x = x * interval - return v - def get_min_max(self, dmin, dmax, interval): - interval = interval or 10 - dmin = max(0, dmin) # we can't have a negative value with a log scale. - v = 1.0 - while v > dmin: - v = v / interval - dmin = v - v = 1.0 - while v < dmax: - v = v * interval - dmax = v - - return dmin, dmax, interval - diff --git a/openerp/pychart/object_set.py b/openerp/pychart/object_set.py deleted file mode 100644 index 9fd22b9e4a7..00000000000 --- a/openerp/pychart/object_set.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -class T(object): - def __init__(self, *objs): - self.__objs = list(objs) - def add(self, *objs): - self.__objs.extend(objs) - def add_objects(self, objs): - self.__objs.extend(objs) - def iterate(self): - return Iterator(self) - def list(self): - return self.__objs - def __getitem__(self, idx): - return self.__objs[idx] - def nth(self, idx): - return self.__objs[idx] - -class Iterator(object): - def __init__(self, set_): - self.__set = set_ - self.__idx = 0 - def reset(self): - self.__idx = 0 - def next(self): - val = self.__set.nth(self.__idx) - self.__idx += 1 - if self.__idx >= len(self.__set.list()): - self.__idx = 0 - return val - - diff --git a/openerp/pychart/pdfcanvas.py b/openerp/pychart/pdfcanvas.py deleted file mode 100644 index 620bb8c1981..00000000000 --- a/openerp/pychart/pdfcanvas.py +++ /dev/null @@ -1,298 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import sys -import pychart_util -import string -import re -import math -import theme -import os -import basecanvas -from scaling import * - -try: - import zlib - _zlib_available_p = 1 -except: - _zlib_available_p = 0 - -class pdf_stream(object): - def __init__(self, fp): - self.fp = fp - self.off = 0 - def write(self, str): - self.fp.write(str) - self.off += len(str) - def tell(self): - return self.off - -def to_radian(deg): - return deg*2*math.pi / 360.0 - -class T(basecanvas.T): - def __init__(self, fname, compress_p_): - basecanvas.T.__init__(self) - self.__out_fname = fname - self.__reset_context() - self.__next_obj_id = 1 - self.__next_font_id = 1 - self.__obj_offsets = {} - self.__registered_fonts = {} - self.__lines = [] - self.__nr_gsave = 0 - - if compress_p_ and not _zlib_available_p: - pychart_util.warn("Zlib not available. Compression request ignored.\n") - compress_p_ = 0 - self.__compress_p = compress_p_ - - def __intern_font(self, name): - "Assign an ID to the font NAME. Return its ID." - if not self.__registered_fonts.has_key(name): - self.__registered_fonts[name] = self.__next_font_id - self.__next_font_id += 1 - return self.__registered_fonts[name] - - def __define_obj(self, fp, str): - obj_id = self.__next_obj_id - self.__next_obj_id += 1 - self.__obj_offsets[obj_id] = fp.tell() - fp.write("%d 0 obj\n%s\nendobj\n" % (obj_id, str)) - return obj_id - - def __define_stream_obj(self, fp, s): - if self.__compress_p: - p = zlib.compress(s) - return self.__define_obj(fp, "<</Length %d/Filter/FlateDecode>>\nstream\n%sendstream" - % (len(p), p)) - else: - return self.__define_obj(fp, "<</Length %d\n>>\nstream\n%s\nendstream" - % (len(s), s)) - - def __define_font_obj(self, fp, name, font_id): - obj_id = self.__define_obj(fp, """<</Type/Font /Subtype/Type1 /Name/F%d /BaseFont/%s /Encoding/MacRomanEncoding>>""" % (font_id, name)) - return obj_id - - def __reset_context(self): - self.__font_name = None - self.__font_size = -1 - self.__line_style = None - self.__fill_color = None - self.__stroke_color = None - self.__mtx_pushed = 0 - - def newpath(self): - pass - def set_fill_color(self, color): - if self.__fill_color == color: - return - if color.r == color.g and color.r == color.b: - self.__write("%f g\n" % (color.r)) - self.__write("%f G\n" % (color.r)) - else: - self.__write("%f %f %f rg\n" % (color.r, color.g, color.b)) - self.__write("%f %f %f RG\n" % (color.r, color.g, color.b)) - self.__fill_color = color - def set_stroke_color(self, color): - self.set_fill_color(color) - return - - def __arcsub(self, x, y, radius, start, theta): - xcos = math.cos(to_radian(theta)) - xsin = math.sin(to_radian(theta)) - x0 = radius * xcos - y0 = radius * xsin - x1 = radius * (4-xcos)/3.0 - y1 = radius * (1-xcos)*(xcos-3)/(3*xsin) - - xx0, xy0 = pychart_util.rotate(x0, y0, start+theta) - xx1, xy1 = pychart_util.rotate(x1, -y1, start+theta) - xx2, xy2 = pychart_util.rotate(x1, y1, start+theta) - self.__write("%f %f %f %f %f %f c\n" % - (x+xx1, y+xy1, x+xx2, y+xy2, x+xx0, y+xy0)) - def path_arc(self, x, y, radius, ratio, start, end): - self.comment("PATHARC %f %f %f %f %f %f\n" - % (x, y, radius, ratio, start, end)) - step = 10 - if radius < 10: - step = 20 - if radius < 5: - step = 30 - if ratio != 1.0: - self.push_transformation((x, y), (1, ratio), None) - deg = start - while deg < end: - theta = min(step, end-deg) - self.__arcsub(x, y, radius, deg, theta/2) - deg += theta - self.pop_transformation() - else: - deg = start - while deg < end: - theta = min(step, end-deg) - self.__arcsub(x, y, radius, deg, theta/2) - deg += theta - self.comment("end PATHARC\n") - - def text_begin(self): - self.__write("BT ") - self.__font_name = None - self.__font_size = None - - def text_end(self): - self.__write("ET\n") - def text_moveto(self, x, y, angle): - if angle != None: - xcos = math.cos(to_radian(angle)) - xsin = math.sin(to_radian(angle)) - self.__write("%f %f %f %f %f %f Tm " % (xcos, xsin, -xsin, xcos, x, y)) - else: - self.__write("1 0 0 1 %f %f Tm " % (x, y)) - - def text_show(self, font_name, font_size, color, str): - if self.__font_name != font_name or self.__font_size != font_size: - font_id = self.__intern_font(font_name) - self.__write("/F%d %d Tf " % (font_id, font_size)) - self.__font_name = font_name - self.__font_size = font_size - self.set_fill_color(color) - self.__write("(%s) Tj " % (str)) - - def push_transformation(self, baseloc, scale, angle, in_text = 0): - if in_text: - op = "Tm" - else: - op = "cm" - self.gsave() - - if baseloc == None: - baseloc = (0,0) - - if angle != None: - radian = to_radian(angle) - self.__write("%f %f %f %f %f %f %s\n" % - (math.cos(radian), math.sin(radian), - -math.sin(radian), math.cos(radian), - baseloc[0], baseloc[1], op)) - if scale != None: - self.__write("%f 0 0 %f %f %f %s\n" % (scale[0], scale[1], - baseloc[0], - baseloc[1], op)) - - def pop_transformation(self, in_text = 0): - if not in_text: - self.grestore() - def closepath(self): - self.__write("h\n") - def clip_sub(self): - self.__write("W n\n") - def fill(self): - self.__write("f n\n") - def gsave(self): - self.__write("q\n") - def grestore(self): - self.__write("Q\n") - self.__reset_context() - - def moveto(self, x, y): - self.__write('%f %f m ' % (x, y)) - def lineto(self, x, y): - self.__write("%f %f l\n" % (x, y)) - def stroke(self): - self.__write("S\n") - - def set_line_style(self, style): - if (self.__line_style == style): - pass - else: - self.set_stroke_color(style.color) - self.__write("%f w " % nscale(style.width)) - if style.dash != None: - self.__write("[%s] 0 d\n" % - " ".join(map(str, nscale_seq(style.dash)))) - else: - self.__write("[] 0 d\n") - self.__write("%d j %d J\n" % (style.cap_style, style.join_style)) - self.__line_style = style - - def comment(self, str): - if not self.__compress_p: - self.__write("%%" + str + "\n") - - def verbatim(self, str): - self.__write(str) - - def __write(self, str): - self.__lines.append(str) - -# def setbb(self, xmin, ymin, xmax, ymax): -# self.__xmin = xmin -# self.__ymin = ymin -# self.__xmax = xmax -# self.__ymax = ymax - - def close(self): - basecanvas.T.close(self) - if self.__lines == []: - return - - _fp, need_close = self.open_output(self.__out_fname) - fp = pdf_stream(_fp) - - fp.write("%PDF-1.2\n") - - stream_obj_id = self.__define_stream_obj(fp, " ".join(self.__lines)) - - fontstr = "" - for font_name, font_id in self.__registered_fonts.items(): - obj_id = self.__define_font_obj(fp, font_name, font_id) - fontstr += "/F%d %d 0 R " % (font_id, obj_id) - - pages_obj_id = self.__define_obj(fp, " <</Type/Pages /Kids [%d 0 R] /Count 1 >>" % (self.__next_obj_id + 1)) - - bbox = theme.adjust_bounding_box([xscale(self.__xmin), yscale(self.__ymin), - xscale(self.__xmax), yscale(self.__ymax)]) - - page_obj_id = self.__define_obj(fp, """ <</Type/Page -\t/Parent %d 0 R -\t/Contents %d 0 R -\t/MediaBox [%d %d %d %d] -\t/Resources << /ProcSet [/PDF /Text] -\t\t/Font << %s >> ->> >>""" % (pages_obj_id, stream_obj_id, - bbox[0], bbox[1], bbox[2], bbox[3], fontstr)) - - info_str = "/Producer (%s)\n/CreationDate (%s)" % (self.creator, self.creation_date) - - if self.title: - info_str += "\n/Title (%s)" % (self.title, ) - if self.author: - info_str += "\n/Author (%s)" % (self.author, ) - - info_obj_id = self.__define_obj(fp, """<<%s>>""" % info_str) - catalog_obj_id = self.__define_obj(fp, """ <</Type/Catalog/Pages %d 0 R>>""" % (pages_obj_id)) - - xref_offset = fp.tell() - fp.write("xref\n0 %d\n" % (len(self.__obj_offsets)+1)) - fp.write("0000000000 65535 f \n") - id = 1 - while id <= len(self.__obj_offsets): - fp.write("%010d 00000 n \n" % (self.__obj_offsets[id])) - id += 1 - fp.write("trailer << /Size %d /Root %d 0 R /Info %d 0 R\n>>\n" % (len(self.__obj_offsets)+1, catalog_obj_id, info_obj_id)) - fp.write("startxref\n%d\n%%%%EOF\n" % xref_offset) - - if need_close: - _fp.close() diff --git a/openerp/pychart/pie_plot.py b/openerp/pychart/pie_plot.py deleted file mode 100644 index b5f14bcde2f..00000000000 --- a/openerp/pychart/pie_plot.py +++ /dev/null @@ -1,149 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import text_box -import fill_style -import line_style -import pychart_util -import chart_object -import arrow -import legend -import font -import pie_plot_doc -import theme - -from pychart_types import * -from types import * - -class T(chart_object.T): - __doc__ = pie_plot_doc.doc - keys = { - "start_angle" : (NumType, 90, - """The angle at which the first item is drawn."""), - "center" : (CoordType, None, "The location of the center of the pie."), - "radius" : (UnitType, None, "The radius of the pie."), - "line_style" : (line_style.T, line_style.default, "The style of the outer edge of each pie slice."), - - "fill_styles" : (ListType, fill_style.standards.list(), - """The fill style of each item. The length of the - list should be equal to the length of the data. - """), - "arc_offsets" : (ListType, None, - """You can draw each pie "slice" shifted off-center. - This attribute, if non-None, - must be a number sequence whose length is equal to - the number of pie slices. The Nth value in arc_offsets - specify the amount of offset - (from the center of the circle) - for the Nth slice. - The value of None will draw all the slices - anchored at the center. - """ - ), - "data" : (AnyType, None, pychart_util.data_desc), - "label_format" : (FormatType, "%s", - "Format string of the label"), - "label_col" : (IntType, 0, - """The column, within "data", from which the labels of items are retrieved."""), - "data_col": (IntType, 1, - """ The column, within "data", from which the data values are retrieved."""), - "label_offset": (UnitType, None, "The distance from the center of each label."), - "arrow_style": (arrow.T, None, - """The style of arrow that connects a label - to the corresponding "pie"."""), - "label_line_style": (line_style.T, None, "The style of the frame surrounding each label."), - "label_fill_style": (fill_style.T, fill_style.default, "The fill style of the frame surrounding each label."), - "shadow": (ShadowType, None, pychart_util.shadow_desc) - } -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def _total(self): - v = 0 - for val in self.data: - v += val[self.data_col] - return v - - def check_integrity(self): - self.type_check() - def get_data_range(self, which): - return (0, 1) - def get_legend_entry(self): - legends = [] - i = 0 - for val in self.data: - fill = self.fill_styles[i] - i = (i + 1) % len(self.fill_styles) - legends.append(legend.Entry(line_style=self.line_style, - fill_style=fill, - label=val[self.label_col])) - return legends - - def draw(self, ar, can): - center = self.center - if not center: - center = (ar.loc[0] + ar.size[0]/2.0, - ar.loc[1] + ar.size[1]/2.0) - radius = self.radius - if not radius: - radius = min(ar.size[0]/2.0, ar.size[1]/2.0) * 0.5 - - label_offset = radius + (self.label_offset or radius * 0.1) - - total = self._total() - i = 0 - cur_angle = self.start_angle - for val in self.data: - fill = self.fill_styles[i] - degree = 360 * float(val[self.data_col]) / float(total) - - off = (0, 0) - if len(self.arc_offsets) > i: - off = pychart_util.rotate(self.arc_offsets[i], 0, cur_angle - degree/2.0) - x_center = center[0]+ off[0] - y_center = center[1]+ off[1] - - can.ellipsis(self.line_style, fill, - x_center, y_center, radius, 1, - cur_angle - degree, cur_angle, - self.shadow) - - label = pychart_util.apply_format(self.label_format, val, - self.label_col) - if label != None: - (x_label, y_label) = pychart_util.rotate(label_offset, 0, cur_angle - degree/2.0) - (x_arrowtip, y_arrowtip) = pychart_util.rotate(radius, 0, cur_angle - degree/2.0) - # Labels on left side of pie need - # their text to avoid obscuring the pie - if x_label < 0: - x_label = x_label - font.text_width(label) - - t = text_box.T(loc = (x_label + x_center, y_label + y_center), - text = label, - line_style = self.label_line_style, - fill_style = self.label_fill_style) - if self.arrow_style: - t.add_arrow((x_arrowtip + x_center, y_arrowtip + y_center), - None, self.arrow_style) - - t.draw(can) - cur_angle = (cur_angle - degree) % 360 - i = (i + 1) % len(self.fill_styles) - - -def init(): - old_val = T.keys["fill_styles"] - T.keys["fill_styles"] = (old_val[0], fill_style.standards.list(), - old_val[2]) -theme.add_reinitialization_hook(init) diff --git a/openerp/pychart/pie_plot_doc.py b/openerp/pychart/pie_plot_doc.py deleted file mode 100644 index e7989085550..00000000000 --- a/openerp/pychart/pie_plot_doc.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -label_fill_style(type:fill_style.T) default="The fill style of the frame surrounding each label.". -center(type:(x,y)) default="The location of the center of the pie.". -arrow_style(type:arrow.T) default="The style of arrow that connects a label - to the corresponding "pie".". -start_angle(type:number) default="The angle at which the first item is drawn.". -label_format(type:printf format string) default="Format string of the label". -arc_offsets(type:list) default="You can draw each pie "slice" shifted off-center. - This attribute, if non-None, - must be a number sequence whose length is equal to - the number of pie slices. The Nth value in arc_offsets - specify the amount of offset - (from the center of the circle) - for the Nth slice. - The value of None will draw all the slices - anchored at the center. - ". -label_offset(type:length in points (\\xref{unit})) default="The distance from the center of each label.". -label_line_style(type:line_style.T) default="The style of the frame surrounding each label.". -label_col(type:int) default="The column, within "data", from which the labels of items are retrieved.". -data_col(type:int) default=" The column, within "data", from which the data values are retrieved.". -radius(type:length in points (\\xref{unit})) default="The radius of the pie.". -fill_styles(type:list) default="The fill style of each item. The length of the - list should be equal to the length of the data. - ". -line_style(type:line_style.T) default="The style of the outer edge of each pie slice.". -data(type:any) default="Specifies the data points. <<chart_data>>". -shadow(type:<function ShadowType at 0xb7d4db8c>) default="The value is either None or a tuple. When non-None, -a drop-shadow is drawn beneath the object. X-off, and y-off specifies the -offset of the shadow relative to the object, and fill specifies the -style of the shadow (@pxref{module-fill-style}).". -""" - diff --git a/openerp/pychart/pngcanvas.py b/openerp/pychart/pngcanvas.py deleted file mode 100644 index 5be7b33bbf6..00000000000 --- a/openerp/pychart/pngcanvas.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import sys -import os -import gs_frontend -import theme - -class T(gs_frontend.T): - def close(self): - gs_frontend.T.close(self) - if self.__output_lines == []: - return - - if theme.use_color: - gs_args = "-sDEVICE=png256 -dTextAlphaBits=4 -q -dNOPAUSE" #PDS - else: - gs_args = "-sDEVICE=pnggray -dTextAlphaBits=4 -q -dNOPAUSE" #PDS - - - temp_fname = None # the temporary file desc. - out_fd = None # the final destination. - - if self.__out_fname and isinstance(self.__out_fname, str): - gs_args += " -sOutputFile=%s" % self.__out_fname - else: - if not self.__out_fname: - out_fd = sys.stdout - else: - if not hasattr(self.__out_fname, "write"): - raise Exception, "Expecting either a filename or a file-like object, but got %s" % self.__out_fname - out_fd = self.__out_fname - import tempfile - temp_fname = tempfile.mktemp() - gs_args += " -sOutputFile=%s" % temp_fname - self.start_gs(gs_args) - self.close_gs() - - if temp_fname: - temp_fd = file(temp_fname, 'rb') - out_fd.write(temp_fd.read()) - temp_fd.close() - - - diff --git a/openerp/pychart/pscanvas.py b/openerp/pychart/pscanvas.py deleted file mode 100644 index 61b7dbfb8ad..00000000000 --- a/openerp/pychart/pscanvas.py +++ /dev/null @@ -1,258 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import sys -import re -import theme -import version -import basecanvas -from scaling import * - -comment_p = 0 - -class T(basecanvas.T): - def __init__(self, fname): - basecanvas.T.__init__(self) - self.__out_fname = fname - self.__reset_context() - self.__output_lines = [] - self.__nr_gsave = 0 - self.__font_ids = {} - self.__nr_fonts = 0 - - def __reset_context(self): - self.__font_name = None - self.__font_size = -1 - self.__line_style = None - self.__color = None - self.__mtx_pushed = 0 - self.__txtmtx_pushed = 0 - - def __intern_font(self, name): - if self.__font_ids.has_key(name): - return self.__font_ids[name] - id = "F%d" % self.__nr_fonts - self.__nr_fonts += 1 - self.__font_ids[name] = id - return id - - def newpath(self): - self.__write("N\n") - def stroke(self): - self.__write("ST\n") - def closepath(self): - self.__write("CP\n") - def moveto(self, x, y): - self.__write('%g %g M\n' % (x, y)) - - def set_fill_color(self, color): - if self.__color == color: - pass - else: - if color.r == color.g and color.r == color.b: - self.__write("%g SG\n" % color.r) - else: - self.__write("%g %g %g SC\n" % (color.r, color.g, color.b)) - self.__color = color - def set_stroke_color(self, color): - self.set_fill_color(color) - - def set_line_style(self, style): - self.set_stroke_color(style.color) - if (self.__line_style == style): - pass - else: - self.__write("%g %d %d " % (nscale(style.width), - style.cap_style, style.join_style)) - if style.dash != None: - self.__write("[%s] 0 SLD " % - " ".join(map(str, nscale_seq(style.dash)))) - else: - self.__write("SL ") - self.__line_style = style - - def gsave(self): - self.__nr_gsave += 1 - self.__write("GS\n") - def grestore(self): - self.__write("GR\n") - self.__nr_gsave -= 1 - self.__reset_context() - - def clip_sub(self): - self.__write("clip\n") - - def path_arc(self, x, y, radius, ratio, start_angle, end_angle): - self.push_transformation((x, y), (1, ratio), None) - self.__write("0 0 %g %g %g arc\n" % (radius, start_angle, end_angle)) - self.pop_transformation() - - def curveto(self, a,b,c,d,e,f): - self.__write("%g %g %g %g %g %g curveto\n" % (a,b,c,d,e,f)) - - def push_transformation(self, baseloc, scale, angle, in_text=0): - self.__mtx_pushed += 1 - self.__write("GB\n") - if baseloc != None: - self.__write("%g %g T\n" % (baseloc[0], baseloc[1])) - if angle != None and angle != 0: - self.__write("%g R\n" % (angle)) - if scale != None: - self.__write("%g %g scale\n" % (scale[0], scale[1])) - def pop_transformation(self, in_text=0): - if self.__mtx_pushed == 0: - raise ValueError, "mtx not pushed" - self.__mtx_pushed -= 1 - self.__write("GE\n") - def text_begin(self): - self.__txtmtx_pushed += 1 - self.__write("TB\n") - def text_end(self): - self.__txtmtx_pushed -= 1 - self.__write("TE\n") - def text_moveto(self, x, y, angle): - self.__write("%g %g T " % (x,y)) - if angle != None and angle != 0: - self.__write("%g R " % angle) - self.moveto(0, 0) - - def text_show(self, font_name, size, color, str): - self.set_fill_color(color) - if (self.__font_name == font_name and self.__font_size == size): - pass - else: - id = self.__intern_font(font_name) - self.__write("%g %s\n" % (size, id)) - self.__font_name = font_name - self.__font_size = size - self.__write("(%s) show\n" % (str)) - - def _path_polygon(self, points): - if (len(points) == 4 - and points[0][0] == points[1][0] - and points[2][0] == points[3][0] - and points[0][1] == points[3][1] - and points[1][1] == points[2][1]): - # a rectangle. - (xmin, ymin, xmax, ymax) = basecanvas._compute_bounding_box(points) - if basecanvas.invisible_p(xmax, ymax): - return - self.setbb(xmin, ymin) - self.setbb(xmax, ymax) - self.__write("%g %g %g %g RECT\n" % \ - (xscale(points[0][0]), yscale(points[0][1]), - xscale(points[2][0]), yscale(points[2][1]))) - else: - basecanvas.T._path_polygon(self, points) - - def lineto(self, x, y): - self.__write("%g %g L\n" % (x, y)) - def fill(self): - self.__write("fill\n") - def comment(self, str): - if comment_p: - self.verbatim("%" + str) - def verbatim(self, str): - self.__write(str) - - def close(self): - basecanvas.T.close(self) - if self.__output_lines == []: - return - - fp, need_close = self.open_output(self.__out_fname) - - if self.__nr_gsave != 0: - raise Exception, "gsave misnest (%d)" % (self.__nr_gsave) - self.write_preamble(fp) - - fp.writelines(self.__output_lines) - fp.writelines(["showpage end\n", - "%%Trailer\n", - "%%EOF\n"]) - if need_close: - fp.close() - - def __write(self, str): - self.__output_lines.append(str) - - def writelines(self, l): - self.__output_lines.extend(l) - - def write_preamble(self, fp): - bbox = [self.__xmin-1, self.__ymin-1, self.__xmax+1, self.__ymax+1] - fp.write("%!PS-Adobe-2.0 EPSF-1.2\n") - fp.write("%%Title: " + self.title + "\n") - fp.write("%%Creator: " + self.creator + "\n") - if self.author: - fp.write("%%Author: " + self.author + "\n") - fp.write("%%CreationDate: " + self.creation_date + "\n") - fp.write("%%DocumentFonts: " + " ".join(self.__font_ids.keys()) + "\n") - fp.write("%%Pages: 1\n") - - bbox = theme.adjust_bounding_box(bbox) - - fp.write("%%%%BoundingBox: %d %d %d %d\n" % \ - (round(xscale(bbox[0])), - round(yscale(bbox[1])), - round(xscale(bbox[2])), - round(yscale(bbox[3])))) - fp.write("%%EndComments\n") - if self.aux_comments != "": - for line in self.aux_comments.split("\n"): - fp.write("% " + line + "\n") - - fp.write(preamble_text) - for name, id in self.__font_ids.items(): - fp.write("/%s {/%s findfont SF} def\n" % (id, name)) - fp.write("%%EndProlog\n%%Page: 1 1\n") - - -preamble_text=""" -40 dict begin -/RECT {4 dict begin - /y2 exch def - /x2 exch def - /y1 exch def - /x1 exch def - newpath x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto closepath - end -} def - -/SF {exch scalefont setfont} def -/TB {matrix currentmatrix} def -/TE {setmatrix} def -/GB {matrix currentmatrix} def -/GE {setmatrix} def -/SG {1 1 1 setrgbcolor setgray} def -/SC {1 setgray setrgbcolor} def -/SL {[] 0 setdash setlinejoin setlinecap setlinewidth} def -/SLD {setdash setlinejoin setlinecap setlinewidth} def -/M {moveto} def -/L {lineto} def -/T {translate} def -/R {rotate} def -/N {newpath} def -/ST {stroke} def -/CP {closepath} def -/GR {grestore} def -/GS {gsave} def -""" - -# SL: set line style. -# width [dash] x linecap linejoin SL -> - -# SF: set font. -# name size SF -> - diff --git a/openerp/pychart/pychart_types.py b/openerp/pychart/pychart_types.py deleted file mode 100644 index e8d8a4174f4..00000000000 --- a/openerp/pychart/pychart_types.py +++ /dev/null @@ -1,71 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import pychart_util -import types -AnyType = 9998 - -def CoordType(val): - if type(val) != types.TupleType and type(val) != types.ListType: - return (" not a valid coordinate.") - if len(val) != 2: - return "Coordinate must be a pair of numbers.\n" - if val[0] != None: - error = NumType(val[0]) - if error: return error - if val[1] != None: - error = NumType(val[1]) - if error: return error - return None - -def IntervalType(val): - if type(val) in (types.IntType, types.LongType, - types.FloatType, types.FunctionType): - return None - return "Expecting a number or a function" - -def CoordOrNoneType(val): - if type(val) not in (types.TupleType, types.ListType): - return "Expecting a tuple or a list." - if len(val) != 2: - return "Coordinate must be a pair of numbers.\n" - for v in val: - if v != None and NumType(val[0]) != None: - return "Expecting a pair of numbers" - return None - -def NumType(val): - if type(val) in (types.IntType, types.LongType, types.FloatType): - return None - else: - return "Expecting a number, found \"" + str(val) + "\"" - -def UnitType(val): - if type(val) in (types.IntType, types.LongType, types.FloatType): - return None - else: - return "Expecting a unit, found \"" + str(val) + "\"" - -def ShadowType(val): - if type(val) not in (types.TupleType, types.ListType): - return "Expecting tuple or list." - if len(val) != 3: - return "Expecting (xoff, yoff, fill)." - return None - -def FormatType(val): - if type(val) in (types.StringType, types.FunctionType): - return None - return "Format must be a string or a function" - diff --git a/openerp/pychart/pychart_util.py b/openerp/pychart/pychart_util.py deleted file mode 100644 index 13b487b5543..00000000000 --- a/openerp/pychart/pychart_util.py +++ /dev/null @@ -1,143 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import sys -import math -import types -import traceback -from types import * - -def inch_to_point(inch): - return inch * 72.0 -def point_to_inch(pt): - return float(pt) / 72.0 - -def rotate(x, y, degree): - """Rotate a coordinate around point (0,0). - - x and y specify the coordinate. - - degree is a number from 0 to 360. - Returns a new coordinate. - """ - radian = float(degree) * 2 * math.pi / 360.0 - newx = math.cos(radian) * x - math.sin(radian) * y - newy = math.sin(radian) * x + math.cos(radian) * y - return (newx, newy) - -debug_level = 1 - -def warn(*strs): - for s in strs: - sys.stderr.write(str(s)) - sys.stderr.write(" ") - sys.stderr.write("\n") - -def info(*strs): - if debug_level < 100: - return - for s in strs: - sys.stderr.write(str(s)) - sys.stderr.write("\n") - -def get_sample_val(l, col): - if len(l) <= col: - return None - return l[col] - -def get_data_list(data, col): - # data = [ elem[col] for elem in data if elem[col] != None ] - r = [] - for item in data: - val = get_sample_val(item, col) - if val != None: - r.append(val) - return r - -def get_data_range(data, col): - data = get_data_list(data, col) - for item in data: - if type(item) not in (types.IntType, types.LongType, types.FloatType): - raise TypeError, "Non-number passed to data: %s" % (data) - return (min(data), max(data)) - -def round_down(val, bound): - return int(val/float(bound)) * bound - -def round_up(val, bound): - return (int((val-1)/float(bound))+1) * bound - - -# -# Attribute type checking stuff -# - -def new_list(): - return [] - -def union_dict(dict1, dict2): - dict = dict1.copy() - dict.update(dict2) - return dict - -def TextVAlignType(val): - if val in ('T', 'B', 'M', None): - return None - return "Text vertical alignment must be one of T(op), B(ottom), or M(iddle).\n" - -def TextAlignType(val): - if val in ('C', 'R', 'L', None): - return None - return "Text horizontal alignment must be one of C(enter), R(ight), or L(eft)." - -def apply_format(format, val, defaultidx): - if format == None: - return None - elif type(format) == StringType: - return format % val[defaultidx] - else: - return apply(format, val) - - -data_desc = "Specifies the data points. <<chart_data>>" -label_desc = "The label to be displayed in the legend. <<legend>>, <<font>>" -xcol_desc = """The column, within attribute "data", from which the X values of sample points are extracted. <<chart_data>>""" -ycol_desc = """The column, within attribute "data", from which the Y values of sample points are extracted. <<chart_data>>""" -tick_mark_desc = "Tick marks to be displayed at each sample point. <<tick_mark>>" -line_desc="The style of the line. " - -def interval_desc(w): - return "When the value is a number, it specifies the interval at which %s are drawn. Otherwise, the value must be a function that takes no argument and returns the list of numbers. The return value specifies the X or Y points at which %s are drawn." % (w,w) - -shadow_desc = """The value is either None or a tuple. When non-None, -a drop-shadow is drawn beneath the object. X-off, and y-off specifies the -offset of the shadow relative to the object, and fill specifies the -style of the shadow (@pxref{module-fill-style}).""" - -string_desc = """The appearance of the string produced here can be -controlled using escape sequences. <<font>>""" - -# -# - -class symbol_lookup_table: - def __init__(self, dict, objs): - self.names = {} - for name, val in dict.items(): - for obj in objs.list(): - if val == obj: - self.names[val] = name - break - def lookup(self, obj): - if self.names.has_key(obj): - return self.names[obj] - return None diff --git a/openerp/pychart/range_plot.py b/openerp/pychart/range_plot.py deleted file mode 100644 index dc4b2edd8b6..00000000000 --- a/openerp/pychart/range_plot.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import line_style -import pychart_util -import chart_object -import fill_style -import legend -import range_plot_doc -from pychart_types import * -from types import * -from scaling import * - - -class T(chart_object.T): - __doc__ = range_plot_doc.doc - keys = { - "data" : (AnyType, None, pychart_util.data_desc), - "label": (StringType, "???", pychart_util.label_desc), - "xcol" : (IntType, 0, pychart_util.xcol_desc), - "min_col": (IntType, 1, - "The lower bound of the sweep is extracted from " - + "this column of data."), - "max_col": (IntType, 2, - "The upper bound of the sweep is extracted from " - + "this column of data."), - "line_style": (line_style.T, line_style.default, - "The style of the boundary line."), - "fill_style": (fill_style.T, fill_style.default, - ""), - } - -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - - def check_integrity(self): - self.type_check() - def get_data_range(self, which): - if which == 'X': - return pychart_util.get_data_range(self.data, self.xcol) - else: - ymax = (pychart_util.get_data_range(self.data, self.max_col))[1] - ymin = (pychart_util.get_data_range(self.data, self.min_col))[0] - return (ymin, ymax) - def get_legend_entry(self): - if self.label: - return legend.Entry(line_style=self.line_style, - fill_style=self.fill_style, - label=self.label) - return None - - def draw(self, ar, can): - - prevPair = None - - xmin=999999 - xmax=-999999 - ymin=999999 - ymax=-999999 - - # Draw the boundary in a single stroke. - can.gsave() - can.newpath() - for pair in self.data: - x = pair[self.xcol] - y = pychart_util.get_sample_val(pair, self.max_col) - if y == None: - continue - - xmin = min(xmin, ar.x_pos(x)) - xmax = max(xmax, ar.x_pos(x)) - ymin = min(ymin, ar.y_pos(y)) - ymax = max(ymax, ar.y_pos(y)) - if prevPair != None: - can.lineto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y))) - else: - can.moveto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y))) - prevPair = pair - - for i in range(len(self.data)-1, -1, -1): - pair = self.data[i] - x = pair[self.xcol] - y = pychart_util.get_sample_val(pair, self.min_col) - if None in (x, y): - continue - - xmin = min(xmin, ar.x_pos(x)) - xmax = max(xmax, ar.x_pos(x)) - ymin = min(ymin, ar.y_pos(y)) - ymax = max(ymax, ar.y_pos(y)) - can.lineto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y))) - can.closepath() - - # create a clip region, and fill it. - can.clip_sub() - can.fill_with_pattern(self.fill_style, xmin, ymin, xmax, ymax) - can.grestore() - - if self.line_style: - # draw the boundary. - prevPair = None - can.newpath() - can.set_line_style(self.line_style) - for pair in self.data: - x = pair[self.xcol] - y = pychart_util.get_sample_val(pair, self.min_col) - if None in (x, y): - continue - - if prevPair != None: - can.lineto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y))) - else: - can.moveto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y))) - prevPair = pair - can.stroke() - - prevPair = None - can.newpath() - can.set_line_style(self.line_style) - for pair in self.data: - x = pair[self.xcol] - y = pychart_util.get_sample_val(pair, self.max_col) - if y == None: - continue - - if prevPair != None: - can.lineto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y))) - else: - can.moveto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y))) - prevPair = pair - can.stroke() - - diff --git a/openerp/pychart/range_plot_doc.py b/openerp/pychart/range_plot_doc.py deleted file mode 100644 index 28700d5378e..00000000000 --- a/openerp/pychart/range_plot_doc.py +++ /dev/null @@ -1,12 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -xcol(type:int) default="The column, within attribute "data", from which the X values of sample points are extracted. <<chart_data>>". -max_col(type:int) default="The upper bound of the sweep is extracted from this column of data.". -min_col(type:int) default="The lower bound of the sweep is extracted from this column of data.". -label(type:str) default="The label to be displayed in the legend. <<legend>>, <<font>>". -line_style(type:line_style.T) default="The style of the boundary line.". -fill_style(type:fill_style.T) default="". -data(type:any) default="Specifies the data points. <<chart_data>>". -""" - diff --git a/openerp/pychart/rose_plot.py b/openerp/pychart/rose_plot.py deleted file mode 100644 index 1f54a4e7cb6..00000000000 --- a/openerp/pychart/rose_plot.py +++ /dev/null @@ -1,144 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import canvas -import fill_style -import line_style -import pychart_util -import chart_object -import legend -import font -import color -from pychart_types import * - -class T(chart_object.T): - """Plots sector diagram which can be superimposed on one another. - Sector diagrams are also known as wind roses""" - keys = { - "start_angle" : (NumType, 90, ""), # top of chart (north) - "center" : (CoordType, None, ""), - "base_radius" : (NumType, None, ""), - "line_style" : (line_style.T, line_style.T(color=color.black, width=0.3), ""), - "fill_styles" : (list, fill_style.standards.list()[:], - """The fill style of each item. The length of the - list should be equal to the length of the data. - """), - "sector_centred":(int, 1, - """Bool indicating whether the sectors should be centred on each sector_width(e.g. on 0)"""), - "dir_offset": (UnitType, None, - """The distance between the directions and the outermost circle. Defaults fine for most cases"""), - "data" : (AnyType, None, pychart_util.data_desc), - "label_col" : (int, 0, - """The column, within "data", from which the labels of items are retrieved."""), - "data_col": (int, 1, - """ The column, within "data", from which the data values are retrieved."""), - "dir_line_style": (line_style.T, None, ""), - "dir_fill_style": (fill_style.T, fill_style.default, ""), - "shadow": (ShadowType, None, pychart_util.shadow_desc), - "sector_width": (int, None, ""), # automatically generated - } - - def __init__(self, colour=True, **args): - chart_object.T.init(self, args) - if colour: - # the theme.color flag does not seem to affect the fill_style.standards, - #besides, I want the first two colors to resemble those of gnuplot's postscript terminal - self.fill_styles = [fill_style.Plain(bgcolor=color.red), - fill_style.Plain(bgcolor=color.green), - fill_style.Plain(bgcolor=color.blue), - fill_style.Plain(bgcolor=color.magenta)] - - def check_integrity(self): - nSectors = len(self.data[0][self.data_col]) - if (360%nSectors != 0): - raise Exception('Length of dataset ' + str(nSectors) + ' not a divisor of 360 degrees!') - for dataset in self.data: - length = len(dataset[self.data_col]) - if length != nSectors: - raise Exception('Lengths of datasets given is different!') - for val in dataset[self.data_col]: - if (val < 0) | (val > 1): - raise Exception('Data value ' + str(val) + ' not between 0 and 1!') - self.sector_width = 360/nSectors - self.type_check() - - def get_data_range(self, which): - return (0, 1) - - def get_legend_entry(self): - legends = [] - i = 0 - for dataset in self.data: - fill = self.fill_styles[i] - i = (i + 1) % len(self.fill_styles) - legends.append(legend.Entry(line_style=self.line_style, - fill_style=fill, - label=dataset[self.label_col])) - return legends - - def draw(self, ar, can): - center = self.center - if not center: - center = (ar.loc[0] + ar.size[0]/2.0, - ar.loc[1] + ar.size[1]/2.0) - base_radius = self.base_radius # the maximum radius of a wedge - if not base_radius: - base_radius = min(ar.size[0]/2.0, ar.size[1]/2.0) #* 0.8 - - sector_decrement = 1./(len(self.data)*2) * self.sector_width # each following sector diagram will have its sector width decremented by half this amount (in degrees) - i = 0 - for dataset in self.data: - cur_angle = self.start_angle - if self.sector_centred: - cur_angle -= self.sector_width/2. - fill = self.fill_styles[i] - x_center = center[0] - y_center = center[1] - - if not i: # draw directions around sector diagram once off - dir_offset = base_radius + (self.dir_offset or base_radius * 0.04) - directions = ['N', 'E', 'S', 'W'] - angle = self.start_angle - - can.ellipsis(line_style.T(color=color.black, width=0.3, dash=line_style.dash1), None, - x_center, y_center, base_radius, 1, - 0, 360) # - - for d in directions: - x_label, y_label = pychart_util.rotate(dir_offset, 0, angle) # coords for bottom left corner of box - tw = font.text_width(d) - half = 1/3. # normal arithmetic does not seem to apply to these text_box objects... - if (angle == 0): # east - y_label -= font.text_height(d)[0]*half # move down half - elif (angle == -180): # west - y_label -= font.text_height(d)[0]*half # move down half - x_label -= font.text_width(d) # move left full - elif (angle == 90): # north - x_label -= font.text_height(d)[0]*half # move left half - elif (angle == -90): # south - y_label -= font.text_height(d)[0]*.8 # move down (couldn't figure out how to set this dynamically so I fudged...) - x_label -= font.text_height(d)[0]*half # move left half - canvas.show(x_label + x_center, y_label + y_center, d) - angle -= 360/len(directions) - - for val in dataset[self.data_col]: # now draw the sectors - radius = base_radius*val # scale the radius - start = cur_angle-self.sector_width+i*sector_decrement - stop = cur_angle-i*sector_decrement # these may seem confusing, but remember that we need to go counterclockwise - - can.ellipsis(self.line_style, fill, - x_center, y_center, radius, 1, start, stop, self.shadow) - cur_angle = (cur_angle - self.sector_width) % 360 # we want to go in anticlockwise direction (North, West, South, etc. as in meteorology) - i = (i + 1) % len(self.fill_styles) - diff --git a/openerp/pychart/scaling.py b/openerp/pychart/scaling.py deleted file mode 100644 index 02dd0360d30..00000000000 --- a/openerp/pychart/scaling.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import theme - -x_base = 300 -y_base = 300 - -def xscale(x): - return x * theme.scale_factor + x_base -def yscale(y): - return y * theme.scale_factor + y_base - -def nscale(x): - return x * theme.scale_factor -def nscale_seq(x): - return map(nscale, x) - diff --git a/openerp/pychart/svgcanvas.py b/openerp/pychart/svgcanvas.py deleted file mode 100644 index 76fc2ce412c..00000000000 --- a/openerp/pychart/svgcanvas.py +++ /dev/null @@ -1,429 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import sys,string,re,math -from xml.dom.minidom import Document,Comment -import theme -import basecanvas -import version -from scaling import * - -# Note we flip all y-coords and negate all angles because SVG's coord -# system is inverted wrt postscript/PDF - note it's not enough to -# scale(1,-1) since that turns text into mirror writing with wrong origin - -_comment_p = 0 # whether comment() writes output - -# Convert a PyChart color object to an SVG rgb() value -def _svgcolor(color): # see color.py - return 'rgb(%d,%d,%d)' % tuple(map(lambda x:int(255*x), - [color.r,color.g,color.b])) - -# Take an SVG 'style' attribute string like 'stroke:none;fill:black' -# and parse it into a dictionary like {'stroke' : 'none', 'fill' : 'black'} -def _parseStyleStr(s): - styledict = {} - if s : - # parses L -> R so later keys overwrite earlier ones - for keyval in s.split(';'): - l = keyval.strip().split(':') - if l and len(l) == 2: styledict[l[0].strip()] = l[1].strip() - return styledict - -# Make an SVG style string from the dictionary described above -def _makeStyleStr(styledict): - s = '' - for key in styledict.keys(): - s += "%s:%s;"%(key,styledict[key]) - return s - -def _protectCurrentChildren(elt): - # If elt is a group, check to see whether there are any non-comment - # children, and if so, create a new group to hold attributes - # to avoid affecting previous children. Return either the current - # elt or the newly generated group. - if (elt.nodeName == 'g') : - for kid in elt.childNodes : - if kid.nodeType != Comment.nodeType: - g = elt.ownerDocument.createElement('g') - g.setAttribute('auto','') - if _comment_p: - g.appendChild(g.ownerDocument.createComment - ('auto-generated group')) - elt.appendChild(g) - elt = g - break - return elt - -class T(basecanvas.T): - def __init__(self, fname): - basecanvas.T.__init__(self) - self.__out_fname = fname - self.__xmin, self.__xmax, self.__ymin, self.__ymax = 0,0,0,0 - self.__doc = Document() - self.__doc.appendChild(self.__doc.createComment - ('Created by PyChart ' + version.version + ' ' + version.copyright)) - self.__svg = self.__doc.createElement('svg') # the svg doc - self.__doc.appendChild(self.__svg) - self.__defs = self.__doc.createElement('defs') # for clip paths - self.__svg.appendChild(self.__defs) - self.__currElt = self.__svg - self.gsave() # create top-level group for dflt styles - self._updateStyle(font_family = theme.default_font_family, - font_size = theme.default_font_size, - font_style = 'normal', - font_weight = 'normal', - font_stretch = 'normal', - fill = 'none', - stroke = 'rgb(0,0,0)', #SVG dflt none, PS dflt blk - stroke_width = theme.default_line_width, - stroke_linejoin = 'miter', - stroke_linecap = 'butt', - stroke_dasharray = 'none') - - def _updateStyle(self, **addstyledict): - elt = _protectCurrentChildren(self.__currElt) - - # fetch the current styles for this node - mystyledict = _parseStyleStr(elt.getAttribute('style')) - - # concat all parent style strings to get dflt styles for this node - parent,s = elt.parentNode,'' - while parent.nodeType != Document.nodeType : - # prepend parent str so later keys will override earlier ones - s = parent.getAttribute('style') + s - parent = parent.parentNode - dfltstyledict = _parseStyleStr(s) - - # Do some pre-processing on the caller-supplied add'l styles - # Convert '_' to '-' so caller can specify style tags as python - # variable names, eg. stroke_width => stroke-width. - # Also convert all RHS values to strs - for key in addstyledict.keys(): - k = re.sub('_','-',key) - addstyledict[k] = str(addstyledict[key]) # all vals => strs - if (k != key) : del addstyledict[key] - - for k in addstyledict.keys() : - if (mystyledict.has_key(k) or # need to overwrite it - (not dfltstyledict.has_key(k)) or # need to set it - dfltstyledict[k] != addstyledict[k]) : # need to override it - mystyledict[k] = addstyledict[k] - - s = _makeStyleStr(mystyledict) - if s : elt.setAttribute('style',s) - - self.__currElt = elt - - #################################################################### - # methods below define the pychart backend device API - - # First are a set of methods to start, construct and finalize a path - - def newpath(self): # Start a new path - if (self.__currElt.nodeName != 'g') : - raise OverflowError, "No containing group for newpath" - # Just insert a new 'path' element into the document - p = self.__doc.createElement('path') - self.__currElt.appendChild(p) - self.__currElt = p - - # This set of methods add data to an existing path element, - # simply add to the 'd' (data) attribute of the path elt - - def moveto(self, x, y): # - if (self.__currElt.nodeName != 'path') : - raise OverflowError, "No path for moveto" - d = ' '.join([self.__currElt.getAttribute('d'),'M',`x`,`-y`]).strip() - self.__currElt.setAttribute('d', d) - def lineto(self, x, y): - if (self.__currElt.nodeName != 'path') : - raise OverflowError, "No path for lineto" - d = ' '.join([self.__currElt.getAttribute('d'),'L',`x`,`-y`]).strip() - self.__currElt.setAttribute('d', d) - def path_arc(self, x, y, radius, ratio, start_angle, end_angle): - # mimic PS 'arc' given radius, yr/xr (=eccentricity), start and - # end angles. PS arc draws from CP (if exists) to arc start, - # then draws arc in counterclockwise dir from start to end - # SVG provides an arc command that draws a segment of an - # ellipse (but not a full circle) given these args: - # A xr yr rotate majorArcFlag counterclockwiseFlag xe ye - # We don't use rotate(=0) and flipped axes => all arcs are clockwise - - if (self.__currElt.nodeName != 'path') : - raise OverflowError, "No path for path_arc" - - self.comment('x=%g, y=%g, r=%g, :=%g, %g-%g' - % (x,y,radius,ratio,start_angle,end_angle)) - - xs = x+radius*math.cos(2*math.pi/360.*start_angle) - ys = y+ratio*radius*math.sin(2*math.pi/360.*start_angle) - xe = x+radius*math.cos(2*math.pi/360.*end_angle) - ye = y+ratio*radius*math.sin(2*math.pi/360.*end_angle) - if (end_angle < start_angle) : # make end bigger than start - while end_angle <= start_angle: # '<=' so 360->0 becomes 360->720 - end_angle += 360 - full_circ = (end_angle - start_angle >= 360) # draw a full circle? - - d = self.__currElt.getAttribute('d') - d += ' %s %g %g' % (d and 'L' or 'M',xs,-ys) # draw from CP, if exists - if (radius > 0) : # skip, eg. 0-radius 'rounded' corners which blowup - if (full_circ) : - # If we're drawing a full circle, move to the end coord - # and draw half a circle to the reflected xe,ye - d += ' M %g %g A %g %g 0 1 0 %g %g'%(xe,-ye, - radius,radius*ratio, - 2*x-xe,-(2*y-ye)) - # Draw arc from the CP (either reflected xe,ye for full circle else - # xs,ys) to the end coord - note with full_circ the - # 'bigArcFlag' value is moot, with exactly 180deg left to draw - d += ' A %g %g 0 %d 0 %g %g' % (radius,radius*ratio, - end_angle-start_angle>180, - xe,-ye) - self.__currElt.setAttribute('d',d.strip()) - def curveto(self, x1,y1,x2,y2,x3,y3): - # Equivalent of PostScript's x1 y1 x2 y2 x3 y3 curveto which - # draws a cubic bezier curve from curr pt to x3,y3 with ctrl points - # x1,y1, and x2,y2 - # In SVG this is just d='[M x0 y0] C x1 y1 x2 y2 x3 y3' - #! I can't find an example of this being used to test it - if (self.__currElt.nodeNode != 'path') : - raise OverflowError, "No path for curveto" - d = ' '.join([self.__currElt.getAttribute('d'),'C', - `x1`,`-y1`,`x2`,`-y2`,`x3`,`-y3`,]).strip() - self.__currElt.setAttribute('d', d) - def closepath(self): # close back to start of path - if (self.__currElt.nodeName != 'path') : - raise OverflowError, "No path for closepath" - d = ' '.join([self.__currElt.getAttribute('d'),'Z']).strip() - self.__currElt.setAttribute('d', d) - - # Next we have three methods for finalizing a path element, - # either fill it, clip to it, or draw it (stroke) - # canvas.polygon() can generate fill/clip cmds with - # no corresponding path so just ignore them - def stroke(self): - if (self.__currElt.nodeName != 'path') : - self.comment('No path - ignoring stroke') - return - self._updateStyle(fill='none') - self.__currElt = self.__currElt.parentNode - def fill(self): - if (self.__currElt.nodeName != 'path') : - self.comment('No path - ignoring fill') - return - self._updateStyle(stroke='none') - self.__currElt = self.__currElt.parentNode - def clip_sub(self): - if (self.__currElt.nodeName != 'path') : - self.comment('No path - ignoring clip') - return - - # remove the current path from the tree ... - p = self.__currElt - self.__currElt=p.parentNode - self.__currElt.removeChild(p) - - # ... add it to a clipPath elt in the defs section - clip = self.__doc.createElement('clipPath') - clipid = 'clip'+`len(self.__defs.childNodes)` - clip.setAttribute('id',clipid) - clip.appendChild(p) - self.__defs.appendChild(clip) - - # ... update the local style to point to it - self._updateStyle(clip_path = 'url(#%s)'%clipid) - - # The text_xxx routines specify the start/end and contents of text - def text_begin(self): - if (self.__currElt.nodeName != 'g') : - raise ValueError, "No group for text block" - t = self.__doc.createElement('text') - self.__currElt.appendChild(t) - self.__currElt = t - def text_moveto(self, x, y, angle): - if (self.__currElt.nodeName != 'text') : - raise ValueError, "No text for moveto" - self.__currElt.setAttribute('x',`x`) - self.__currElt.setAttribute('y',`-y`) - if (angle) : - self.__currElt.setAttribute('transform', - 'rotate(%g,%g,%g)' % (-angle,x,-y)) - def text_show(self, font_name, size, color, str): - if (self.__currElt.nodeName != 'text') : - raise ValueError, "No text for show" - - # PyChart constructs a postscript font name, for example: - # - # Helvetica Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique - # Helvetica-Narrow Times-Roman Times-Italic - # Symbol Palatino-Roman Bookman-Demi Courier AvantGarde-Book - # - # We need to deconstruct this to get the font-family (the - # piece before the '-'), and other characteristics. - # Note that 'Courier' seems to correspond to SVGs 'CourierNew' - # and that the SVG Symbol font is Unicode where the ascii text - # 'Symbol' doesn't create greek characters like 'Sigma ...' - - # should really pass a unicode string, or provide translation - # - # SVG defines: - # font-style = normal (aka roman) | italic | oblique - # font-weight = normal | bold (aka demi?) - # font-stretch = normal | wider | narrower | ultra-condensed | - # extra-condensed | condensed | semi-condensed | - # semi-expanded | expanded | extra-expanded | ultra-expanded - # ('narrow' seems to correspond to 'condensed') - - m = re.match(r'([^-]*)(-.*)?',font_name) - font_name,modifiers = m.groups() - if font_name == 'Courier' : font_name = 'CourierNew' - font_style = font_weight = font_stretch = 'normal' - if modifiers : - if re.search('Italic',modifiers) : font_style = 'italic' - elif re.search('Oblique',modifiers) : font_style = 'oblique' - if re.search('Bold|Demi',modifiers) : font_weight = 'bold' - if re.search('Narrow',modifiers) : font_stretch = 'condensed' - #! translate ascii symbol font chars -> unicode (see www.unicode.org) - #! http://www.unicode.org/Public/MAPPINGS/VENDORS/ADOBE/symbol.txt - #! but xml Text element writes unicode chars as '?' to XML file... - str = re.sub(r'\\([()])',r'\1',str) # unescape brackets - self._updateStyle(fill=_svgcolor(color), - stroke='none', - font_family=font_name, - font_size=size, - font_style=font_style, - font_weight=font_weight, - font_stretch=font_stretch) - self.__currElt.appendChild(self.__doc.createTextNode(str)) - def text_end(self): - if (self.__currElt.nodeName != 'text') : - raise ValueError, "No text for close" - self.__currElt = self.__currElt.parentNode - - - # Three methods that change the local style of elements - # If applied to a group, they persist until the next grestore, - # If applied within a path element, they only affect that path - - # although this may not in general correspond to (say) PostScript - # behavior, it appears to correspond to reflect mode of use of this API - def set_fill_color(self, color): - self._updateStyle(fill=_svgcolor(color)) - def set_stroke_color(self, color): - self._updateStyle(stroke=_svgcolor(color)) - def set_line_style(self, style): # see line_style.py - linecap = {0:'butt', 1:'round', 2:'square'} - linejoin = {0:'miter', 1:'round', 2:'bevel'} - if style.dash: dash = ','.join(map(str,style.dash)) - else : dash = 'none' - self._updateStyle(stroke_width = style.width, - stroke = _svgcolor(style.color), - stroke_linecap = linecap[style.cap_style], - stroke_linejoin = linejoin[style.join_style], - stroke_dasharray = dash) - - # gsave & grestore respectively push & pop a new context to hold - # new style and transform parameters. push/pop transformation are - # similar but explicitly specify a coordinate transform at the - # same time - def gsave(self): - if (self.__currElt.nodeName not in ['g','svg']) : - raise ValueError, "No group for gsave" - g = self.__doc.createElement('g') - self.__currElt.appendChild(g) - self.__currElt = g - def grestore(self): - if (self.__currElt.nodeName != 'g'): - raise ValueError, "No group for grestore" - # first pop off any auto-generated groups (see protectCurrentChildren) - while (self.__currElt.hasAttribute('auto')) : - self.__currElt.removeAttribute('auto') - self.__currElt = self.__currElt.parentNode - # then pop off the original caller-generated group - self.__currElt = self.__currElt.parentNode - - def push_transformation(self, baseloc, scale, angle, in_text=0): - #? in_text arg appears to always be ignored - - # In some cases this gets called after newpath, with - # corresonding pop_transformation called after the path is - # finalized so we check specifically for that, and generate - # an enclosing group to hold the incomplete path element - # We could add the transform directly to the path element - # (like we do with line-style etc) but that makes it harder - # to handle the closing 'pop' and might lead to inconsitency - # with PostScript if the closing pop doesn't come right after - # the path element - - elt = self.__currElt - if elt.nodeName == 'g': - elt = None - elif (elt.nodeName == 'path' and not elt.hasAttribute('d')) : - g = elt.parentNode - g.removeChild(elt) - self.__currElt = g - else: - raise ValueError, "Illegal placement of push_transformation" - - t = '' - if baseloc : - t += 'translate(%g,%g) '%(baseloc[0],-baseloc[1]) - if angle : - t += 'rotate(%g) '%-angle - if scale : - t += 'scale(%g,%g) '%tuple(scale) - - self.gsave() - self.__currElt.setAttribute('transform',t.strip()) - if elt: # elt has incomplete 'path' or None - self.__currElt.appendChild(elt) - self.__currElt = elt - - def pop_transformation(self, in_text=0): #? in_text unused? - self.grestore() - - # If verbose, add comments to the output stream (helps debugging) - def comment(self, str): - if _comment_p : - self.__currElt.appendChild(self.__doc.createComment(str)) - - # The verbatim method is currently not supported - presumably with - # the SVG backend the user would require access to the DOM since - # we're not directly outputting plain text here - def verbatim(self, str): - self.__currElt.appendChild(self.__doc.createComment('verbatim not implemented: ' + str)) - - # The close() method finalizes the SVG document and flattens the - # DOM document to XML text to the specified file (or stdout) - def close(self): - basecanvas.T.close(self) - self.grestore() # matching the gsave in __init__ - if (self.__currElt.nodeName != 'svg') : - raise ValueError, "Incomplete document at close!" - - # Don't bother to output an empty document - this can happen - # when we get close()d immediately by theme reinit - if (len(self.__svg.childNodes[-1].childNodes) == 0) : - return - - fp, need_close = self.open_output(self.__out_fname) - bbox = theme.adjust_bounding_box([self.__xmin, self.__ymin, - self.__xmax, self.__ymax]) - self.__svg.setAttribute('viewBox','%g %g %g %g' - % (xscale(bbox[0]), - -yscale(bbox[3]), - xscale(bbox[2])-xscale(bbox[0]), - yscale(bbox[3])-yscale(bbox[1]))) - self.__doc.writexml(fp,'',' ','\n') - if need_close: - fp.close() diff --git a/openerp/pychart/text_box.py b/openerp/pychart/text_box.py deleted file mode 100644 index 481deda1317..00000000000 --- a/openerp/pychart/text_box.py +++ /dev/null @@ -1,153 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import canvas -import line_style -import pychart_util -import fill_style -import font -import chart_object -import color -import arrow -import text_box_doc -from pychart_types import * -from types import * - -class T(chart_object.T): - __doc__ = text_box_doc.doc - keys = {"text": (StringType, "???", "Text body. <<font>>"), - "loc": (TupleType, (0,0), - "The location of the text box."), - "line_style": (line_style.T, line_style.default, - """The line style of the surrounding frame."""), - "fill_style": (fill_style.T, fill_style.white, - "Specifies the fill style of the text box."), - "top_fudge": (UnitType, 0, - "The amount of space (in points) above the first line"), - "bottom_fudge": (UnitType, 5, - "The amount of space below the last line"), - "left_fudge": (UnitType, 5, - "The amount of space left of the box"), - "right_fudge": (UnitType, 5, - "The amount of space right of the box"), - "_arrows": (ListType, pychart_util.new_list, "The list of arrows. Not to be touched by the user directly"), - "radius": (UnitType, 0, - """Radius of the four corners of the rectangle. - If the value is zero, a sharp-cornered - rectangle is drawn."""), - "shadow": (ShadowType, None, - pychart_util.shadow_desc) - } -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - def get_dimension(self): - x = self.loc[0] - self.left_fudge - y = self.loc[1] - self.bottom_fudge - width = font.text_width(self.text) + self.right_fudge + self.left_fudge - height = (font.text_height(self.text))[0] + self.top_fudge + self.bottom_fudge - return (x, y, width, height) - - def choose_end_point(self, tipx, tipy): - (x, y, width, height) = self.get_dimension() - - minDist = -1 - minPoint = None - vertices = [(x, y), - (x+width, y), - (x+width, y+height), - (x, y+height)] - - if tipx >= x and tipx < x+width: - vertices.append((tipx, y)) - vertices.append((tipx, y+height)) - if tipy >= y and tipy < y+height: - vertices.append((x, tipy)) - vertices.append((x+width, tipy)) - - for startPoint in vertices: - dist = ((startPoint[0] - tipx) **2 + (startPoint[1] - tipy) **2) - if not minPoint or dist < minDist: - minPoint = startPoint - minDist = dist - - return minPoint - - def add_arrow(self, tipLoc, tail=None, arrow = arrow.default): - """This method adds a straight arrow that points to - @var{TIPLOC}, which is a tuple of integers. @var{TAIL} - specifies the starting point of the arrow. It is either None - or a string consisting of the following letters: 'l', 'c', - 'r', 't', 'm,', and 'b'. Letters 'l', 'c', or 'r' means to - start the arrow from the left, center, or right of the text - box, respectively. Letters 't', 'm', or 'b' means to start the - arrow from the top, middle or bottom of the text box. For - example, when @samp{tail = 'tc'} then arrow is drawn from - top-center point of the text box. ARROW specifies the style of - the arrow. <<arrow>>. - """ - self._arrows.append((tipLoc, tail, arrow)) - - def draw(self, can = None): - if can == None: - can = canvas.default_canvas() - x = self.loc[0] - y = self.loc[1] - text_width = font.text_width(self.text) - text_height = font.text_height(self.text)[0] - (halign, valign, angle) = font.get_align(self.text) - - if self.line_style or self.fill_style: - width = text_width+self.left_fudge+self.right_fudge - height = text_height+self.bottom_fudge+self.top_fudge - can.round_rectangle(self.line_style, self.fill_style, - x-self.left_fudge, y-self.bottom_fudge, - x-self.left_fudge+width, y-self.bottom_fudge+height, - self.radius, self.shadow) - - if halign == 'L': - can.show(x, y, self.text) - elif halign == 'C': - can.show(x+text_width/2.0, y, self.text) - elif halign == 'R': - can.show(x+text_width, y, self.text) - else: - raise Exception, "Unsupported alignment (" + halign + ")" - - # draw arrows - for t in self._arrows: - (tipLoc, tail, arrow) = t - if tail: - (x, y, width, height) = self.get_dimension() - origin = [x, y] - for ch in tail: - if ch == 'l': - origin[0] = x - elif ch == 'c': - origin[0] = x+width/2.0 - elif ch == 'r': - origin[0] = x+width - elif ch == 'b': - origin[1] = y - elif ch == 'm': - origin[1] = y+height/2.0 - elif ch == 't': - origin[1] = y+height - else: - raise ValueError, tail + ": unknown tail location spec." - else: - origin = self.choose_end_point(tipLoc[0], tipLoc[1]) - arrow.draw((origin, tipLoc), can) - - diff --git a/openerp/pychart/text_box_doc.py b/openerp/pychart/text_box_doc.py deleted file mode 100644 index 72145345bd8..00000000000 --- a/openerp/pychart/text_box_doc.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -loc(type:tuple) default="The location of the text box.". -shadow(type:<function ShadowType at 0xb7d4db8c>) default="The value is either None or a tuple. When non-None, -a drop-shadow is drawn beneath the object. X-off, and y-off specifies the -offset of the shadow relative to the object, and fill specifies the -style of the shadow (@pxref{module-fill-style}).". -left_fudge(type:length in points (\\xref{unit})) default="The amount of space left of the box". -bottom_fudge(type:length in points (\\xref{unit})) default="The amount of space below the last line". -fill_style(type:fill_style.T) default="Specifies the fill style of the text box.". -right_fudge(type:length in points (\\xref{unit})) default="The amount of space right of the box". -top_fudge(type:length in points (\\xref{unit})) default="The amount of space (in points) above the first line". -text(type:str) default="Text body. <<font>>". -radius(type:length in points (\\xref{unit})) default="Radius of the four corners of the rectangle. - If the value is zero, a sharp-cornered - rectangle is drawn.". -line_style(type:line_style.T) default="The line style of the surrounding frame.". -_arrows(type:list) default="The list of arrows. Not to be touched by the user directly". -""" - diff --git a/openerp/pychart/theme.py b/openerp/pychart/theme.py deleted file mode 100644 index a725e14d009..00000000000 --- a/openerp/pychart/theme.py +++ /dev/null @@ -1,235 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import sys -import os -import re -import getopt -import pychart_util - -__doc__ = """This module is defines variables for changing the looks -of charts. All the variables can be changed either via environment -variable PYCHART_OPTIONS or via the command-line options. - -The value of PYCHART_OPTIONS should be a sequence of var=val separated -by space. Below is an example, which tells Pychart to write to file -foo.pdf and use Times-Roman as the default font. - -PYCHART_OPTIONS="output=foo.pdf font-family=Times" - -The summary of attributes that can be set via PYCHART_OPTIONS follows: - -output=FILENAME (default: stdout) - - Set the output file name. - -format=[ps|pdf|pdf-uncompressed|png|x11|svg] (default: ps) - - Set the output file format. - -font-family=NAME (default: Helvetica) - - Set the default font to be used by texts. - -font-size=N (default: 9) - - Set the default font to be used by texts. -line-width=X (default: 0.4) - - Set the default line width, in points. See also - pychart.line_style. - -scale=X (default: 1.0) - - Set the scaling factor. The default is 1.0. - -color=[yes|no] (default: no) - - If yes, Pychart colorizes default object attributes. - -You can also set these variables by calling theme.get_options. -""" - -use_color = 0 -scale_factor = 1 -output_format = None # "ps", "pdf", "png", "x11", or "svg" -compress_output = 1 -output_file = "" - -default_font_family = "Helvetica" -default_font_size = 9 -default_line_height = None -default_font_halign = "L" -default_font_valign = "B" -default_font_angle = 0 -default_line_width = 0.4 - -debug_level = 1 -delta_bounding_box = [-3, -3, 3, 3] -bounding_box = {} - -def parse_yesno(str): - if str in ("yes", "true", "1"): - return 1 - else: - return 0 - -def parse_bounding_box(arg): - global delta_bounding_box, bounding_box - - l = arg.split(",") - if len(l) != 4: - raise ValueError, "Need to specify margin=LEFT,BOTTOM,RIGHT,TOP" - for i in range(0, 4): - val = l[i].strip() - if val[0] == '+': - delta_bounding_box[i] = int(val[1:]) - elif val[0] == '-': - delta_bounding_box[i] = int(val[1:]) - else: - bounding_box[i] = int(val) - -def adjust_bounding_box(bbox): - """Adjust the bounding box as specified by user. - Returns the adjusted bounding box. - - - bbox: Bounding box computed from the canvas drawings. - It must be a four-tuple of numbers. - """ - for i in range(0, 4): - if bounding_box.has_key(i): - bbox[i] = bounding_box[i] - else: - bbox[i] += delta_bounding_box[i] - return bbox - -def parse_option(opt, arg): - global use_color, scale_factor, margin - global output_format, output_file, compress_output - global default_font_family, default_font_size - global default_line_height - global default_line_width, debug_level - if opt == "format": - if arg in ("ps", "eps"): - output_format = "ps" - elif arg == "png": - output_format = "png" - elif arg == "svg": - output_format = "svg" - elif arg == "x11": - output_format = "x11" - elif arg == "pdf-uncompressed": - output_format = "pdf" - compress_output = 0 - elif arg in ("pdf-compressed", "pdf"): - output_format = "pdf" - compress_output = 1 - else: - raise ValueError, "Unknown output option: " + str(arg) - elif opt == "output": - output_file = arg - elif opt == "color": - use_color = 1 - elif opt == "scale": - scale_factor = float(arg) - elif opt == "bbox": - parse_bounding_box(arg) - elif opt == "font-family": - default_font_family = arg - elif opt == "font-size": - default_font_size = float(arg) - default_line_height = float(arg) - elif opt == "line-width": - default_line_width = float(arg) - elif opt == "debug-level": - debug_level = int(arg) - else: - raise getopt.GetoptError, "Unknown option: " + opt + " " + arg - -if os.environ.has_key("PYCHART_OPTIONS"): - for opt in os.environ["PYCHART_OPTIONS"].split(): - opt, arg = opt.split("=") - parse_option(opt, arg) - -hooks = [] -def add_reinitialization_hook(proc): - global hooks - hooks.append(proc) - proc() - -def usage(): - print "Usage: %s [options..]" % sys.argv[0] - print """ - --scale=X: Set the scaling factor to X (default: 1.0). - --format=[ps|png|pdf|x11|svg]: Set the output format (default: ps). - --font-family=NAME: Set the default font family (default: Helvetica). - --font-size=NAME: Set the default font size (default: 9pts). - --line-width=NAME: Set the default line width (default: 0.4). - --debug-level=N: Set the messaging verbosity (default: 0). - --bbox=LEFT,BOTTOM,RIGHT,TOP: Specifies the amount of space (in PS points) to be left in the edges of the picture (default: -1,-1,+1,+1). - """ - -def reinitialize(): - """This procedure must be called after setting variables in - the |theme| module. This procedure propagates the new values of - the theme variables to other modules that depend on their values.""" - for proc in hooks: - proc() - -def get_options(argv = None): - """This procedure takes a list of command line arguments in <argv> - and parses - options. It returns the non-parsed portion of <argv>. Parameter - <argv> can be - omitted, in which case its value defaults to |sys.argv[1:]|. - The options supported are: "|--format=[ps,png,pdf,x11,svg]|", - "|--output=|<file>", "|--color=[yes,no]|" - "|--scale=|<X>", "|--font-family=|<name>", "|--font-size=|<X>", - "|--line-width=|<X>", - "|--debug-level=|<N>", "|bbox=|<left,bottom,right,top>". - The below code shows an example. - -#!/usr/bin/python -from pychart import * -args = theme.get_options() -ar = area.T(...) -... - """ - if argv == None: - argv = sys.argv[1:] - try: - opts, args = getopt.getopt(argv, "d:co:f:", - ["format=", "output=", "color=", - "scale=", "font-family=", "font-size=", - "line-width=", "debug-level=", - "bbox="]) - except getopt.GetoptError, foo: - print foo - usage() - raise getopt.GetoptError - for opt, arg in opts: - if opt == "-d": - parse_option("debug-level", arg) - elif opt == "-c": - parse_option("color", None) - elif opt == "-o": - parse_option("output", arg) - elif opt == "-f": - parse_option("format", arg) - else: - parse_option(opt[2:], arg) - reinitialize() - return args - - diff --git a/openerp/pychart/tick_mark.py b/openerp/pychart/tick_mark.py deleted file mode 100644 index a632da24bbe..00000000000 --- a/openerp/pychart/tick_mark.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import color -import line_style -import fill_style -import chart_object -import object_set -import pychart_util -import tick_mark_doc -from pychart_types import * - -_keys = { - "line_style": (line_style.T, line_style.default, "The line style of the tick mark."), - "fill_style": (fill_style.T, fill_style.white, "The fill style."), - "size": (UnitType, 5, "Size of the tick mark."), - } - -class T(chart_object.T): - __doc__ = tick_mark_doc.doc - keys = _keys -##AUTOMATICALLY GENERATED - -##END AUTOMATICALLY GENERATED - - def predraw_check(self): - if not hasattr(self, "type_checked"): - self.type_check() - self.type_checked = 1 - -class Circle(T): - """Draws a circle. """ - def draw(self, can, x, y): - self.predraw_check() - can.ellipsis(self.line_style, self.fill_style, x, y, - self.size/2.0, 1) - -class Square(T): - """Draws a square.""" - def draw(self, can, x, y): - self.predraw_check() - # move to the bottom-left corner - x = x - self.size/2.0 - y = y - self.size/2.0 - can.rectangle(self.line_style, self.fill_style, - x, y, x+self.size, y+self.size) - -class Triangle(T): - """Draws a triangle pointing up.""" - def draw(self, can, x, y): - self.predraw_check() - can.polygon(self.line_style, self.fill_style, - ((x-self.size/1.6, y-self.size/2.0), - (x+self.size/1.6, y-self.size/2.0), - (x, y+self.size/2.0))) -class DownTriangle(T): - """Draws a triangle pointing down.""" - def draw(self, can, x, y): - self.predraw_check() - can.polygon(self.line_style, self.fill_style, - ((x, y-self.size/2.0), - (x-self.size/1.6, y+self.size/2.0), - (x+self.size/1.6, y+self.size/2.0))) - - -class X(T): - """Draw a "X"-shaped tick mark. Attribute "fill-style" is ignored.""" - keys = pychart_util.union_dict(T.keys, - {"line_style": (line_style.T, - line_style.T(width=0.7), - "The line style of the tick mark")}) - def draw(self, can, x, y): - self.predraw_check() - # move to the bottom-left corner - x = x - self.size/2.0 - y = y - self.size/2.0 - can.line(self.line_style, x, y, x+self.size, y+self.size) - can.line(self.line_style, x+self.size, y, x, y+self.size) - -class Plus(T): - """Draw a "+"-shaped tick mark. Attribute "fill-style" is ignored.""" - keys = pychart_util.union_dict(T.keys, - {"line_style": (line_style.T, - line_style.T(width=1), - "The line style of the tick mark.")}) - def draw(self, can, x, y): - self.predraw_check() - # move to the bottom-left corner - can.line(self.line_style, x-self.size/1.4, y, x+self.size/1.4, y) - can.line(self.line_style, x, y-self.size/1.4, x, y+self.size/1.4) - -class Diamond(T): - """Draw a square rotated at 45 degrees.""" - def draw(self, can, x, y): - self.predraw_check() - # move to the bottom-left corner - can.polygon(self.line_style, self.fill_style, - ((x-self.size/1.4, y), (x, y+self.size/1.4), - (x+self.size/1.4, y), (x, y-self.size/1.4))) - -class Star(T): - """Draw a "*". Attribute "fill-style" is ignored.""" - keys = pychart_util.union_dict(T.keys, - {"line_style": (line_style.T, - line_style.T(width=1), - "The line style of the tick mark.")}) - def draw(self, can, x, y): - self.predraw_check() - # move to the bottom-left corner - midx = x - midy = y - d_len = self.size / 2.0 - r_len = self.size * 1.414 / 2.0 - can.line(self.line_style, x-d_len, y-d_len, x+d_len, y+d_len) - can.line(self.line_style, x+d_len, y-d_len, x-d_len, y+d_len) - can.line(self.line_style, midx, y-r_len, midx, y+r_len) - can.line(self.line_style, x-r_len, midy, x+r_len, midy) - -class Null(T): - """This tickmark doesn't draw anything. All the attributes are ignored.""" - def __init__ (self): - self.line_style = None - self.fill_style = None - self.size = -1 - def draw(self, can, x, y): - pass - -standards = object_set.T() -def _intern(style): - standards.add(style) - return style - -square = _intern(Square()) -square3 = _intern(Square(size=3)) -square5 = square -x = _intern(X()) -x3 = _intern(X(size=3)) -x5 = x -star = _intern(Star()) -star3 = _intern(Star(size=3)) -star5 = star -plus = _intern(Plus()) -plus3 = _intern(Plus(size=3)) -plus5 = plus -dia = _intern(Diamond()) -dia3 = _intern(Diamond(size=3)) -dia5 = dia -tri = _intern(Triangle()) -tri3 = _intern(Triangle(size=3)) -tri5 = tri -dtri = _intern(DownTriangle()) -dtri3 = _intern(DownTriangle(size=3)) -dtri5 = dtri -circle1 = _intern(Circle(size=1)) -circle2 = _intern(Circle(size=3)) -circle3 = _intern(Circle(size=5)) -blacksquare = _intern(Square(fill_style=fill_style.black)) -blacksquare3 = _intern(Square(size=3, fill_style=fill_style.black)) -blackdia = _intern(Diamond(fill_style=fill_style.black)) -blackdia3 = _intern(Diamond(size=3, fill_style=fill_style.black)) -blacktri = _intern(Triangle(fill_style=fill_style.black)) -blacktri3 = _intern(Triangle(size=3, fill_style=fill_style.black)) -blackdtri = _intern(DownTriangle(fill_style=fill_style.black)) -blackdtri3 = _intern(DownTriangle(size=3, fill_style=fill_style.black)) -blackcircle1 = _intern(Circle(size=1, fill_style=fill_style.black)) -blackcircle3 = _intern(Circle(size=3, fill_style=fill_style.black)) -gray70square = _intern(Square(fill_style=fill_style.gray70)) -gray70square3 = _intern(Square(size=3, fill_style=fill_style.gray70)) -gray70dia = _intern(Diamond(fill_style=fill_style.gray70)) -gray70dia3 = _intern(Diamond(size=3, fill_style=fill_style.gray70)) -gray70tri = _intern(Triangle(fill_style=fill_style.gray70)) -gray70tri3 = _intern(Triangle(size=3, fill_style=fill_style.gray70)) -gray70dtri = _intern(DownTriangle(fill_style=fill_style.gray70)) -gray70dtri3 = _intern(DownTriangle(size=3, fill_style=fill_style.gray70)) -gray70circle1 = _intern(Circle(size=1, fill_style=fill_style.gray70)) -gray70circle3 = _intern(Circle(size=3, fill_style=fill_style.gray70)) -default = _intern(Null()) - diff --git a/openerp/pychart/tick_mark_doc.py b/openerp/pychart/tick_mark_doc.py deleted file mode 100644 index 61151668827..00000000000 --- a/openerp/pychart/tick_mark_doc.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- -# automatically generated by generate_docs.py. -doc="""Attributes supported by this class are: -line_style(type:line_style.T) default="The line style of the tick mark.". -size(type:length in points (\\xref{unit})) default="Size of the tick mark.". -fill_style(type:fill_style.T) default="The fill style.". -""" - diff --git a/openerp/pychart/typechecker.py b/openerp/pychart/typechecker.py deleted file mode 100644 index a119f909c1f..00000000000 --- a/openerp/pychart/typechecker.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import types -class IntervalTypeClass: - def typeCheck(self, val): - if type(val) in (types.IntType, types.LongType, types.FloatType, - types.FunctionType): - return None - return "Expecting a number or a function, but received '%s'", val - def typeDescription(self): - return "A number or function" - def varDescription(self, name): - return "A number or function" - -IntervalType = IntervalTypeClass() - diff --git a/openerp/pychart/version.py b/openerp/pychart/version.py deleted file mode 100644 index 4fe19c790fe..00000000000 --- a/openerp/pychart/version.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -version = "1.37" -copyright = "Copyright 1999-2005 Yasushi Saito" - diff --git a/openerp/pychart/x11canvas.py b/openerp/pychart/x11canvas.py deleted file mode 100644 index bb1cacfefdc..00000000000 --- a/openerp/pychart/x11canvas.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import os -import gs_frontend -import theme -import sys - -class T(gs_frontend.T): - def close(self): - gs_frontend.T.close(self) - self.start_gs("-sDEVICE=x11") - sys.stdin.readline() - self.close_gs() - diff --git a/openerp/pychart/zap.py b/openerp/pychart/zap.py deleted file mode 100644 index 7291ed3275a..00000000000 --- a/openerp/pychart/zap.py +++ /dev/null @@ -1,79 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com) -# -# Jockey is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Jockey is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -import fill_style -import line_style -import copy - -def _draw_zap(can, p1, p2, style, pat): - x = copy.deepcopy(p1) - x.extend(p2) - can.polygon(None, pat, x) - can.lines(style, p1) - can.lines(style, p2) - - -def zap_horizontally(can, style, pat, x1, y1, x2, y2, xsize, ysize): - """Draw a horizontal "zapping" symbol on the canvas that shows - that a graph is ripped in the middle. - - Parameter <fill_style> specifies the style for the zig-zag lines. - PAT specifies the pattern with which the area is filled. - The symbol is drawn in the rectangle (<x1>, <y1>) - (<x2>, <y2>). - Each "zigzag" has the width <xsize>, height <ysize>.""" - - assert isinstance(style, line_style.T) - assert isinstance(pat, fill_style.T) - - points = [] - points2 = [] - x = x1 - y = y1 - while x < x2: - points.append((x, y)) - points2.append((x, y + (y2-y1))) - x += xsize - if y == y1: - y += ysize - else: - y -= ysize - - points2.reverse() - _draw_zap(can, points, points2, style, pat) - -def zap_vertically(can, style, pat, x1, y1, x2, y2, xsize, ysize): - """Draw a vertical "zapping" symbol on the canvas that shows - that a graph is ripped in the middle. - - Parameter <fill_style> specifies the style for the zig-zag lines. - PAT specifies the pattern with which the area is filled. - The symbol is drawn in the rectangle (<x1>, <y1>) - (<x2>, <y2>). - Each "zigzag" has the width <xsize>, height <ysize>.""" - - points = [] - points2 = [] - x = x1 - y = y1 - while y < y2: - points.append((x, y)) - points2.append((x + (x2-x1), y)) - y += ysize - if x == x1: - x += xsize - else: - x -= xsize - - points2.reverse() - _draw_zap(can, points, points2, style, pat) - diff --git a/openerp/report/__init__.py b/openerp/report/__init__.py index 646967f00d1..48b654fdd86 100644 --- a/openerp/report/__init__.py +++ b/openerp/report/__init__.py @@ -24,7 +24,6 @@ import print_xml import print_fnc import custom import render -import openerp.pychart import int_to_text import report_sxw diff --git a/openerp/report/custom.py b/openerp/report/custom.py index 051d1f29862..596d9a9f1b9 100644 --- a/openerp/report/custom.py +++ b/openerp/report/custom.py @@ -21,7 +21,6 @@ import os import time -import openerp.netsvc as netsvc import openerp.tools as tools from openerp.tools.safe_eval import safe_eval as eval @@ -67,7 +66,6 @@ class report_custom(report_int): # def _row_get(self, cr, uid, objs, fields, conditions, row_canvas=None, group_by=None): result = [] - tmp = [] for obj in objs: tobreak = False for cond in conditions: @@ -108,7 +106,7 @@ class report_custom(report_int): key = levels.keys() for l in key: objs = eval('obj.'+l,{'obj': obj}) - if not isinstance(objs, browse_record_list) and type(objs) <> type([]): + if not isinstance(objs, (browse_record_list, list)): objs = [objs] field_new = [] cond_new = [] @@ -221,11 +219,9 @@ class report_custom(report_int): res_dic[prev].append(line) else: prev = line[groupby] - if res_dic.has_key(line[groupby]): - res_dic[line[groupby]].append(line) - else: - res_dic[line[groupby]] = [] - res_dic[line[groupby]].append(line) + res_dic.setdefault(line[groupby], []) + res_dic[line[groupby]].append(line) + #we use the keys in results since they are ordered, whereas in res_dic.heys() they aren't for key in filter(None, [x[groupby] for x in results]): row = [] @@ -267,7 +263,7 @@ class report_custom(report_int): else: try: row.append(float(r[j])) - except: + except Exception: row.append(r[j]) results2.append(row) if report['type']=='pie': @@ -365,7 +361,6 @@ class report_custom(report_int): order_date['Y'] = lambda x : x abscissa = [] - tmp = {} idx = 0 date_idx = None @@ -389,7 +384,7 @@ class report_custom(report_int): if date_idx != None: for r in results: key = process_date['Y'](r[date_idx]) - if not data_by_year.has_key(key): + if key not in data_by_year: data_by_year[key] = [] for i in range(len(r)): r[i] = fct[i](r[i]) @@ -407,14 +402,14 @@ class report_custom(report_int): for d in data_by_year[line]: for idx in range(len(fields)-1): fields_bar.append({}) - if fields_bar[idx].has_key(d[0]): + if d[0] in fields_bar[idx]: fields_bar[idx][d[0]] += d[idx+1] else: fields_bar[idx][d[0]] = d[idx+1] for idx in range(len(fields)-1): data = {} for k in fields_bar[idx].keys(): - if data.has_key(k): + if k in data: data[k] += fields_bar[idx][k] else: data[k] = fields_bar[idx][k] @@ -488,7 +483,7 @@ class report_custom(report_int): if date_idx != None: for r in results: key = process_date['Y'](r[date_idx]) - if not data_by_year.has_key(key): + if key not in data_by_year: data_by_year[key] = [] for i in range(len(r)): r[i] = fct[i](r[i]) @@ -507,14 +502,14 @@ class report_custom(report_int): for d in data_by_year[line]: for idx in range(len(fields)-1): fields_bar.append({}) - if fields_bar[idx].has_key(d[0]): + if d[0] in fields_bar[idx]: fields_bar[idx][d[0]] += d[idx+1] else: fields_bar[idx][d[0]] = d[idx+1] for idx in range(len(fields)-1): data = {} for k in fields_bar[idx].keys(): - if data.has_key(k): + if k in data: data[k] += fields_bar[idx][k] else: data[k] = fields_bar[idx][k] diff --git a/openerp/report/interface.py b/openerp/report/interface.py index 9a97c445671..17dc0973d7e 100644 --- a/openerp/report/interface.py +++ b/openerp/report/interface.py @@ -44,8 +44,8 @@ class report_int(netsvc.Service): def __init__(self, name): assert not self.exists(name), 'The report "%s" already exists!' % name super(report_int, self).__init__(name) - if name[0:7]<>'report.': - raise Exception, 'ConceptionError, bad report name, should start with "report."' + if not name.startswith('report.'): + raise Exception('ConceptionError, bad report name, should start with "report."') self.name = name self.id = 0 self.name2 = '.'.join(name.split('.')[1:]) @@ -181,7 +181,7 @@ class report_rml(report_int): def create_pdf(self, rml, localcontext = None, logo=None, title=None): if not localcontext: - localcontext={} + localcontext = {} localcontext.update({'internal_header':self.internal_header}) if logo: self.bin_datas['logo'] = logo diff --git a/openerp/report/preprocess.py b/openerp/report/preprocess.py index e681860d7a2..93b6b4d1bc9 100644 --- a/openerp/report/preprocess.py +++ b/openerp/report/preprocess.py @@ -48,7 +48,7 @@ class report(object): try: while n.tag != txt.group(3): n = n.getparent() - except: + except Exception: n = node else: n = node.getparent() diff --git a/openerp/report/print_xml.py b/openerp/report/print_xml.py index ee1b9a316b3..c2af0984c2e 100644 --- a/openerp/report/print_xml.py +++ b/openerp/report/print_xml.py @@ -200,7 +200,7 @@ class document(object): else: args = [] # get the object - if attrs.has_key('model'): + if 'model' in attrs: obj = self.pool.get(attrs['model']) else: if isinstance(browser, list): @@ -209,7 +209,7 @@ class document(object): obj = browser._table # get the ids - if attrs.has_key('ids'): + if 'ids' in attrs: ids = self.eval(browser, attrs['ids']) else: if isinstance(browser, list): @@ -228,7 +228,7 @@ class document(object): if not isinstance(datas[atr['value']], (str, unicode)): txt = str(datas[atr['value']]) else: - txt = datas[atr['value']] + txt = datas[atr['value']] el.text = txt else: for el_cld in node: diff --git a/openerp/report/printscreen/ps_form.py b/openerp/report/printscreen/ps_form.py index 8e3823e6b03..cf6d77cbe26 100644 --- a/openerp/report/printscreen/ps_form.py +++ b/openerp/report/printscreen/ps_form.py @@ -120,7 +120,7 @@ class report_printscreen_list(report_int): line[f]=round(line[f],precision) col = etree.SubElement(node_line, 'col', tree='no') if line[f] != None: - col.text = tools.ustr(line[f] or '') + col.text = tools.ustr(line[f] or '') else: col.text = '/' diff --git a/openerp/report/printscreen/ps_list.py b/openerp/report/printscreen/ps_list.py index dc280a53e3e..8f0629462f8 100644 --- a/openerp/report/printscreen/ps_list.py +++ b/openerp/report/printscreen/ps_list.py @@ -56,7 +56,7 @@ class report_printscreen_list(report_int): def _parse_string(self, view): try: dom = etree.XML(view.encode('utf-8')) - except: + except Exception: dom = etree.XML(view) return self._parse_node(dom) diff --git a/openerp/report/render/html2html/html2html.py b/openerp/report/render/html2html/html2html.py index 181c7f7ba67..09d7ad5e825 100644 --- a/openerp/report/render/html2html/html2html.py +++ b/openerp/report/render/html2html/html2html.py @@ -20,9 +20,7 @@ ############################################################################## from openerp.report.render.rml2pdf import utils -from lxml import etree import copy -import openerp.pooler as pooler import base64 import cStringIO import re diff --git a/openerp/report/render/makohtml2html/makohtml2html.py b/openerp/report/render/makohtml2html/makohtml2html.py index 57e57bd8d63..dbb3327a105 100644 --- a/openerp/report/render/makohtml2html/makohtml2html.py +++ b/openerp/report/render/makohtml2html/makohtml2html.py @@ -23,8 +23,7 @@ import mako from lxml import etree from mako.template import Template from mako.lookup import TemplateLookup -import openerp.netsvc as netsvc -import traceback, sys, os +import os _logger = logging.getLogger(__name__) @@ -126,9 +125,8 @@ class makohtml2html(object): final_html += self.format_header(etree_obj) final_html += self.format_body(etree_obj) return final_html - except Exception,e: - tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) - _logger.error('report :\n%s\n%s\n', tb_s, str(e)) + except Exception: + _logger.exception('report :') def parseNode(html, localcontext = {}): r = makohtml2html(html, localcontext) diff --git a/openerp/report/render/odt2odt/odt2odt.py b/openerp/report/render/odt2odt/odt2odt.py index d077207f4d7..b9713943dc8 100644 --- a/openerp/report/render/odt2odt/odt2odt.py +++ b/openerp/report/render/odt2odt/odt2odt.py @@ -20,7 +20,6 @@ ############################################################################## from openerp.report.render.rml2pdf import utils -from lxml import etree import copy class odt2odt(object): diff --git a/openerp/report/render/rml2html/rml2html.py b/openerp/report/render/rml2html/rml2html.py index 504492772df..90bd58af99a 100644 --- a/openerp/report/render/rml2html/rml2html.py +++ b/openerp/report/render/rml2html/rml2html.py @@ -39,7 +39,7 @@ import sys import cStringIO from lxml import etree import copy -import utils + from openerp.report.render.rml2pdf import utils class _flowable(object): @@ -98,7 +98,7 @@ class _flowable(object): try: if new_child.get('style').find('terp_tblheader')!= -1: new_node.tag = 'th' - except: + except Exception: pass process(node,new_node) if new_node.get('colWidths',False): @@ -232,7 +232,7 @@ class _rml_stylesheet(object): attr = {} attrs = ps.attrib for key, val in attrs.items(): - attr[key] = val + attr[key] = val attrs = [] for a in attr: if a in self._tags: @@ -296,13 +296,13 @@ class _rml_template(object): frames[(posy,posx,tmpl.get('id'))] = _rml_tmpl_frame(posx, utils.unit_get(tmpl.get('width'))) for tmpl in pt.findall('pageGraphics'): for n in tmpl: - if n.tag == 'image': - self.data = rc + utils._process_text(self, n.text) - if n.tag in self._tags: - t = self._tags[n.tag](n, self.style,self.localcontext) - frames[(t.posy,t.posx,n.tag)] = t - else: - self.style.update(n) + if n.tag == 'image': + self.data = rc + utils._process_text(self, n.text) + if n.tag in self._tags: + t = self._tags[n.tag](n, self.style,self.localcontext) + frames[(t.posy,t.posx,n.tag)] = t + else: + self.style.update(n) keys = frames.keys() keys.sort() keys.reverse() diff --git a/openerp/report/render/rml2pdf/trml2pdf.py b/openerp/report/render/rml2pdf/trml2pdf.py index 96287166074..a17c03b40cb 100644 --- a/openerp/report/render/rml2pdf/trml2pdf.py +++ b/openerp/report/render/rml2pdf/trml2pdf.py @@ -82,7 +82,7 @@ class NumberedCanvas(canvas.Canvas): def showPage(self): self._currentPage +=1 if not self._flag: - self._pageCount += 1 + self._pageCount += 1 else: self.pages.update({self._currentPage:self._pageCount}) self._codes.append({'code': self._code, 'stack': self._codeStack}) @@ -424,7 +424,7 @@ class _rml_canvas(object): flow.drawOn(self.canvas,infos['x'],infos['y']) infos['height']-=h else: - raise ValueError, "Not enough space" + raise ValueError("Not enough space") def _line_mode(self, node): ljoin = {'round':1, 'mitered':0, 'bevelled':2} diff --git a/openerp/report/render/rml2txt/rml2txt.py b/openerp/report/render/rml2txt/rml2txt.py index 4a30e0d2345..ab1930d81ba 100755 --- a/openerp/report/render/rml2txt/rml2txt.py +++ b/openerp/report/render/rml2txt/rml2txt.py @@ -22,9 +22,7 @@ import sys import StringIO -import copy from lxml import etree -import base64 import utils @@ -336,8 +334,8 @@ class _rml_stylesheet(object): attr = {} attrs = ps.attributes for i in range(attrs.length): - name = attrs.item(i).localName - attr[name] = ps.get(name) + name = attrs.item(i).localName + attr[name] = ps.get(name) attrs = [] for a in attr: if a in self._tags: diff --git a/openerp/report/render/rml2txt/utils.py b/openerp/report/render/rml2txt/utils.py index 174612d847e..a56ee02b66d 100644 --- a/openerp/report/render/rml2txt/utils.py +++ b/openerp/report/render/rml2txt/utils.py @@ -23,7 +23,6 @@ import copy import re import reportlab import reportlab.lib.units -from lxml import etree from openerp.tools.safe_eval import safe_eval as eval _regex = re.compile('\[\[(.+?)\]\]') @@ -38,7 +37,7 @@ def _child_get(node, self=None, tagname=None): if n.get('rml_except', False): try: eval(n.get('rml_except'), {}, self.localcontext) - except: + except Exception: continue if n.get('rml_tag'): try: @@ -47,7 +46,7 @@ def _child_get(node, self=None, tagname=None): n2.tag = tag n2.attrib.update(attr) yield n2 - except: + except Exception: yield n else: yield n @@ -56,7 +55,7 @@ def _child_get(node, self=None, tagname=None): if self and self.localcontext and n.get('rml_except', False): try: eval(n.get('rml_except'), {}, self.localcontext) - except: + except Exception: continue if (tagname is None) or (n.tag==tagname): yield n @@ -74,11 +73,11 @@ def _process_text(self, txt): if sps: try: txt2 = eval(sps.pop(0),self.localcontext) - except: + except Exception: txt2 = '' - if type(txt2) == type(0) or type(txt2) == type(0.0): + if isinstance(txt2, (int, float)): txt2 = str(txt2) - if type(txt2)==type('') or type(txt2)==type(u''): + if isinstance(txt2, basestring): result += txt2 return result diff --git a/openerp/report/render/simple.py b/openerp/report/render/simple.py index 4ce10991924..cb3831c141f 100644 --- a/openerp/report/render/simple.py +++ b/openerp/report/render/simple.py @@ -66,7 +66,6 @@ class simple(render.render): return self.result.getvalue() if __name__=='__main__': - import time s = simple() s.xml = '''<test> <author-list> @@ -82,7 +81,7 @@ if __name__=='__main__': </author-list> </test>''' if s.render(): - print s.get() + print s.get() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/service/http_server.py b/openerp/service/http_server.py index 07e31ea9c7d..63e0d08fc92 100644 --- a/openerp/service/http_server.py +++ b/openerp/service/http_server.py @@ -44,10 +44,8 @@ import posixpath import urllib import os import logging -from SimpleXMLRPCServer import SimpleXMLRPCDispatcher from websrv_lib import * -import openerp.netsvc as netsvc import openerp.tools as tools try: diff --git a/openerp/service/netrpc_server.py b/openerp/service/netrpc_server.py index 325288791f7..fcbfaf0ba82 100644 --- a/openerp/service/netrpc_server.py +++ b/openerp/service/netrpc_server.py @@ -126,12 +126,12 @@ class TinySocketServerThread(threading.Thread,netsvc.Server): ct.start() lt = len(self.threads) if (lt > 10) and (lt % 10 == 0): - # Not many threads should be serving at the same time, so log - # their abuse. - _logger.debug("Netrpc: %d threads", len(self.threads)) + # Not many threads should be serving at the same time, so log + # their abuse. + _logger.debug("Netrpc: %d threads", len(self.threads)) self.socket.close() except Exception, e: - _logger.warning("Netrpc: closing because of exception %s" % str(e)) + _logger.warning("Netrpc: closing because of exception %s", e) self.socket.close() return False diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 1dfd61c1daf..6e1f463c1cb 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -40,6 +40,7 @@ import openerp.tools as tools import openerp.modules import openerp.exceptions from openerp.service import http_server +from openerp import SUPERUSER_ID #.apidoc title: Exported Service methods #.apidoc module-mods: member-order: bysource @@ -72,8 +73,8 @@ def _initialize_db(serv, id, db_name, demo, lang, user_password): if lang: modobj = pool.get('ir.module.module') - mids = modobj.search(cr, 1, [('state', '=', 'installed')]) - modobj.update_translations(cr, 1, mids, lang) + mids = modobj.search(cr, SUPERUSER_ID, [('state', '=', 'installed')]) + modobj.update_translations(cr, SUPERUSER_ID, mids, lang) cr.execute('UPDATE res_users SET password=%s, lang=%s, active=True WHERE login=%s', ( user_password, lang, 'admin')) @@ -237,9 +238,9 @@ class db(netsvc.ExportService): if not data or res: _logger.error( - 'DUMP DB: %s failed! Please verify the configuration of the database password on the server. '\ - 'It should be provided as a -w <PASSWD> command-line option, or as `db_password` in the '\ - 'server configuration file.\n %s' % (db_name, data)) + 'DUMP DB: %s failed! Please verify the configuration of the database password on the server. ' + 'It should be provided as a -w <PASSWD> command-line option, or as `db_password` in the ' + 'server configuration file.\n %s', db_name, data) raise Exception, "Couldn't dump database" _logger.info('DUMP DB successful: %s', db_name) @@ -252,7 +253,7 @@ class db(netsvc.ExportService): self._set_pg_psw_env_var() if self.exp_db_exist(db_name): - _logger.warning('RESTORE DB: %s already exists' % (db_name,)) + _logger.warning('RESTORE DB: %s already exists', db_name) raise Exception, "Database already exists" self._create_empty_database(db_name) @@ -281,7 +282,7 @@ class db(netsvc.ExportService): res = stdout.close() if res: raise Exception, "Couldn't restore database" - _logger.info('RESTORE DB: %s' % (db_name)) + _logger.info('RESTORE DB: %s', db_name) return True finally: @@ -464,8 +465,7 @@ GNU Public Licence. backup_directory = os.path.join(tools.config['root_path'], 'backup', time.strftime('%Y-%m-%d-%H-%M')) if zips and not os.path.isdir(backup_directory): - _logger.info('create a new backup directory to \ - store the old modules: %s', backup_directory) + _logger.info('create a new backup directory to store the old modules: %s', backup_directory) os.makedirs(backup_directory) for module in zips: @@ -525,11 +525,11 @@ GNU Public Licence. 'OS Name : %s\n' \ %(platform.platform(), platform.os.name) if os.name == 'posix': - if platform.system() == 'Linux': - lsbinfo = os.popen('lsb_release -a').read() - environment += '%s'%(lsbinfo) - else: - environment += 'Your System is not lsb compliant\n' + if platform.system() == 'Linux': + lsbinfo = os.popen('lsb_release -a').read() + environment += '%s'%(lsbinfo) + else: + environment += 'Your System is not lsb compliant\n' environment += 'Operating System Release : %s\n' \ 'Operating System Version : %s\n' \ 'Operating System Architecture : %s\n' \ @@ -694,7 +694,7 @@ class report_spool(netsvc.ExportService): self._reports[id]['state'] = True except Exception, exception: - _logger.exception('Exception: %s\n', str(exception)) + _logger.exception('Exception: %s\n', exception) if hasattr(exception, 'name') and hasattr(exception, 'value'): self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value)) else: @@ -731,7 +731,7 @@ class report_spool(netsvc.ExportService): self._reports[id]['format'] = format self._reports[id]['state'] = True except Exception, exception: - _logger.exception('Exception: %s\n', str(exception)) + _logger.exception('Exception: %s\n', exception) if hasattr(exception, 'name') and hasattr(exception, 'value'): self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value)) else: diff --git a/openerp/tests/__init__.py b/openerp/tests/__init__.py index d3ab62ebc1c..aa3055f471c 100644 --- a/openerp/tests/__init__.py +++ b/openerp/tests/__init__.py @@ -9,7 +9,7 @@ See the :ref:`test-framework` section in the :ref:`features` list. """ from . import test_expression, test_html_sanitize, test_ir_sequence, test_orm,\ - test_view_validation, test_uninstall + test_view_validation, test_uninstall, test_misc fast_suite = [ test_ir_sequence, @@ -20,6 +20,7 @@ checks = [ test_html_sanitize, test_orm, test_view_validation, + test_misc, ] # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tests/addons/test_impex/tests/test_import.py b/openerp/tests/addons/test_impex/tests/test_import.py index ab12f0375b5..03507ee7012 100644 --- a/openerp/tests/addons/test_impex/tests/test_import.py +++ b/openerp/tests/addons/test_impex/tests/test_import.py @@ -3,6 +3,7 @@ import openerp.modules.registry import openerp from openerp.tests import common +from openerp.tools.misc import mute_logger def ok(n): """ Successful import of ``n`` records @@ -221,6 +222,7 @@ class test_integer_field(ImporterCase): -1, -42, -(2**31 - 1), -(2**31), -12345678 ], values(self.read())) + @mute_logger('openerp.sql_db') def test_out_of_range(self): self.assertEqual( self.import_(['value'], [[str(2**31)]]), @@ -714,6 +716,15 @@ class test_m2m(ImporterCase): class test_o2m(ImporterCase): model_name = 'export.one2many' + def test_name_get(self): + # FIXME: bloody hell why can't this just name_create the record? + self.assertRaises( + IndexError, + self.import_, + ['const', 'value'], + [['5', u'Java is a DSL for taking large XML files' + u' and converting them to stack traces']]) + def test_single(self): self.assertEqual( self.import_(['const', 'value/value'], [ diff --git a/openerp/tests/addons/test_limits/models.py b/openerp/tests/addons/test_limits/models.py index 5240acd23ab..32e2a9a16f4 100644 --- a/openerp/tests/addons/test_limits/models.py +++ b/openerp/tests/addons/test_limits/models.py @@ -27,7 +27,6 @@ class m(openerp.osv.osv.Model): return True def consume_cpu_time(self, cr, uid, seconds, context=None): - import os t0 = time.clock() t1 = time.clock() while t1 - t0 < seconds: diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 9bf090e05cb..80e1971e277 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import os +import threading import time import unittest2 import xmlrpclib @@ -11,6 +12,13 @@ ADDONS_PATH = openerp.tools.config['addons_path'] PORT = openerp.tools.config['xmlrpc_port'] DB = openerp.tools.config['db_name'] +# If the database name is not provided on the command-line, +# use the one on the thread (which means if it is provided on +# the command-line, this will break when installing another +# database from XML-RPC). +if not DB and hasattr(threading.current_thread(), 'dbname'): + DB = threading.current_thread().dbname + HOST = '127.0.0.1' ADMIN_USER = 'admin' diff --git a/openerp/tests/test_html_sanitize.py b/openerp/tests/test_html_sanitize.py index 90ccc88cc1d..cb46b325144 100755 --- a/openerp/tests/test_html_sanitize.py +++ b/openerp/tests/test_html_sanitize.py @@ -26,11 +26,15 @@ class TestSanitizer(unittest.TestCase): def test_simple(self): x = "yop" self.assertEqual(x, html_sanitize(x)) + + def test_trailing_text(self): + x = 'lala<p>yop</p>xxx' + self.assertEqual(x, html_sanitize(x)) - def test_test_case(self): + def test_no_exception(self): html_sanitize(test_case) - def test_crm(self): + def test_unicode(self): html_sanitize("Merci à l'intérêt pour notre produit.nous vous contacterons bientôt. Merci") if __name__ == '__main__': diff --git a/openerp/tests/test_ir_sequence.py b/openerp/tests/test_ir_sequence.py index fcc5888e47e..cbb1a347038 100644 --- a/openerp/tests/test_ir_sequence.py +++ b/openerp/tests/test_ir_sequence.py @@ -22,6 +22,16 @@ def registry(model): def cursor(): return openerp.modules.registry.RegistryManager.get(DB).db.cursor() + +def drop_sequence(code): + cr = cursor() + for model in ['ir.sequence', 'ir.sequence.type']: + s = registry(model) + ids = s.search(cr, ADMIN_USER_ID, [('code', '=', code)]) + s.unlink(cr, ADMIN_USER_ID, ids) + cr.commit() + cr.close() + class test_ir_sequence_standard(unittest2.TestCase): """ A few tests for a 'Standard' (i.e. PostgreSQL) sequence. """ @@ -48,7 +58,7 @@ class test_ir_sequence_standard(unittest2.TestCase): 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', {}) + n = registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type', {}) assert n cr.commit() cr.close() @@ -57,15 +67,19 @@ class test_ir_sequence_standard(unittest2.TestCase): """ Try to draw a number from two transactions. """ cr0 = cursor() cr1 = cursor() - n0 = registry('ir.sequence').get(cr0, ADMIN_USER_ID, 'test_sequence_type', {}) + n0 = registry('ir.sequence').next_by_code(cr0, ADMIN_USER_ID, 'test_sequence_type', {}) assert n0 - n1 = registry('ir.sequence').get(cr1, ADMIN_USER_ID, 'test_sequence_type', {}) + n1 = registry('ir.sequence').next_by_code(cr1, ADMIN_USER_ID, 'test_sequence_type', {}) assert n1 cr0.commit() cr1.commit() cr0.close() cr1.close() + @classmethod + def tearDownClass(cls): + drop_sequence('test_sequence_type') + class test_ir_sequence_no_gap(unittest2.TestCase): """ Copy of the previous tests for a 'No gap' sequence. """ @@ -85,7 +99,7 @@ class test_ir_sequence_no_gap(unittest2.TestCase): 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', {}) + n = registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type_2', {}) assert n cr.commit() cr.close() @@ -99,12 +113,16 @@ class test_ir_sequence_no_gap(unittest2.TestCase): cr1._default_log_exceptions = False # Prevent logging a traceback 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', {}) + n0 = registry('ir.sequence').next_by_code(cr0, ADMIN_USER_ID, 'test_sequence_type_2', {}) assert n0 - n1 = registry('ir.sequence').get(cr1, ADMIN_USER_ID, 'test_sequence_type_2', {}) + n1 = registry('ir.sequence').next_by_code(cr1, ADMIN_USER_ID, 'test_sequence_type_2', {}) cr0.close() cr1.close() + @classmethod + def tearDownClass(cls): + drop_sequence('test_sequence_type_2') + class test_ir_sequence_change_implementation(unittest2.TestCase): """ Create sequence objects and change their ``implementation`` field. """ @@ -146,6 +164,11 @@ class test_ir_sequence_change_implementation(unittest2.TestCase): cr.commit() cr.close() + @classmethod + def tearDownClass(cls): + drop_sequence('test_sequence_type_3') + drop_sequence('test_sequence_type_4') + class test_ir_sequence_generate(unittest2.TestCase): """ Create sequence objects and generate some values. """ @@ -162,8 +185,8 @@ class test_ir_sequence_generate(unittest2.TestCase): 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)) + f = lambda *a: registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type_5', {}) + assert all(str(x) == f() for x in xrange(1,10)) cr.commit() cr.close() @@ -180,11 +203,15 @@ class test_ir_sequence_generate(unittest2.TestCase): 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)) + f = lambda *a: registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type_6', {}) + assert all(str(x) == f() for x in xrange(1,10)) cr.commit() cr.close() - + + @classmethod + def tearDownClass(cls): + drop_sequence('test_sequence_type_5') + drop_sequence('test_sequence_type_6') if __name__ == '__main__': diff --git a/openerp/tests/test_misc.py b/openerp/tests/test_misc.py new file mode 100644 index 00000000000..7661f253b17 --- /dev/null +++ b/openerp/tests/test_misc.py @@ -0,0 +1,21 @@ +# This test can be run stand-alone with something like: +# > PYTHONPATH=. python2 openerp/tests/test_misc.py + +import unittest2 + +class test_misc(unittest2.TestCase): + """ Test some of our generic utility functions """ + + def test_append_to_html(self): + from openerp.tools import append_content_to_html + test_samples = [ + ('<!DOCTYPE...><HTML encoding="blah">some <b>content</b></HtMl>', '--\nYours truly', True, + '<!DOCTYPE...><html encoding="blah">some <b>content</b>\n<pre>--\nYours truly</pre>\n</html>'), + ('<html><body>some <b>content</b></body></html>', '<!DOCTYPE...>\n<html><body>\n<p>--</p>\n<p>Yours truly</p>\n</body>\n</html>', False, + '<html><body>some <b>content</b>\n\n\n<p>--</p>\n<p>Yours truly</p>\n\n\n</body></html>'), + ] + for html, content, flag, expected in test_samples: + self.assertEqual(append_content_to_html(html,content,flag), expected, 'append_content_to_html is broken') + +if __name__ == '__main__': + unittest2.main() \ No newline at end of file diff --git a/openerp/tests/test_orm.py b/openerp/tests/test_orm.py index ea9b37e5f3b..bce5bc3903a 100644 --- a/openerp/tests/test_orm.py +++ b/openerp/tests/test_orm.py @@ -1,4 +1,3 @@ -import os import unittest2 import openerp @@ -15,6 +14,10 @@ LINK_TO = lambda id: (4, id, False) DELETE_ALL = lambda: (5, False, False) REPLACE_WITH = lambda ids: (6, False, ids) +def sorted_by_id(list_of_dicts): + "sort dictionaries by their 'id' field; useful for comparisons" + return sorted(list_of_dicts, key=lambda d: d.get('id')) + class TestO2MSerialization(common.TransactionCase): def setUp(self): @@ -23,21 +26,18 @@ class TestO2MSerialization(common.TransactionCase): def test_no_command(self): " empty list of commands yields an empty list of records " - results = self.partner.resolve_o2m_commands_to_record_dicts( + results = self.partner.resolve_2many_commands( self.cr, UID, 'address', []) self.assertEqual(results, []) def test_CREATE_commands(self): " returns the VALUES dict as-is " - results = self.partner.resolve_o2m_commands_to_record_dicts( - self.cr, UID, 'address', - map(CREATE, [{'foo': 'bar'}, {'foo': 'baz'}, {'foo': 'baq'}])) - self.assertEqual(results, [ - {'foo': 'bar'}, - {'foo': 'baz'}, - {'foo': 'baq'} - ]) + values = [{'foo': 'bar'}, {'foo': 'baz'}, {'foo': 'baq'}] + results = self.partner.resolve_2many_commands( + self.cr, UID, 'address', map(CREATE, values)) + + self.assertEqual(results, values) def test_LINK_TO_command(self): " reads the records from the database, records are returned with their ids. " @@ -48,14 +48,14 @@ class TestO2MSerialization(common.TransactionCase): ] commands = map(LINK_TO, ids) - results = self.partner.resolve_o2m_commands_to_record_dicts( + results = self.partner.resolve_2many_commands( self.cr, UID, 'address', commands, ['name']) - self.assertEqual(results, [ + self.assertEqual(sorted_by_id(results), sorted_by_id([ {'id': ids[0], 'name': 'foo'}, {'id': ids[1], 'name': 'bar'}, {'id': ids[2], 'name': 'baz'} - ]) + ])) def test_bare_ids_command(self): " same as the equivalent LINK_TO commands " @@ -65,14 +65,14 @@ class TestO2MSerialization(common.TransactionCase): self.partner.create(self.cr, UID, {'name': 'baz'}) ] - results = self.partner.resolve_o2m_commands_to_record_dicts( + results = self.partner.resolve_2many_commands( self.cr, UID, 'address', ids, ['name']) - self.assertEqual(results, [ + self.assertEqual(sorted_by_id(results), sorted_by_id([ {'id': ids[0], 'name': 'foo'}, {'id': ids[1], 'name': 'bar'}, {'id': ids[2], 'name': 'baz'} - ]) + ])) def test_UPDATE_command(self): " take the in-db records and merge the provided information in " @@ -80,18 +80,32 @@ class TestO2MSerialization(common.TransactionCase): id_bar = self.partner.create(self.cr, UID, {'name': 'bar'}) id_baz = self.partner.create(self.cr, UID, {'name': 'baz', 'city': 'tag'}) - results = self.partner.resolve_o2m_commands_to_record_dicts( + results = self.partner.resolve_2many_commands( self.cr, UID, 'address', [ LINK_TO(id_foo), UPDATE(id_bar, {'name': 'qux', 'city': 'tagtag'}), UPDATE(id_baz, {'name': 'quux'}) ], ['name', 'city']) - self.assertEqual(results, [ + self.assertEqual(sorted_by_id(results), sorted_by_id([ {'id': id_foo, 'name': 'foo', 'city': False}, {'id': id_bar, 'name': 'qux', 'city': 'tagtag'}, {'id': id_baz, 'name': 'quux', 'city': 'tag'} - ]) + ])) + + def test_DELETE_command(self): + " deleted records are not returned at all. " + ids = [ + self.partner.create(self.cr, UID, {'name': 'foo'}), + self.partner.create(self.cr, UID, {'name': 'bar'}), + self.partner.create(self.cr, UID, {'name': 'baz'}) + ] + commands = [DELETE(ids[0]), DELETE(ids[1]), DELETE(ids[2])] + + results = self.partner.resolve_2many_commands( + self.cr, UID, 'address', commands, ['name']) + + self.assertEqual(results, []) def test_mixed_commands(self): ids = [ @@ -99,28 +113,27 @@ class TestO2MSerialization(common.TransactionCase): for name in ['NObar', 'baz', 'qux', 'NOquux', 'NOcorge', 'garply'] ] - results = self.partner.resolve_o2m_commands_to_record_dicts( + results = self.partner.resolve_2many_commands( self.cr, UID, 'address', [ CREATE({'name': 'foo'}), UPDATE(ids[0], {'name': 'bar'}), LINK_TO(ids[1]), - LINK_TO(ids[2]), + DELETE(ids[2]), UPDATE(ids[3], {'name': 'quux',}), UPDATE(ids[4], {'name': 'corge'}), CREATE({'name': 'grault'}), LINK_TO(ids[5]) ], ['name']) - self.assertEqual(results, [ + self.assertEqual(sorted_by_id(results), sorted_by_id([ {'name': 'foo'}, {'id': ids[0], 'name': 'bar'}, {'id': ids[1], 'name': 'baz'}, - {'id': ids[2], 'name': 'qux'}, {'id': ids[3], 'name': 'quux'}, {'id': ids[4], 'name': 'corge'}, {'name': 'grault'}, {'id': ids[5], 'name': 'garply'} - ]) + ])) def test_LINK_TO_pairs(self): "LINK_TO commands can be written as pairs, instead of triplets" @@ -131,43 +144,20 @@ class TestO2MSerialization(common.TransactionCase): ] commands = map(lambda id: (4, id), ids) - results = self.partner.resolve_o2m_commands_to_record_dicts( + results = self.partner.resolve_2many_commands( self.cr, UID, 'address', commands, ['name']) - self.assertEqual(results, [ + self.assertEqual(sorted_by_id(results), sorted_by_id([ {'id': ids[0], 'name': 'foo'}, {'id': ids[1], 'name': 'bar'}, {'id': ids[2], 'name': 'baz'} - ]) + ])) def test_singleton_commands(self): "DELETE_ALL can appear as a singleton" + results = self.partner.resolve_2many_commands( + self.cr, UID, 'address', [DELETE_ALL()], ['name']) - try: - self.partner.resolve_o2m_commands_to_record_dicts( - self.cr, UID, 'address', [(5,)], ['name']) - except AssertionError: - # 5 should fail with an assert error, but not e.g. a ValueError - pass - - def test_invalid_commands(self): - "Commands with uncertain semantics in this context should be forbidden" - - with self.assertRaises(AssertionError): - self.partner.resolve_o2m_commands_to_record_dicts( - self.cr, UID, 'address', [DELETE(42)], ['name']) - - with self.assertRaises(AssertionError): - self.partner.resolve_o2m_commands_to_record_dicts( - self.cr, UID, 'address', [FORGET(42)], ['name']) - - with self.assertRaises(AssertionError): - self.partner.resolve_o2m_commands_to_record_dicts( - self.cr, UID, 'address', [DELETE_ALL()], ['name']) - - with self.assertRaises(AssertionError): - self.partner.resolve_o2m_commands_to_record_dicts( - self.cr, UID, 'address', [REPLACE_WITH([42])], ['name']) - + self.assertEqual(results, []) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tiny_socket.py b/openerp/tiny_socket.py index b4bed83a4c0..b5f5bbccee3 100644 --- a/openerp/tiny_socket.py +++ b/openerp/tiny_socket.py @@ -22,12 +22,15 @@ import socket import cPickle import cStringIO -import marshal import netsvc #.apidoc title: Net-RPC classes +# Pickle protocol version 2 is optimized compared to default (version 0) +PICKLE_PROTOCOL = 2 + + class Myexception(Exception): """ custom exception object store @@ -63,20 +66,19 @@ class mysocket: netsvc.close_socket(self.sock) def mysend(self, msg, exception=False, traceback=None): - msg = cPickle.dumps([msg,traceback]) - self.sock.sendall('%8d%s%s' % (len(msg), exception and "1" or "0", msg)) + msg = cPickle.dumps([msg, traceback], PICKLE_PROTOCOL) + self.sock.sendall('%8d%d%s' % (len(msg), bool(exception), msg)) def myreceive(self): buf='' - while len(buf) < 8: - chunk = self.sock.recv(8 - len(buf)) + while len(buf) < 9: + chunk = self.sock.recv(9 - len(buf)) if not chunk: raise socket.timeout buf += chunk - size = int(buf) - buf = self.sock.recv(1) - if buf != "0": - exception = buf + size = int(buf[:8]) + if buf[8] != "0": + exception = buf[8] else: exception = False msg = '' diff --git a/openerp/tools/amount_to_text_en.py b/openerp/tools/amount_to_text_en.py index 9a1ac939e6b..97d690c70e2 100644 --- a/openerp/tools/amount_to_text_en.py +++ b/openerp/tools/amount_to_text_en.py @@ -88,8 +88,8 @@ def amount_to_text(number, currency): end_word = english_number(int(list[1])) cents_number = int(list[1]) cents_name = (cents_number > 1) and 'Cents' or 'Cent' - final_result = start_word +' '+units_name+' and ' + end_word +' '+cents_name - return final_result + + return ' '.join(filter(None, [start_word, units_name, (start_word or units_name) and (end_word or cents_name) and 'and', end_word, cents_name])) #------------------------------------------------------------- diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index 36f560ba62c..be8465055ee 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -591,7 +591,11 @@ form: module.record_id""" % (xml_id,) if rec.get('action'): a_action = rec.get('action','').encode('utf8') - a_type = rec.get('type','').encode('utf8') or 'act_window' + + # determine the type of action + a_type, a_id = self.model_id_get(cr, a_action) + a_type = a_type.split('.')[-1] # keep only type part + icons = { "act_window": 'STOCK_NEW', "report.xml": 'STOCK_PASTE', @@ -601,8 +605,8 @@ form: module.record_id""" % (xml_id,) "server": 'STOCK_EXECUTE', } values['icon'] = icons.get(a_type,'STOCK_NEW') + if a_type=='act_window': - a_id = self.id_get(cr, a_action) cr.execute('select view_type,view_mode,name,view_id,target from ir_act_window where id=%s', (int(a_id),)) rrres = cr.fetchone() assert rrres, "No window action defined for this id %s !\n" \ @@ -627,9 +631,8 @@ form: module.record_id""" % (xml_id,) values['icon'] = 'STOCK_EXECUTE' if not values.get('name', False): values['name'] = action_name - + elif a_type in ['wizard', 'url', 'client', 'server'] and not values.get('name'): - a_id = self.id_get(cr, a_action) a_table = 'ir_act_%s' % a_type cr.execute('select name from %s where id=%%s' % a_table, (int(a_id),)) resw = cr.fetchone() @@ -667,9 +670,6 @@ form: module.record_id""" % (xml_id,) self.idref[rec_id] = int(pid) if rec.get('action') and pid: - a_action = rec.get('action').encode('utf8') - a_type = rec.get('type','').encode('utf8') or 'act_window' - a_id = self.id_get(cr, a_action) action = "ir.actions.%s,%d" % (a_type, a_id) self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', 'tree_but_open', 'Menuitem', [('ir.ui.menu', int(pid))], action, True, True, xml_id=rec_id) return ('ir.ui.menu', pid) diff --git a/openerp/tools/html_sanitize.py b/openerp/tools/html_sanitize.py index 6763b464ab1..6ea7b90e2ba 100644 --- a/openerp/tools/html_sanitize.py +++ b/openerp/tools/html_sanitize.py @@ -1,62 +1,92 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Business Applications +# Copyright (C) 2012 OpenERP S.A. (<http://openerp.com>). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## +import lxml.html +import operator import re -def html_sanitize(x): - return x # It seems that our test suite doesn't care. - if not x: - return x - root = pq("<div />") - if type(x) == str: - x = unicode(x, "utf8", "replace") - root.html(x) - result = handle_element(root[0]) - new = pq(result) - return new.html() +from openerp.loglevels import ustr +def html_sanitize(src): + if not src: + return src + src = ustr(src, errors='replace') + root = lxml.html.fromstring(u"<div>%s</div>" % src) + result = handle_element(root) + res = [] + for element in children(result[0]): + if isinstance(element, basestring): + res.append(element) + else: + element.tail = "" + res.append(lxml.html.tostring(element)) + return ''.join(res) + +# FIXME: shouldn't this be a whitelist rather than a blacklist?! to_remove = set(["script", "head", "meta", "title", "link", "img"]) to_unwrap = set(["html", "body"]) -javascript_regex = re.compile("""^\s*javascript\s*\:.*$""") +javascript_regex = re.compile(r"^\s*javascript\s*:.*$", re.IGNORECASE) + def handle_a(el, new): href = el.get("href", "#") if javascript_regex.search(href): href = "#" new.set("href", href) + special = { "a": handle_a, } -def handle_element(el): - if type(el) == str or type(el) == unicode: - return [el] - if el.tag in to_remove: +def handle_element(element): + if isinstance(element, basestring): + return [element] + if element.tag in to_remove: return [] - if el.tag in to_unwrap: - return reduce(lambda x,y: x+y, [handle_element(x) for x in children(el)]) - new = pq("<%s />" % el.tag)[0] - for i in children(el): - append_to(handle_element(i), new) - if el.tag in special: - special[el.tag](el, new) - return [new] - -def children(el): + if element.tag in to_unwrap: + return reduce(operator.add, [handle_element(x) for x in children(element)]) + result = lxml.html.fromstring("<%s />" % element.tag) + for c in children(element): + append_to(handle_element(c), result) + if element.tag in special: + special[element.tag](element, result) + return [result] + +def children(node): res = [] - if el.text is not None: - res.append(el.text) - for i in el.getchildren(): - res.append(i) - if i.tail is not None: - res.append(i.tail) + if node.text is not None: + res.append(node.text) + for child_node in node.getchildren(): + res.append(child_node) + if child_node.tail is not None: + res.append(child_node.tail) return res -def append_to(new_ones, el): - for i in new_ones: - if type(i) == str or type(i) == unicode: - children = el.getchildren() +def append_to(elements, dest_node): + for element in elements: + if isinstance(element, basestring): + children = dest_node.getchildren() if len(children) == 0: - el.text = i + dest_node.text = element else: - children[-1].tail = i + children[-1].tail = element else: - el.append(i) + dest_node.append(element) diff --git a/openerp/tools/image.py b/openerp/tools/image.py index 1caafb23a18..f673906f328 100644 --- a/openerp/tools/image.py +++ b/openerp/tools/image.py @@ -20,9 +20,12 @@ ############################################################################## import io -from PIL import Image import StringIO +from PIL import Image +from PIL import ImageFilter +from random import random + # ---------------------------------------- # Image resizing # ---------------------------------------- @@ -47,15 +50,17 @@ def image_resize_image(base64_source, size=(1024, 1024), encoding='base64', file image. - past the thumbnail on the transparent background and center it. - + :param base64_source: base64-encoded version of the source - image + image; if False, returns False :param size: tuple(height, width) :param encoding: the output encoding :param filetype: the output filetype :param avoid_if_small: do not resize if image height and width are smaller than the expected size. """ + if not base64_source: + return False image_stream = io.BytesIO(base64_source.decode(encoding)) image = Image.open(image_stream) # check image size: do not create a thumbnail if avoiding smaller images @@ -63,6 +68,7 @@ def image_resize_image(base64_source, size=(1024, 1024), encoding='base64', file return base64_source # create a thumbnail: will resize and keep ratios image.thumbnail(size, Image.ANTIALIAS) + image = image.filter(ImageFilter.SHARPEN) # create a transparent image for background background = Image.new('RGBA', size, (255, 255, 255, 0)) # past the resized image on the background @@ -72,42 +78,57 @@ def image_resize_image(base64_source, size=(1024, 1024), encoding='base64', file background.save(background_stream, filetype) return background_stream.getvalue().encode(encoding) -def image_resize_image_big(base64_source, size=(1204, 1204), encoding='base64', filetype='PNG'): +def image_resize_image_big(base64_source, size=(1204, 1204), encoding='base64', filetype='PNG', avoid_if_small=True): """ Wrapper on image_resize_image, to resize images larger than the standard 'big' image size: 1024x1024px. - :param base64_source: base64 encoded source image. If False, - the function returns False. + :param size, encoding, filetype, avoid_if_small: refer to image_resize_image """ - if not base64_source: - return False - return image_resize_image(base64_source, size, encoding, filetype, True) + return image_resize_image(base64_source, size, encoding, filetype, avoid_if_small) -def image_resize_image_medium(base64_source, size=(180, 180), encoding='base64', filetype='PNG'): +def image_resize_image_medium(base64_source, size=(128, 128), encoding='base64', filetype='PNG', avoid_if_small=False): """ Wrapper on image_resize_image, to resize to the standard 'medium' image size: 180x180. - :param base64_source: base64 encoded source image. If False, - the function returns False. + :param size, encoding, filetype, avoid_if_small: refer to image_resize_image """ - if not base64_source: - return False - return image_resize_image(base64_source, size, encoding, filetype) - -def image_resize_image_small(base64_source, size=(50, 50), encoding='base64', filetype='PNG'): + return image_resize_image(base64_source, size, encoding, filetype, avoid_if_small) + +def image_resize_image_small(base64_source, size=(64, 64), encoding='base64', filetype='PNG', avoid_if_small=False): """ Wrapper on image_resize_image, to resize to the standard 'small' image size: 50x50. - :param base64_source: base64 encoded source image. If False, - the function returns False. + :param size, encoding, filetype, avoid_if_small: refer to image_resize_image """ - if not base64_source: - return False - return image_resize_image(base64_source, size, encoding, filetype) + return image_resize_image(base64_source, size, encoding, filetype, avoid_if_small) + +# ---------------------------------------- +# Colors +# --------------------------------------- + +def image_colorize(original, randomize=True, color=(255, 255, 255)): + """ Add a color to the transparent background of an image. + :param original: file object on the original image file + :param randomize: randomize the background color + :param color: background-color, if not randomize + """ + # create a new image, based on the original one + original = Image.open(io.BytesIO(original)) + image = Image.new('RGB', original.size) + # generate the background color, past it as background + if randomize: + color = (int(random() * 192 + 32), int(random() * 192 + 32), int(random() * 192 + 32)) + image.paste(color) + image.paste(original, mask=original) + # return the new image + buffer = StringIO.StringIO() + image.save(buffer, 'PNG') + return buffer.getvalue() # ---------------------------------------- # Misc image tools # --------------------------------------- def image_get_resized_images(base64_source, return_big=False, return_medium=True, return_small=True, - big_name='image', medium_name='image_medium', small_name='image_small'): + big_name='image', medium_name='image_medium', small_name='image_small', + avoid_resize_big=True, avoid_resize_medium=False, avoid_resize_small=False): """ Standard tool function that returns a dictionary containing the big, medium and small versions of the source image. This function is meant to be used for the methods of functional fields for @@ -116,24 +137,22 @@ def image_get_resized_images(base64_source, return_big=False, return_medium=True Default parameters are given to be used for the getter of functional image fields, for example with res.users or res.partner. It returns only image_medium and image_small values, to update those fields. - - :param base64_source: if set to False, other values are set to False - also. The purpose is to be linked to the fields that hold images in - OpenERP and that are binary fields. - :param return_big: if set, return_dict contains the 'big_name' entry - :param return_medium: if set, return_dict contains the 'medium_name' entry - :param return_small: if set, return_dict contains the 'small_name' entry - :param big_name: name related to the big version of the image; - 'image' by default. - :param medium_name: name related to the medium version of the - image; 'image_medium' by default. - :param small_name: name related to the small version of the - image; 'image_small' by default. + + :param base64_source: base64-encoded version of the source + image; if False, all returnes values will be False + :param return_{..}: if set, computes and return the related resizing + of the image + :param {..}_name: key of the resized image in the return dictionary; + 'image', 'image_medium' and 'image_small' by default. + :param avoid_resize_[..]: see avoid_if_small parameter :return return_dict: dictionary with resized images, depending on previous parameters. """ return_dict = dict() - if return_big: return_dict[big_name] = image_resize_image_big(base64_source) - if return_medium: return_dict[medium_name] = image_resize_image_medium(base64_source) - if return_small: return_dict[small_name] = image_resize_image_small(base64_source) - return return_dict \ No newline at end of file + if return_big: + return_dict[big_name] = image_resize_image_big(base64_source, avoid_if_small=avoid_resize_big) + if return_medium: + return_dict[medium_name] = image_resize_image_medium(base64_source, avoid_if_small=avoid_resize_medium) + if return_small: + return_dict[small_name] = image_resize_image_small(base64_source, avoid_if_small=avoid_resize_small) + return return_dict diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index e90fadf0492..9a7b3499425 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -134,7 +134,7 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False): @param name name of the file @param mode file open mode @param subdir subdirectory - @param pathinfo if True returns tupple (fileobject, filepath) + @param pathinfo if True returns tuple (fileobject, filepath) @return fileobject if pathinfo is False else (fileobject, filepath) """ @@ -142,44 +142,60 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False): adps = addons.module.ad_paths rtp = os.path.normcase(os.path.abspath(config['root_path'])) - if name.replace(os.path.sep, '/').startswith('addons/'): + if os.path.isabs(name): + # It is an absolute path + # Is it below 'addons_path' or 'root_path'? + name = os.path.normcase(os.path.normpath(name)) + for root in adps + [rtp]: + if name.startswith(root): + base = root.rstrip(os.sep) + name = name[len(base) + 1:] + break + else: + # It is outside the OpenERP root: skip zipfile lookup. + base, name = os.path.split(name) + return _fileopen(name, mode=mode, basedir=base, pathinfo=pathinfo) + + if name.replace(os.sep, '/').startswith('addons/'): subdir = 'addons' - name = name[7:] + name2 = name[7:] + elif subdir: + name = os.path.join(subdir, name) + if name.replace(os.sep, '/').startswith('addons/'): + subdir = 'addons' + name2 = name[7:] + else: + name2 = name - # First try to locate in addons_path + # First, try to locate in addons_path if subdir: - subdir2 = subdir - if subdir2.replace(os.path.sep, '/').startswith('addons/'): - subdir2 = subdir2[7:] - - subdir2 = (subdir2 != 'addons' or None) and subdir2 - for adp in adps: try: - if subdir2: - fn = os.path.join(adp, subdir2, name) - else: - fn = os.path.join(adp, name) - fn = os.path.normpath(fn) - fo = file_open(fn, mode=mode, subdir=None, pathinfo=pathinfo) - if pathinfo: - return fo, fn - return fo + return _fileopen(name2, mode=mode, basedir=adp, + pathinfo=pathinfo) except IOError: pass - if subdir: - name = os.path.join(rtp, subdir, name) - else: - name = os.path.join(rtp, name) + # Second, try to locate in root_path + return _fileopen(name, mode=mode, basedir=rtp, pathinfo=pathinfo) - name = os.path.normpath(name) - # Check for a zipfile in the path - head = name +def _fileopen(path, mode, basedir, pathinfo): + name = os.path.normpath(os.path.join(basedir, path)) + # Give higher priority to module directories, which is + # a more common case than zipped modules. + if os.path.isfile(name): + fo = open(name, mode) + if pathinfo: + return (fo, name) + return fo + + # Support for loading modules in zipped form. + # This will not work for zipped modules that are sitting + # outside of known addons paths. + head = os.path.normpath(path) zipname = False - name2 = False - while True: + while os.sep in head: head, tail = os.path.split(head) if not tail: break @@ -187,9 +203,10 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False): zipname = os.path.join(tail, zipname) else: zipname = tail - if zipfile.is_zipfile(head+'.zip'): + zpath = os.path.join(basedir, head + '.zip') + if zipfile.is_zipfile(zpath): from cStringIO import StringIO - zfile = zipfile.ZipFile(head+'.zip') + zfile = zipfile.ZipFile(zpath) try: fo = StringIO() fo.write(zfile.read(os.path.join( @@ -197,20 +214,14 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False): os.sep, '/'))) fo.seek(0) if pathinfo: - return fo, name + return (fo, name) return fo except Exception: - name2 = os.path.normpath(os.path.join(head + '.zip', zipname)) pass - for i in (name2, name): - if i and os.path.isfile(i): - fo = file(i, mode) - if pathinfo: - return fo, i - return fo - if os.path.splitext(name)[1] == '.rml': - raise IOError, 'Report %s doesn\'t exist or deleted : ' %str(name) - raise IOError, 'File not found : %s' % name + # Not found + if name.endswith('.rml'): + raise IOError('Report %r doesn\'t exist or deleted' % name) + raise IOError('File not found: %s' % name) #---------------------------------------------------------- @@ -395,6 +406,42 @@ def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=Non cr.close() return res +def email_split(text): + """ Return a list of the email addresses found in ``text`` """ + if not text: return [] + return re.findall(r'([^ ,<@]+@[^> ,]+)', text) + +def append_content_to_html(html, content, plaintext=True): + """Append extra content at the end of an HTML snippet, trying + to locate the end of the HTML document (</body>, </html>, or + EOF), and wrapping the provided content in a <pre/> block + unless ``plaintext`` is False. A side-effect of this + method is to coerce all HTML tags to lowercase in ``html``, + and strip enclosing <html> or <body> tags in content if + ``plaintext`` is False. + + :param str html: html tagsoup (doesn't have to be XHTML) + :param str content: extra content to append + :param bool plaintext: whether content is plaintext and should + be wrapped in a <pre/> tag. + """ + html = ustr(html) + if plaintext: + content = u'\n<pre>%s</pre>\n' % ustr(content) + else: + content = re.sub(r'(?i)(</?html.*>|</?body.*>|<!\W*DOCTYPE.*>)', '', content) + content = u'\n%s\n'% ustr(content) + # Force all tags to lowercase + html = re.sub(r'(</?)\W*(\w+)([ >])', + lambda m: '%s%s%s' % (m.group(1),m.group(2).lower(),m.group(3)), html) + insert_location = html.find('</body>') + if insert_location == -1: + insert_location = html.find('</html>') + if insert_location == -1: + return '%s%s' % (html, content) + return '%s%s%s' % (html[:insert_location], content, html[insert_location:]) + + #---------------------------------------------------------- # SMS #---------------------------------------------------------- @@ -1140,4 +1187,37 @@ class UnquoteEvalContext(defaultdict): def __missing__(self, key): return unquote(key) + +class mute_logger(object): + """Temporary suppress the logging. + Can be used as context manager or decorator. + + @mute_logger('openerp.plic.ploc') + def do_stuff(): + blahblah() + + with mute_logger('openerp.foo.bar'): + do_suff() + + """ + def __init__(self, *loggers): + self.loggers = loggers + + def filter(self, record): + return 0 + + def __enter__(self): + for logger in self.loggers: + logging.getLogger(logger).addFilter(self) + + def __exit__(self, exc_type=None, exc_val=None, exc_tb=None): + for logger in self.loggers: + logging.getLogger(logger).removeFilter(self) + + def __call__(self, func): + @wraps(func) + def deco(*args, **kwargs): + with self: + return func(*args, **kwargs) + return deco # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index cdb9716e43d..93034b92f67 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -43,6 +43,7 @@ import misc from misc import UpdateableStr from misc import SKIPPED_ELEMENT_TYPES import osutil +from openerp import SUPERUSER_ID _logger = logging.getLogger(__name__) @@ -214,7 +215,7 @@ class GettextAlias(object): if cr: # Try to use ir.translation to benefit from global cache if possible pool = pooler.get_pool(cr.dbname) - res = pool.get('ir.translation')._get_source(cr, 1, None, ('code','sql_constraint'), lang, source) + res = pool.get('ir.translation')._get_source(cr, SUPERUSER_ID, None, ('code','sql_constraint'), lang, source) else: _logger.debug('no context cursor detected, skipping translation for "%r"', source) else: @@ -879,7 +880,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, if not ids: # lets create the language with locale information - lang_obj.load_lang(cr, 1, lang=lang, lang_name=lang_name) + lang_obj.load_lang(cr, SUPERUSER_ID, lang=lang, lang_name=lang_name) # now, the serious things: we read the language file @@ -910,15 +911,15 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, # dictionary which holds values for this line of the csv file # {'lang': ..., 'type': ..., 'name': ..., 'res_id': ..., # 'src': ..., 'value': ..., 'module':...} - dic = {'lang': lang} - dic_module = False - for i in range(len(f)): - if f[i] in ('module',): + dic = dict.fromkeys(('name', 'res_id', 'src', 'type', 'imd_model', 'imd_name', 'module', 'value')) + dic['lang'] = lang + for i, field in enumerate(f): + if field == 'module': continue - dic[f[i]] = row[i] + dic[field] = row[i] # This would skip terms that fail to specify a res_id - if not dic.get('res_id', False): + if not dic.get('res_id'): continue res_id = dic.pop('res_id') @@ -927,21 +928,16 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, dic['res_id'] = int(res_id) dic['module'] = module_name else: - try: - tmodel = dic['name'].split(',')[0] - if '.' in res_id: - tmodule, tname = res_id.split('.', 1) - else: - tmodule = dic_module - tname = res_id - dic['imd_model'] = tmodel - dic['module'] = tmodule - dic['imd_name'] = tname - dic['res_id'] = None - except Exception: - _logger.warning("Could not decode resource for %s, please fix the po file.", - dic['res_id'], exc_info=True) - dic['res_id'] = None + tmodel = dic['name'].split(',')[0] + if '.' in res_id: + tmodule, tname = res_id.split('.', 1) + else: + tmodule = False + tname = res_id + dic['imd_model'] = tmodel + dic['imd_name'] = tname + dic['module'] = tmodule + dic['res_id'] = None irt_cursor.push(dic) diff --git a/openerp/tools/yaml_import.py b/openerp/tools/yaml_import.py index 136d1bcee7b..f487070fea0 100644 --- a/openerp/tools/yaml_import.py +++ b/openerp/tools/yaml_import.py @@ -13,6 +13,7 @@ import yaml_tag import yaml import re from lxml import etree +from openerp import SUPERUSER_ID # YAML import needs both safe and unsafe eval, but let's # default to /safe/. @@ -100,7 +101,7 @@ class RecordDictWrapper(dict): return dict.__getitem__(self, key) class YamlInterpreter(object): - def __init__(self, cr, module, id_map, mode, filename, report=None, noupdate=False): + def __init__(self, cr, module, id_map, mode, filename, report=None, noupdate=False, loglevel=logging.DEBUG): self.cr = cr self.module = module self.id_map = id_map @@ -110,6 +111,7 @@ class YamlInterpreter(object): report = assertion_report.assertion_report() self.assertion_report = report self.noupdate = noupdate + self.loglevel = loglevel self.pool = pooler.get_pool(cr.dbname) self.uid = 1 self.context = {} # opererp context @@ -119,6 +121,9 @@ class YamlInterpreter(object): 'datetime': datetime, 'timedelta': timedelta} + def _log(self, *args, **kwargs): + _logger.log(self.loglevel, *args, **kwargs) + def _ref(self): return lambda xml_id: self.get_id(xml_id) @@ -282,20 +287,20 @@ class YamlInterpreter(object): view_id = record.view if view_id and (view_id is not True): - view_id = self.pool.get('ir.model.data').get_object_reference(self.cr, 1, self.module, record.view)[1] + view_id = self.pool.get('ir.model.data').get_object_reference(self.cr, SUPERUSER_ID, self.module, record.view)[1] if model.is_transient(): record_dict=self.create_osv_memory_record(record, fields) else: self.validate_xml_id(record.id) try: - self.pool.get('ir.model.data')._get_id(self.cr, 1, self.module, record.id) + self.pool.get('ir.model.data')._get_id(self.cr, SUPERUSER_ID, self.module, record.id) default = False except ValueError: default = True if self.isnoupdate(record) and self.mode != 'init': - id = self.pool.get('ir.model.data')._update_dummy(self.cr, 1, record.model, self.module, record.id) + id = self.pool.get('ir.model.data')._update_dummy(self.cr, SUPERUSER_ID, record.model, self.module, record.id) # check if the resource already existed at the last update if id: self.id_map[record] = int(id) @@ -311,12 +316,12 @@ class YamlInterpreter(object): if view_id: varg = view_id if view_id is True: varg = False - view = model.fields_view_get(self.cr, 1, varg, 'form', context) + view = model.fields_view_get(self.cr, SUPERUSER_ID, varg, 'form', context) view_id = etree.fromstring(view['arch'].encode('utf-8')) record_dict = self._create_record(model, fields, view_id, default=default) _logger.debug("RECORD_DICT %s" % record_dict) - id = self.pool.get('ir.model.data')._update(self.cr, 1, record.model, \ + id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, record.model, \ self.module, record_dict, record.id, noupdate=self.isnoupdate(record), mode=self.mode, context=context) self.id_map[record.id] = int(id) if config.get('import_partial'): @@ -324,8 +329,8 @@ class YamlInterpreter(object): def _create_record(self, model, fields, view=False, parent={}, default=True): if view is not False: - defaults = default and model._add_missing_default_values(self.cr, 1, {}, context=self.context) or {} - fg = model.fields_get(self.cr, 1, context=self.context) + defaults = default and model._add_missing_default_values(self.cr, SUPERUSER_ID, {}, context=self.context) or {} + fg = model.fields_get(self.cr, SUPERUSER_ID, context=self.context) else: defaults = {} fg = {} @@ -356,7 +361,7 @@ class YamlInterpreter(object): if (view is not False) and (fg[field_name]['type']=='one2many'): view2 = view.find("field[@name='%s']/form"%(field_name,)) if not view2: - view2 = self.pool.get(fg[field_name]['relation']).fields_view_get(self.cr, 1, False, 'form', self.context) + view2 = self.pool.get(fg[field_name]['relation']).fields_view_get(self.cr, SUPERUSER_ID, False, 'form', self.context) view2 = etree.fromstring(view2['arch'].encode('utf-8')) field_value = self._eval_field(model, field_name, fields[field_name], view2, parent=record_dict, default=default) @@ -391,7 +396,7 @@ class YamlInterpreter(object): # Evaluation args args = map(lambda x: eval(x, ctx), match.group(2).split(',')) - result = getattr(model, match.group(1))(self.cr, 1, [], *args) + result = getattr(model, match.group(1))(self.cr, SUPERUSER_ID, [], *args) for key, val in (result or {}).get('value', {}).items(): if key not in fields: assert key in fg, "The returning field '%s' from your on_change call '%s' does not exist on the object '%s'" % (key, match.group(1), model._name) @@ -484,12 +489,10 @@ class YamlInterpreter(object): self.noupdate = node.noupdate def process_python(self, node): - def log(msg, *args): - _logger.log(logging.TEST, msg, *args) python, statements = node.items()[0] model = self.get_model(python.model) statements = statements.replace("\r\n", "\n") - code_context = {'model': model, 'cr': self.cr, 'uid': self.uid, 'log': log, 'context': self.context} + code_context = { 'model': model, 'cr': self.cr, 'uid': self.uid, 'log': self._log, 'context': self.context } code_context.update({'self': model}) # remove me when no !python block test uses 'self' anymore try: code_obj = compile(statements, self.filename, 'exec') @@ -653,7 +656,7 @@ class YamlInterpreter(object): self._set_group_values(node, values) - pid = self.pool.get('ir.model.data')._update(self.cr, 1, \ + pid = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, \ 'ir.ui.menu', self.module, values, node.id, mode=self.mode, \ noupdate=self.isnoupdate(node), res_id=res and res[0] or False) @@ -664,7 +667,7 @@ class YamlInterpreter(object): action_type = node.type or 'act_window' action_id = self.get_id(node.action) action = "ir.actions.%s,%d" % (action_type, action_id) - self.pool.get('ir.model.data').ir_set(self.cr, 1, 'action', \ + self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', \ 'tree_but_open', 'Menuitem', [('ir.ui.menu', int(parent_id))], action, True, True, xml_id=node.id) def process_act_window(self, node): @@ -698,7 +701,7 @@ class YamlInterpreter(object): if node.target: values['target'] = node.target - id = self.pool.get('ir.model.data')._update(self.cr, 1, \ + id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, \ 'ir.actions.act_window', self.module, values, node.id, mode=self.mode) self.id_map[node.id] = int(id) @@ -706,7 +709,7 @@ class YamlInterpreter(object): keyword = 'client_action_relate' value = 'ir.actions.act_window,%s' % id replace = node.replace or True - self.pool.get('ir.model.data').ir_set(self.cr, 1, 'action', keyword, \ + self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', keyword, \ node.id, [node.src_model], value, replace=replace, noupdate=self.isnoupdate(node), isobject=True, xml_id=node.id) # TODO add remove ir.model.data @@ -720,14 +723,14 @@ class YamlInterpreter(object): if len(ids): self.pool.get(node.model).unlink(self.cr, self.uid, ids) else: - _logger.log(logging.TEST, "Record not deleted.") + self._log("Record not deleted.") def process_url(self, node): self.validate_xml_id(node.id) res = {'name': node.name, 'url': node.url, 'target': node.target} - id = self.pool.get('ir.model.data')._update(self.cr, 1, \ + id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, \ "ir.actions.url", self.module, res, node.id, mode=self.mode) self.id_map[node.id] = int(id) # ir_set @@ -735,7 +738,7 @@ class YamlInterpreter(object): keyword = node.keyword or 'client_action_multi' value = 'ir.actions.url,%s' % id replace = node.replace or True - self.pool.get('ir.model.data').ir_set(self.cr, 1, 'action', \ + self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', \ keyword, node.url, ["ir.actions.url"], value, replace=replace, \ noupdate=self.isnoupdate(node), isobject=True, xml_id=node.id) @@ -750,7 +753,7 @@ class YamlInterpreter(object): else: value = expression res[fieldname] = value - self.pool.get('ir.model.data').ir_set(self.cr, 1, res['key'], res['key2'], \ + self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, res['key'], res['key2'], \ res['name'], res['models'], res['value'], replace=res.get('replace',True), \ isobject=res.get('isobject', False), meta=res.get('meta',None)) @@ -779,7 +782,7 @@ class YamlInterpreter(object): self._set_group_values(node, values) - id = self.pool.get('ir.model.data')._update(self.cr, 1, "ir.actions.report.xml", \ + id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, "ir.actions.report.xml", \ self.module, values, xml_id, noupdate=self.isnoupdate(node), mode=self.mode) self.id_map[xml_id] = int(id) @@ -787,7 +790,7 @@ class YamlInterpreter(object): keyword = node.keyword or 'client_print_multi' value = 'ir.actions.report.xml,%s' % id replace = node.replace or True - self.pool.get('ir.model.data').ir_set(self.cr, 1, 'action', \ + self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', \ keyword, values['name'], [values['model']], value, replace=replace, isobject=True, xml_id=xml_id) def process_none(self): @@ -805,11 +808,9 @@ class YamlInterpreter(object): is_preceded_by_comment = False for node in yaml.load(yaml_string): - is_preceded_by_comment = self._log(node, is_preceded_by_comment) + is_preceded_by_comment = self._log_node(node, is_preceded_by_comment) try: self._process_node(node) - except YamlImportException, e: - _logger.exception(e) except Exception, e: _logger.exception(e) raise @@ -852,26 +853,27 @@ class YamlInterpreter(object): else: raise YamlImportException("Can not process YAML block: %s" % node) - def _log(self, node, is_preceded_by_comment): + def _log_node(self, node, is_preceded_by_comment): if is_comment(node): is_preceded_by_comment = True - _logger.log(logging.TEST, node) + self._log(node) elif not is_preceded_by_comment: if isinstance(node, types.DictionaryType): msg = "Creating %s\n with %s" args = node.items()[0] - _logger.log(logging.TEST, msg, *args) + self._log(msg, *args) else: - _logger.log(logging.TEST, node) + self._log(node) else: is_preceded_by_comment = False return is_preceded_by_comment -def yaml_import(cr, module, yamlfile, idref=None, mode='init', noupdate=False, report=None): +def yaml_import(cr, module, yamlfile, kind, idref=None, mode='init', noupdate=False, report=None): if idref is None: idref = {} + loglevel = logging.TEST if kind == 'test' else logging.DEBUG yaml_string = yamlfile.read() - yaml_interpreter = YamlInterpreter(cr, module, idref, mode, filename=yamlfile.name, report=report, noupdate=noupdate) + yaml_interpreter = YamlInterpreter(cr, module, idref, mode, filename=yamlfile.name, report=report, noupdate=noupdate, loglevel=loglevel) yaml_interpreter.process(yaml_string) # keeps convention of convert.py diff --git a/openerp/wizard/__init__.py b/openerp/wizard/__init__.py index 7354a43498d..debf0f1e74f 100644 --- a/openerp/wizard/__init__.py +++ b/openerp/wizard/__init__.py @@ -31,7 +31,6 @@ import openerp.pooler as pooler from openerp.osv.osv import except_osv from openerp.osv.orm import except_orm -import sys _logger = logging.getLogger(__name__) @@ -168,10 +167,7 @@ class interface(netsvc.Service): or isinstance(e, except_orm): netsvc.abort_response(2, e.name, 'warning', e.value) else: - import traceback - tb_s = reduce(lambda x, y: x+y, traceback.format_exception( - sys.exc_type, sys.exc_value, sys.exc_traceback)) - _logger.error('Exception in call: ' + tb_s) + _logger.exception('Exception in call:') raise return res diff --git a/scripts/run_all_with_tests.sh b/scripts/run_all_with_tests.sh new file mode 100755 index 00000000000..877a5908b1a --- /dev/null +++ b/scripts/run_all_with_tests.sh @@ -0,0 +1,17 @@ +DATABASE=trunk +dropdb ${DATABASE} +REPOSITORIES=../../addons/trunk +MODULES=`python -c "import os; print ','.join(list(set(os.listdir('${REPOSITORIES}')) - set(['document_ftp'])))"` +createdb ${DATABASE} +rm openerp-server.log +./openerp-server \ + --log-level=debug \ + --addons=${REPOSITORIES},../../web/trunk/addons \ + -d ${DATABASE} \ + -i ${MODULES} \ + --stop-after-init \ + --no-xmlrpc \ + --no-xmlrpcs \ + --no-netrpc \ + --test-enable \ + --logfile=openerp-server.log diff --git a/setup.py b/setup.py index 6e1adadde82..a26b74e255d 100755 --- a/setup.py +++ b/setup.py @@ -87,18 +87,15 @@ setuptools.setup( scripts = ['openerp-server'], data_files = data(), packages = setuptools.find_packages(), + dependency_links = ['http://download.gna.org/pychart/'], #include_package_data = True, install_requires = [ - # TODO the pychart package we include in openerp corresponds to PyChart 1.37. - # It seems there is a single difference, which is a spurious print in generate_docs.py. - # It is probably safe to move to PyChart 1.39 (the latest one). - # (Let setup.py choose the latest one, and we should check we can remove pychart from - # our tree.) http://download.gna.org/pychart/ - # TODO 'pychart', + 'pychart', 'babel', + 'docutils', 'feedparser', 'gdata', - 'lxml', + 'lxml < 3', 'mako', 'psycopg2', 'pydot',