././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1745680201.873057 trytond-7.0.30/0000755000175000017500000000000015003173512011411 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1745680198.0 trytond-7.0.30/CHANGELOG0000644000175000017500000012433215003173506012633 0ustar00cedced Version 7.0.30 - 2025-04-26 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.29 - 2025-04-02 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.28 - 2025-03-15 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.27 - 2025-03-04 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.26 - 2025-02-16 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.25 - 2025-02-01 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.24 - 2025-01-16 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.23 - 2025-01-01 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.22 - 2024-12-16 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.21 - 2024-12-01 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.20 - 2024-10-18 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.19 - 2024-10-05 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.18 - 2024-09-16 --------------------------- * Bug fixes (see mercurial logs for details) * Retrieve groups of actions without checking access (#13506) * Check read access of report records (#13505) Version 7.0.17 - 2024-09-01 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.16 - 2024-08-01 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.15 - 2024-07-17 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.14 - 2024-07-01 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.13 - 2024-06-15 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.12 - 2024-06-02 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.11 - 2024-05-01 --------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.10 - 2024-04-17 --------------------------- * Bug fixes (see mercurial logs for details) * Do not accept compressed content from unauthenticated request (#13142) Version 7.0.9 - 2024-04-04 -------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.8 - 2024-03-03 -------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.7 - 2024-02-15 -------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.6 - 2024-02-03 -------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.5 - 2024-01-15 -------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.4 - 2024-01-01 -------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.3 - 2023-12-16 -------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.2 - 2023-12-01 -------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.1 - 2023-11-17 -------------------------- * Bug fixes (see mercurial logs for details) Version 7.0.0 - 2023-10-30 -------------------------- * Bug fixes (see mercurial logs for details) * Add pairwise_longest tools * Add support for Python 3.12 * Support default values for autocomplete * Support default value from context * Add autocomplete method on ModelView * Add likify tools * Remove user from contextual key of Cache * Remove user from evaluation context of rule domain * Allow customizing context per model for rule * Use multiple jobs to dump and restore a test database * Support database cache as template for tests * Add route test case * Add on_scan_code method on Model * Support add/update/remove/delete for on_change_with of xxx2Many * Add decorator on RPC * Remove translations with empty source * Run doc tests with different globals * Create user applications as validated from user preferences * Support GIN index with btree_gin PostgreSQL extension * Add a canonicalize function for domains * Enforce record rules when reading only non SQL fields (#12428) * Support PYSON comparison of timedelta * Support encoding timedelta into PYSON TimeDelta * Allow date formating in sequences substitutions * Make ModelSQL based on table query read only by default * Add email validation tools * Remove overlapping indexes * Support subset operator between index definitions * Add sum_tree helper * Convert sum attribute into boolean * Store records selection on export Version 6.8.0 - 2023-05-01 -------------------------- * Bug fixes (see mercurial logs for details) * Support return instances for Function getter and on_change_with * Log events for ModelStorage * Use IDENTITY column for id columns in the postgresql backend * Use no breaking space to format number and date * Fallback to code to format currency without symbol * Add sort method to order like ModelStorage.search * Do not alter argument values of with_transaction decorator (#12108) * Support SMALLINT and REAL as backend types * Remove BigInteger field * Remove support for Python 3.7 * Add support for Python 3.11 * Add scroll time for calendar view * Allow cache size to be configured * Add local and global list of ignore context keys * Add functions in transaction for check access and active record * Add check_access and active_records attribute to Transaction * Add searchable and sortable methods on Field * Add support for barcode and QR code * Support reading string value of selection fields * Add ButtonActionException and RPCReturnException * Rename ModelStorage.count into ModelStorage.estimated_count * Add border type to images * Lock table on transaction start * Use EXISTS for search on O2M with many records * Replace target_search by use of count() * Manage domain on id in single value list as unique * Do not validate domain for empty fields * Warn about implicit save() of unsaved relation * Raise error message with record name and field in check_xml_record * Cache RPC call for class method selection Version 6.6.0 - 2022-10-31 -------------------------- * Bug fixes (see mercurial logs for details) * Add sql_id method to Reference field * Use declarative index definition for ModelSQL * Add configuration entries for unaccent and similarity functions * Add authentication services * Schedule actions using server timezone * Reset the user sessions less often * Add straight values to wizard state view * Add strip option to Char fields * Strip only one wildcard * Manage web extension origin as null * Remove same types restriction on PYSON If * Allow PYSON size of fields to be None * Add command line completion with argcomplete * Include record name and value in validation error message * Add header parameter on export data * Enforce certificate validation for SMTP connection (issue11564) * Use singleton for TableHandler Version 6.4.0 - 2022-05-02 -------------------------- * Bug fixes (see mercurial logs for details) * Use unittest discover * Add module tutorial * Test all XML view and SVG icon files are used * Add notification message * Add validate_fields to ModelStorage * Drop support for PyPy and psycopg2cffi * Use a set for field's depends * Relax the constraint on a field's depends * Include only needed fields when fetching a view definition * Make warning check re-entrant * Manage DatabaseDataError in ModelSQL * Remove support for pysqlite2 * Do not import empty One2Many data * Deduplicate entries in domain inversion's simplify * Prevent to create and delete singleton * Allow CORS on root path * Allow button access to be deactivated * Always return tuple for MultiSelection * Use default selectors instead of select * Add batch option to push queue tasks * Support ref value for reference field * Enforce ref model in XML data * Do not resolve entities by default with lxml (issue11219) * Use defusedxml to parse XML (issue11244) * Use dictionary as search_order on Reference field * Retry sending email on temporary failure * Order not sorted Selection by index definition * Add optional column on tree view * Use dictionary as domain on Reference field * Include model, field and column in import data error message * Support limit and offset to ModelSQL count search and search_count * Apply view inheritance to board * Add RPC view_get method to View * Apply view inheritance to all matching elements * Limit board action domain to active id and ids * Remove entropy check on password * Set view_id in the context when calling view_attributes * Add ip_address and device_cookie login method options * Add support for Python 3.10 * Remove support for Python 3.6 * Add creatable attribute on tree and form views * Fill local cache of Function field instances with values * Cache Function field getter without context in readonly transactions * Use expire delay instead of UTC datetime in reset password email * Use RENAME and DROP COLUMN with SQLite backend * Support window functions with SQLite backend * Use JSONB to store Dict field on PostgreSQL backend Version 6.2.0 - 2021-11-01 -------------------------- * Bug fixes (see mercurial logs for details) * Allow to cast to date with timezone * Support create/delete attribute in view * Skip default values when copying records * Use local cache for relation fields in readonly transactions * Add format method to DictSchemaMixin * Allow modify record name on the reports * Add methods to format number and symbol on Lang * Add format number with symbol on Report * Allow locking tables by calling ModelSQL.lock without records * Add test on domain of relation fields * Add stored path as alternative to MPTT * Activate and upgrade modules from configuration wizard * Add set_from_header in email tools * Add grouping attribute to numeric widgets * Ensure with a test that objects in the Pool have __slots__ * Use bigdecimal tag for XML-RPC * Use tuple in Dict value instead of list * Do not set record name on title of report get_email * Add node to id of status * Use ImmutableDict for Transaction context * Use UNION for 'Or'-ed domain with subqueries * Add remove_forbidden_chars in tools * Manage errors during non-interactive operations * Add estimation count to ModelStorage * Support empty digits in format_number of Report * Add digits mixin * Use argon2 or scrypt to hash password by default * Allow PYSON Expression as key for PYSON In with dict object * Add method to format warning name with records * Add option to trytond-console to start a readonly transaction * Add support for werkzeug 2.0 * Combine search and get_keys in DictSchemaMixin * Make language code unique * Support base64 encoded data in ModelStorage.import_data * Add BOOL_AND and BOOL_OR to SQLite backend Version 6.0.0 - 2021-05-03 -------------------------- * Bug fixes (see mercurial logs for details) * Allow column sql types to be tested from the table handler * Add support for database connection parameters to configuration URI * Use immutable datastructures for Dict and MultiSelection fields * Skip warnings for non-interactive operations * Check rule only if _check_access is set * Add statistics to Cache * Add support for avatars * Add status command * Add document widget on form view * Add full text and similarity search and FullText field * Add URL type to icon * Use instance method to get next sequence value * Store the sequence type directly on sequence * Allow sending email with record's attachments * Add which records to use for actions * Add parent to group to inherit accesses * Add __access__ to Model * Add route wrapper to allow null origin * Add header grouping on report * Protect trusted devices against brute force attack * Make ModelView.parse_view public * Add help for each value to selection and multiselection * Use safe_join in SharedDataMiddlewareIndex (issue10068) * Use menu name for window opened from menu * Add trigonometric functions to sqlite backend * Allow skipping user warnings globally * Add validate option to trytond-admin * Refresh pool of other processes * Add clear_all method to Cache * Support Genshi element directives in HTML editor * Add firstline tool * Add support for Python 3.9 * Skip access check on ModelStorage instances * Eager load Function field with same multiple getter * Support other methods for button_change decorator * Allow copying Python instances of Model * Add all buttons to default form view * Unify PYSON string format * Forbid all white spaces except space in Char field Version 5.8.0 - 2020-11-02 -------------------------- * Bug fixes (see mercurial logs for details) * Remove support for Python 3.5 * Support import of timedelta data * Add symbol widget * Add sql_pairing tool * Add format_datetime to Report * Allow sharing view searches * Allow overriding digits in Lang.currency and Report.format_currency * Add record name in report filename * Add deletable and writable state from ir.rule to read * Add language attribute to data tag * Add e-mail template * Send e-mail on behalf of user * Register mixins to generic Report class * Cache in memory the report template instances * Support Genshi's MsgDirective in report * Support PYSON comparison of date and datetime * Add cron task to clean old queue tasks * Add option to run cron once * Add defaults option to route * Add escape_wildcard in tools * Add option to ensure emails are sent * Allow keyword action for all models * Add sortable_values in tools * Remove default colors on graph and calendar * Add model, record and records attributes on Wizard * Check read access of wizard records * Add cached_property in tools * Use custom class to store record data * Do not write to existing targets on xxx2Many add * Add configuration check * Add support for properties to fields.depends * Allow combining authentication methods together * Add context to export CSV route Version 5.6.0 - 2020-05-04 -------------------------- * Bug fixes (see mercurial logs for details) * Call getter function when accessing Function field on unsaved record * Add language configuration wizard * Allow copying attachments and notes to created records * Add link button on form * Support explicit delete and remove for saving and on_change xxx2Many * Add export_data_domain to ModelStorage * Add route to export CSV data * Add test on target of relation fields * Add width and height attributes on calendar view * Add default database name configuration * Add retry option to report convert * Add depends fields on view_attributes * Simplify trigger action * Run trigger in the queue * Do not copy Binary content with file_id * Replace memoize with functools.lru_cache * Add support for Python 3.8 * Set all fields readonly for inactive record * Enable check_access context when checking wizard access (issue9108) * Add option to send test email with trytond-admin * Add editable on calendar view * Add xalign and yalign to group * Add MultiSelection entry to Dict field * Allow empty order clause * Change editable tree attribute into boolean * Send default order to clients * Replace advisory lock by SKIP LOCKED in queue pulling * Load WSGI middleware from configuration * Add help text to Dict keys * Update button_action with returned values * Use direct access to backend classes * Add weasyprint support * Add slugify tool * Add is_secure, host and http_host to url module * Add __href__ to URLMixin * Add validate attribute to wizard's Button * Return 400 instead of 500 for Tryton exception * Fill the reverse field in the One2Many setter * Drop support for skiptest attribute on xml files * Remove implicit field names in ModelStorage.search_read Version 5.4.0 - 2019-11-04 -------------------------- * Bug fixes (see mercurial logs for details) * Improve tests on depends * Add permission groups on export * Retry cron job on DatabaseOperationalError * Add visual context on tree view * Add start value to PYSON Date and DateTime * Add MultiSelection field * Support dot notation on PYSON Eval * Add __slots__ * Pass app and request to wsgi error handlers * Add lazy_gettext * Add format_timedelta to Report * Add partial TO_CHAR support for date and datetime on SQLite * Setup default logging for WSGI app * Add format argument to report format_date function * Change expand attribute into a factor * Allow SQL expression as value of fields * Allow customizing Dict keys order with a sequence field * Add invalid domain in DomainValidationError * Add domain inversion tools * Add get_relation_fields to DictSchemaMixin * Add level on Model.fields_get to fill relation_fields Version 5.2.0 - 2019-05-06 -------------------------- * Bug fixes (see mercurial logs for details) * Add sort and translate options to Reference field * Do not create empty translations * Replace dsn by params to connect to postgresql * Simplify cron * Add duration on Cache * Add strip wildcards helpers * Add list-form view * Do not set id for on_change calls if cached * Add cache on RPC * Remove support for Python 3.4 * Allow to update record when importing data * Set context on record instantiated by Field.__set__ * Set context when reading related fields * Check read access on field in search order (issue8189) * Add base64 converter to URL map * Add HTML widget * Support import of native numeric, date and datetime data * Add day view on calendar * Raise NotImplementedError when setting Function field without setter * Add exports in view_toolbar_get * Add resources method to ModelStorage * Validate selection format in Dict schema * Allow to extend Field's string and help * Add console * Add Model.__names__ to retrieve model and field names * Add size attribute on image tag * Allow to use channel to synchronize Cache * Display ids and rule names on access error * Move field definition from Model to Field * Use number of verbose flag as log level * Add coroutine concurrency option * Add increasing delay on database operational error retry * Allows to lock records for update * Remove _nocache on Transaction * Make Cache transactional * Allow to search on key's value of Dict * Allow to order Dict by key's value * Do not store keys with null value in Dict * Add cache timeout for web * Allow the bus requests to be redirected to another host * Add support for CORS * Add extras modules to ModuleTestCase * Add timeout to Report.convert * Allow records from XML with noupdate to be deleted * Add ir.calendar for month and day * Rename languages: hu_HU, it_IT and pt_BR into hu, it and pt * Define custom exceptions * Remove _error_messages, raise_user_error and raise_user_warning * Remove ModelStorage._constraints * Add ir.message * Add check on ModelSQL for positive id * New API to read related fields * Remove implicit fields names in ModelStorage.read * Check read access on field in search domain (issue7766) * Add active field on ModelAccess, ModelFieldAccess and Group * Use write mode by default to check create and delete of resources Version 5.0.0 - 2018-10-01 -------------------------- * Bug fixes (see mercurial logs for details) * Allow non translatable reports * Replace hard coded 'state' by '_transition_state' in copy * Support dotted notation in copy default * Allow callable in copy default * Add bus system * Allow to set any default configuration value from environment * Clear existing session when password is changed * Manage session with max_age and timeout * Use passlib to hash and update password * Remove unique constraint on attachment name * New icons * Add pyson TimeDelta * Remove button if it is not allowed to access some of its dependant fields * Add support for Python 3.7 * Add transactional queue and workers * Add __table_handler__ to ModelSQL * Support partial index * Allow to use SQL expression for index action * Add cache clean timeout configuration * Implicit conversion to boolean in PYSON statement * Add domain to dictionary schema * Fill main language in ir.configuration at database initialization * Remove support for Python 2.7 * Check Rule also after modification * Check Rule after indirect fields * Allow to define view id in switch client action * Do not validate Function fields even with setter * Simplify the creation of dependencies graph * Make depends on methods generic to any method * Add width/height attribute to notebook * Allow to call set_lang with None and language instance * Add hostname configuration to list database * Add tree mixin * Rename "install-dependences" into "activate-dependencies" * Use recursive common table expression for child_of/parent_of operators * Add sql_cast on Field Version 4.8.0 - 2018-04-23 -------------------------- * Bug fixes (see mercurial logs for details) * Add index method to order field set calls * Add deactivable mixin * Ensure active field is present on tree view * Manage depends xml attribute on field tag * Add expand attribute on group tag * Add depends on Pool.register * Add Exclude constraint * Allow to perform unaccented searches on Char fields * Always raise exception in table handler * Simplify API for Session: new, remove, check and reset * Ensure that all buttons are registered in ir.model.button * Make trytond-admin ask for admin email * Add option to set admin email with trytond-admin * Add option to reset admin password with trytond-admin * Add reset password button * Add depends on Button * Add ModelData.has_model cache for ModelStorage.check_xml_record * Limit authentication attempt per IP network * Manage 'X-Forwarded' headers from proxies * Add '_request' attribute to Transaction context * Delete translations on deletion only when model has translatable field * Remove MySQL backend * Add keyword attribute to button tag * Allow field name on image tag * Remove unoconv and call soffice directly * Allow to include mixin to pool objects * Improve validation of PYSON domain * Use JSON canonical form for Dict value * Remove rules on user * Add monetary formatting to language * Add exceptional parent language * Add get method on ir.lang * Convert format, currency and strftime of ir.lang into instance methods Version 4.6.0 - 2017-10-30 -------------------------- * Bug fixes (see mercurial logs for details) * Add support for Python 3.6 * Remove support for Python 3.3 * Move handling of sequences to the Database object * Allow to add tests through entry points * Add translated descriptor for Reference field * Implement alter_type and alter_size for sqlite backend * Add a maximum size for request * Add support for single record report * Add support for Flat OpenDocument * Add get_email in trytond.report * Replace plain extension by txt * Support test database cache for remote postgresql * Increase session randomness to 32 bytes * Allow to specify datetime related values in XML files * Add environment variables to wsgi script * Add unique ids check on RPC * Assert unique records on ModelView.button and Workflow.transition * Add test for function field methods * Add option install module dependencies with trytond-admin * Add localhost_name and timeout as get_smtp_server uri parameters * Delete missing modules not activated when updating module list * Remove empty pages from notebook * Allow to store Dict as JSON on the database Version 4.4.0 - 2017-05-01 -------------------------- * Bug fixes (see mercurial logs for details) * Sanitize path in file_open against suffix (CVE-2017-0360) * Add constraint on user password * Remove Property field * Add MultiValueMixin and ValueMixin * Use sql type in column creation * Use generic SQL type in field and let backend determine the SQLType * Add filter to xxx2Many fields * Add NULLS ordering * Add context domain on ir.action.act_window * Allow None limit in action window * Add has_window_functions on Database * Allow Many2One on ModelSQL to target ModelStorage * Manage Cache in Transaction * Allow to register multiple exit functions on Transaction * Return 429 status when too many login attempts * Add set_rpc on Field * Add has_select_for on Database * Store custom report translation in separate module * Add form action keyword for set/synchronize translation on report and view * Add negative value for col attribute * Allow to use domain_ method with Function fields * Validate wizard definition on module tests * Remove order constraint on register ModelSQL * Add relate from report to translations Version 4.2.0 - 2016-11-28 -------------------------- * Bug fixes (see mercurial logs for details) * Add toolbar attribute for richtext widget * Add PYSON widget * Allow to define the text color and background color in calendar view * Allow to override cache implementation * Add button rule * Allow to specify translatable languages in trytond-admin * Add datetime_field on Reference * Merge Spanish's into Spanish (Latin American) * Do not check write access on model for wizard with groups * Add user application * Add sequence_ordered * Remove most country specific code in languages * Add support for derivative translations * Remove IDENTIFIER regexp on ir.model and ir.model.field * Enforce suffix and prefix to have id or name * Sanitize path in file_open (CVE-2016-1242) * Prevent read of user password hash (CVE-2016-1241) * Add database dump cache for tests * Remove unused tools: find_in_path, exec_command_pipe and mod10r * Implementation of drop_column for SQLite * Allow to pass many configuration files * Remove translate on field name of User * Allow to define the default mode in calendar view * Use 'default_rec_name' context key in Model.default_get * Add option to store Attachment in database * Allow to store Binary field in filestore * Add filestore module * Allow None in Greater/Less PYSON * Add option to set admin password with trytond-admin * Remove super password * Remove database management from RPC * Remove ModelView.view_header_get * Remove string attribute from views * Don't check write access on model for button with groups * Limit readonly state for xxx2Many * Add option to update modules list with trytond-admin * Use home directory as default path for database and web root. * Add count option on Action Window Domains * Remove window_name on Action Window * Return the calling keyword in ActionKeyword.get_keywords * Add customizable login process * Allow to customize the substitutions used on sequence * Allow PYSON in tree_invisible attribute Version 4.0.0 - 2016-05-02 -------------------------- * Bug fixes (see mercurial logs for details) * Add sendmail module to send transactional email * Support Two-Phase Commit in Transaction * Allow Report to generate text plain, XML, HTML and XHTML * Add workflow graph on ir.model * Add context model on ir.action.act_window * Switch to WSGI API * Limit the login size in LoginAttempt * Remove LocalDict from tools * Add LRUDictTransaction * Follow PEP-0249 for Database, Transaction and Cursor * Add Python3 support * Make TestCase create and drop its database * Add with_transaction decorator for tests * Add note on resources * Add 'where' operator for xxx2many fields * Strip and unquote double-quote from Postgresql schema in search_path * Move webdav into a separate module * Don't read historized user when evaluating record rules as it could lead to past privilege escalation. * Only rebuild mptt tree if left or right values have their default values * Allow nested inherited view * Add button on cron to run once * Check all fields when writing a sequence of records, values (CVE-2015-0861) * Add view_ids on tree view * Add parent_of operator * Enforce type of inheriting view * Use instance context in translated descriptor of Selection Version 3.8.0 - 2015-11-02 -------------------------- * Bug fixes (see mercurial logs for details) * Add test for all field methods * Load po files also in 'override' subdirectory * Add support for float and integer on Property fields * Remove foreign-key on create_uid and write_uid * Prevent deletion of any user * Manage PostgreSQL schema * Remove colors attribute on tree view * Remove style on Report * Add StateReport to Wizard * Allow to override ModelSQL._table * Allow to import backend from entry points * Add reversed operators to PYSON expressions * Explicity raise error when creating/writing/deleting models with table_query * Use CURRENT_TIMESTAMP instead of now * Use Constraint instance in ModelSQL._sql_constraints * Only return default record if no domain supplied on ModelSingleton search * Rule.domain_get returns a domain and Rule.query_get a SQL query * Add target_search option to Many2One * Add tables argument to ModelSQL.search_domain * Rename ir.module.module* into ir.module* Version 3.6.0 - 2015-04-20 -------------------------- * Bug fixes (see mercurial logs for details) * Use bytes and bytearray for Binary * Add button_change * Add support for PyPy * Add support for psycopg2cffi * Add noeval on PYSONDecoder * Add __repr__ to PYSON * Remove safe_eval * Add ModelView.view_attributes * Add pyson attribute on data field tag * Changed into JSON: - record rule domain - trigger condition - 'states', 'domain', 'spell' and 'colors' view attributes - view domain - 'email', 'domain', 'context', 'order' and 'search_value' action fields * Add product attribute on form view for One2Many * Remove float_time widget * Add TimeDelta field * search_global yields record instead of id * Add ModelTestCase * Add test for missing default model access * Report API refactorization * Add test for access rights of menu and actions * Allow to use the dotted notation for order parameters * Use action_id to find report to use * Allow custom StateView without Model * Remove Pool.object_name_list * Add translated descriptor for Dict field * Clean private context keyword in RPC * Add cache section in configuration * Use dualmethod on ModelStorage.save * New API for on_change: instance changes * Add restore_history_before on ModelSQL * Remove img_{width,height} form attributes Version 3.4.0 - 2014-10-20 -------------------------- * Bug fixes (see mercurial logs for details) * Use literal_eval instead of safe_eval (CVE-2014-6633) * Prevent double underscore in safe_eval (CVE-2014-6633) * Add pre-validation on button * Model and Field access checked only if _check_access is set * Add check_access to RPC * Add check_access to Wizard and Report * Add support for domain_ method * Refactor configuration file and command line * Use the context of the relation field for instanciation * Use a configuration field for logging * Add translated descriptor for Selection field * Add tree_state attribute on tree view * Allow to sync XML data * Remove on_change calls in Model.default_get * Add group call to on_change * Add UnionMixin * Allow to disable sorting of dictionary field's selection * Add active field to views of action window * Make global cache depends on explicit context keys * Don't add to global cache Binary fields * Add MatchMixin * Add image widget to tree * Remove context, current_date and time from record rule evaluation Version 3.2.0 - 2014-04-21 -------------------------- * Bug fixes (see mercurial logs for details) * Add restore_history to ModelSQL * Add history revisions * Add the multi selection widget * Add index to one2many's on_change * Remove auto-refresh on Action Window * Add support of domain for non-relation field * Manage microseconds in JSON-RPC and XML-RPC * Remove Sha field * Add password widget * Add Len to PYSON * Use bcrypt to hash password if possible * Use a sequence of ids, values to set fields * Client side actions on button and wizard * Add depends attribute to data tag * Add tree_invisible attribute to button in tree view * Drop support of Python 2.6 * Deprecate on_change, on_change_with, selection_change_with and autocomplete field arguments * Add fields.depends decorator * Add run-tests * Validate only modified and dependant fields on model write * Improve error messages by showing the failing value * Remove relation field actions: - delete_all - unlink_all - set * Rename relation field action unlink into remove * Use a sequence of records, values in write * set_context of Transaction.set_user is restricted to root * Add a "copy" action to One2Many and Many2Many's set method * Force UTC as timezone (migration script available on tryton-tools) * Add relation_field for many2one Version 3.0.0 - 2013-10-21 -------------------------- * Bug fixes (see mercurial logs for details) * Allow customization of translation in po files * Use python-sql * Add convert_domain method on Fields * Add sql_format and sql_type methods on Fields * Allow to return a full domain for Function.searcher * Replace static backend by dynamic get method * Replace order_field by order_ method * Allow field One2One in check_recursion * Remove the default order on MPTT * Add grouped attribute to data tag * Store selection tree state * Add order to Action Window * Add factor on number fields * Add calendar view * Remove request Version 2.8.0 - 2013-04-22 -------------------------- * Bug fixes (see mercurial logs for details) * Allow to search on target of Reference field * Remove _inherits * Add dynamic label * Add prefix, suffix on tree view * Replace _constraints with validate in ModelStorage * Add selection_change_with on Selection and Reference fields * Add Dict fields * Remove unique constraint on model and field access * Use lists of values in create * (Field, Operator, Operand) are replaced by Domain on Rule * Add global search * Replace view shortcut by menu favorite * Store default language in database * Add icon attribute on fields * Prevent Wizard State name to start with '_' * Add completion attribute for Many2One, Many2Many and One2Many * Add ViewSearch * Add domains on Action Window Version 2.6.0 - 2012-10-22 -------------------------- * Bug fixes (see mercurial logs for details) * Add pre-validation * Allow to use XML file for views * Add RPC definition * Repace BrowseRecord by Model instance * Replace Cache decorator by a simple LRU Cache * Remove Cacheable * Remove _description * Rename _name by __name__ * Use class in Pool * Fix search button clause in ModelButton.get_groups (CVE-2012-2238) * Merge all kind of buttons * Use XML id for board action instead of id * Add states attribute to notebook * Allow to use tuple for Reference * Add constant interpolation on line graph * Add create/delete field access * Add dynamic size limit on the One2Many, Many2Many and Char * Replace __tryton__.py by tryton.cfg * Allow to use Reference field in One2Many & Many2Many * Remove hexmd5 from ModelView.fields_view_get * Allow client to manage model access * Add time format validation * Remove ModelSQL.default_sequence Version 2.4.0 - 2012-04-23 -------------------------- * Bug fixes (see mercurial logs for details) * Don't allow rpc call on ModelStorage without ModelView (CVE-2012-0215) * Add shared WebDAV * Remove workflow module * Simplify workflow engine * Add ir.model.button for access rights * Replace fill by expand * Integer, Numeric and Float allow None as value * NULL value is None and not False * Replace user action by a list of actions * Add group call to on_change_with * Allow to get fuzzy translation * Allow to customize server timezone * Add richtext widget for WYSIWYG editor * Add support of fields.Time * Replace nested view by reference id * Remove underscore to ir.translation methods * Add default database language code * Add extras_depend to module definition * Store session in database * New Wizard design * Add pyson.Id * Use XML-RPC struct for Decimal and Date * Remove change_default on fields Version 2.2.0 - 2011-10-24 -------------------------- * Bug fixes (see mercurial logs for details) * Remove name field in ir.property * Add wizard to show views * Switched from .csv to .po for translations * Search on Many2One fields include inactive records * Change select on fields into Boolean * Change format of search_value on ir.action.act_window * Manage relation field access * Support size format in context for Binary fields * Use buffer for Binary fields * No more store Binary fields in base64 * Remove tabpos attribute on notebook * Make PYSON more Pythonic * Add readonly on Transaction * Add has_returning on Cursor * Remove use of python code in workflow XML * Use SQL sequence on PostgreSQL for ir.sequence * Allow to specify more than one interface * Use unoconv for report format conversion * Allow to use any Opendocument as report template * Drop NetRPC and activate JSON-RPC by default * Remove ir.action.wizard_size * Rename expand and fill attributes into yexpand and yfill * Add xalign and yalign as field attributes * Drop support of Python 2.5 * Remove support of Many2Many field in record XML * Change Pool into a Singleton * Remove support of zipped modules Version 2.0.0 - 2011-04-26 -------------------------- * Bug fixes (see mercurial logs for details) * Use md5 hash for indexing translation * Merge tree and list views * Added autocompletion on fields.Char * Remove ir.default * Add type, last user and last modification on ir.attachment * Rename datas into data on ir.attachment * Add new configuration option to prevent database listing * Add warning to wizards * Add server-side icons * Add support for file link to BinaryField * Add model field access * Add loading attribute on fields * Remove priority attribute on fields * Model doesn't convert anymore ids for inherited methods * Remove required attribute on Boolean fields * Add One2One field * Add AUTOINCREMENT to sqlite primary key Version 1.8.0 - 2010-11-01 -------------------------- * Bug fixes (see mercurial logs for details) * Add timestamp sequence * New transaction management * Make _timestamp numeric instead of datetime to work with XML-RPC and JSON-RPC * Add ir.trigger to trigger ModelStorage change * Add default value to Boolean fields at database level Version 1.6.0 - 2010-05-08 -------------------------- * Bug fixes (see mercurial logs for details) * Add symbol parameter to formatLang * searcher on Function fields take only one domain clause as argument * Use a Reference field on ir.attachment to store resource informations Improve the ir.attachment views to be usable on the client side * Use basic access authentication for XML-RPC * Replace child{1,2} attributes in xml views by a unique child * Models that uses _inherits will search in inherited parents for missing functions * Remove ids from on_change* calls * Improve search on translatable fields * export_data return empty value for invisible fields * Don't allow to use float in Numeric fields * set/get function on Fields take a list of ids * New interface for Function/Property fields Take a Field as first argument instead of many separate arguments Remove static arguments * Fix Float and Numeric for lost of precision * Add decimal digits validation on fields * Improve unittests to run trytond from tests Use sqlite as default backend Add skiptest attribute to data tag Add option to test_tryton to run tests from all modules * Add MySQL backend * Refactoring by validation with pylint * Modify ondelete attribute of Many2One according to required attribute value * Refactor import_data of ModelStorage * Raise exception when search function is missing on Function fields * Add LRU memoization, use it to cache compiled code for safe_eval. * Add PySON to replace python string evaluation on client side * Add JSON-RPC * Add groups on Sequence Types and add rules on sequence based on it. * Ignore Fields that starts with "_" * Add comment on table and field for postgresql backend * Remove egenix-mx-base and replace it by python-dateutil * Add cache to safe_eval * Rename HttpDaemon into XMLRPCDaemon * Improve TranslateFactory to fetch all translations for a report in one query * Handle displayname on webdav.collection * Handle current-user-privilege-set on webdav.collection Version 1.4.0 - 2009-10-19 -------------------------- * Bug fixes (see mercurial logs for details) * Add datetime_field on xxx2Many to use a specific _datetime when reading the related record * Add new tool safe_eval * Handle sequence and history renaming when renaming table * Add old_password to set_preferences of res.user on password change * Allow to drop constraint, index and foreign key with custom table name * Added column_rename on TableHandler * Add new tool reduce_ids * Add limit_clause function on cursor * Fill the cursor cache at search * Allow rpc on today of ir.date * Use the module dependency order to apply views that inherits * Allow to update database at the end of restore * Add ir.model.access check get and set of ir.property * Add ModelSingleton * Move login test in res.user * Rename osv into model on workflow * Add logout method * Move BrowseRecord cache onto the cursor except for Function fields * Don't order search result if order value is [] * Add reload of modules if files have changed * Add salt to sha of password * Add strftime to ir.lang to handle locale's format * Add sqlite backend * Add validate test for required and size * Remove _sequence on ModelSQL * Use gzip in pysocket * Add gzip encoding for XML-RPC * Add report name in the result of Report.execute * Add ir.action.wizard_size to store prefered wizard size * Add delete_all action on One2Many field * Read, write, create, delete permission on record rules * Add reset_default method to ir.default * Doesn't append '%' to "like", "ilike" clauses * Handle database dump and restore with password * Add float_time attribute in fields view Version 1.2.0 - 2009-04-20 -------------------------- * Bug fixes (see mercurial logs for details) * Add delete of foreign keys with ondelete CASCADE * Add write for foreign keys with ondelete SET NULL * Add datetime_field on Many2One to use a specific _datetime when reading the related record * Use _datetime in context to read record value at specific datetime * Add _history_table on ModelSQL to historize change on records * Allow to use related fields (many2one and reference) in read * Use rec_name function field instead of name_get and name_search * Use a new Pool for objects * Move workflow in ModelWorkflow and the workflow module * Remove Service and LocalService objects * New netrpc/xmlrpc syntax * copy on ModelStorage copies one2many directly on the right record * Search on translated field will search only on translated value * Add active field on ir.action to allow better override of reports * Add depends attributes on Column * Make Modified Preorder Tree Traversal respects the default order of the model * Add replace_attributes for xpath tag * Add email parameter on report action * Allow to inherit views from an other model * Add user warnings * Allow to use a list of id for copy method * Use one lock per database * Improve netrpc communication speed * Add contextual domain on inherited views * Allow to use globals in domain and states * Add translate attribute on Selection field * Use explicit join in search SQL query * Fix for host with IPv6 enable but without default IPv6 route * Allow egg installation Version 1.0.0 - 2008-11-17 -------------------------- * Initial release ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1745680198.0 trytond-7.0.30/COPYRIGHT0000644000175000017500000000165215003173506012713 0ustar00cedcedCopyright (C) 2004-2008 Tiny SPRL. Copyright (C) 2007-2025 Cédric Krier. Copyright (C) 2007-2013 Bertrand Chenal. Copyright (C) 2008-2025 B2CK SPRL. Copyright (C) 2011 Openlabs Technologies & Consulting (P) Ltd. Copyright (C) 2011-2025 Nicolas Évrard. Copyright (C) 2020-2023 Maxime Richez Copyright (C) 2020-2023 SALUC SA This program 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 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/LICENSE0000644000175000017500000010451314517761237012442 0ustar00cedced GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program 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 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/MANIFEST.in0000644000175000017500000000031414517761237013165 0ustar00cedcedinclude CHANGELOG include COPYRIGHT include LICENSE include README.rst include doc/* include trytond/ir/ui/icons/LICENSE recursive-include doc *.rst recursive-include doc *.po recursive-include doc *.pot ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1745680201.873057 trytond-7.0.30/PKG-INFO0000644000175000017500000001023215003173512012504 0ustar00cedcedMetadata-Version: 2.4 Name: trytond Version: 7.0.30 Summary: Tryton server Home-page: http://www.tryton.org/ Download-URL: http://downloads.tryton.org/7.0/ Author: Tryton Author-email: foundation@tryton.org License: GPL-3 Project-URL: Bug Tracker, https://bugs.tryton.org/ Project-URL: Documentation, https://docs.tryton.org/latest/server/ Project-URL: Forum, https://www.tryton.org/forum Project-URL: Source Code, https://code.tryton.org/tryton Keywords: business application platform ERP Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: Environment :: No Input/Output (Daemon) Classifier: Framework :: Tryton Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) Classifier: Natural Language :: Bulgarian Classifier: Natural Language :: Catalan Classifier: Natural Language :: Chinese (Simplified) Classifier: Natural Language :: Czech Classifier: Natural Language :: Dutch Classifier: Natural Language :: English Classifier: Natural Language :: Finnish Classifier: Natural Language :: French Classifier: Natural Language :: German Classifier: Natural Language :: Hungarian Classifier: Natural Language :: Indonesian Classifier: Natural Language :: Italian Classifier: Natural Language :: Persian Classifier: Natural Language :: Polish Classifier: Natural Language :: Portuguese (Brazilian) Classifier: Natural Language :: Romanian Classifier: Natural Language :: Russian Classifier: Natural Language :: Slovenian Classifier: Natural Language :: Spanish Classifier: Natural Language :: Turkish Classifier: Natural Language :: Ukrainian Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Topic :: Software Development :: Libraries :: Application Frameworks Requires-Python: >=3.8 License-File: LICENSE Requires-Dist: defusedxml Requires-Dist: lxml>=2.0 Requires-Dist: relatorio[fodt]>=0.7.0 Requires-Dist: Genshi Requires-Dist: python-dateutil Requires-Dist: polib Requires-Dist: python-sql>=1.3 Requires-Dist: werkzeug>=0.12 Requires-Dist: passlib>=1.7.0 Requires-Dist: pytz; python_version < "3.9" Requires-Dist: backports.entry-points-selectable; python_version < "3.10" Provides-Extra: test Requires-Dist: pillow; extra == "test" Provides-Extra: postgresql Requires-Dist: psycopg2>=2.7.0; extra == "postgresql" Provides-Extra: graphviz Requires-Dist: pydot; extra == "graphviz" Provides-Extra: levenshtein Requires-Dist: python-Levenshtein; extra == "levenshtein" Provides-Extra: bcrypt Requires-Dist: passlib[bcrypt]; extra == "bcrypt" Provides-Extra: argon2 Requires-Dist: passlib[argon2]; extra == "argon2" Provides-Extra: html2text Requires-Dist: html2text; extra == "html2text" Provides-Extra: weasyprint Requires-Dist: weasyprint; extra == "weasyprint" Provides-Extra: coroutine Requires-Dist: gevent>=1.1; extra == "coroutine" Provides-Extra: image Requires-Dist: pillow; extra == "image" Provides-Extra: barcode Requires-Dist: python-barcode[images]; extra == "barcode" Provides-Extra: qrcode Requires-Dist: qrcode[pil]; extra == "qrcode" Requires-Dist: webcolors; extra == "qrcode" Provides-Extra: completion Requires-Dist: argcomplete; extra == "completion" Provides-Extra: email-validation Requires-Dist: email-validator>=2; extra == "email-validation" Requires-Dist: dnspython; extra == "email-validation" Dynamic: author Dynamic: author-email Dynamic: classifier Dynamic: description Dynamic: download-url Dynamic: home-page Dynamic: keywords Dynamic: license Dynamic: license-file Dynamic: platform Dynamic: project-url Dynamic: provides-extra Dynamic: requires-dist Dynamic: requires-python Dynamic: summary trytond ======= The server of Tryton. Tryton is business software, ideal for companies of any size, easy to use, complete and 100% Open Source. It provides modularity, scalability and security. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/README.rst0000644000175000017500000000030314517761237013114 0ustar00cedcedtrytond ======= The server of Tryton. Tryton is business software, ideal for companies of any size, easy to use, complete and 100% Open Source. It provides modularity, scalability and security. ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1745680201.706388 trytond-7.0.30/bin/0000755000175000017500000000000015003173512012161 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/bin/trytond0000755000175000017500000000550014517761237013632 0ustar00cedced#!/usr/bin/env python3 # PYTHON_ARGCOMPLETE_OK # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import glob import logging import os import sys import threading try: import argcomplete except ImportError: argcomplete = None DIR = os.path.abspath(os.path.normpath(os.path.join(__file__, '..', '..', 'trytond'))) if os.path.isdir(DIR): sys.path.insert(0, os.path.dirname(DIR)) import trytond.commandline as commandline from trytond.config import config, split_netloc parser = commandline.get_parser_daemon() if argcomplete: argcomplete.autocomplete(parser) options = parser.parse_args() commandline.config_log(options) extra_files = config.update_etc(options.configfile) if options.coroutine: # Monkey patching must be done before importing from gevent import monkey monkey.patch_all() from trytond.modules import get_module_info, get_modules from trytond.pool import Pool # Import trytond things after it is configured from trytond.wsgi import app with commandline.pidfile(options): Pool.start() threads = [] for name in options.database_names: thread = threading.Thread(target=Pool(name).init) thread.start() threads.append(thread) for thread in threads: thread.join() hostname, port = split_netloc(config.get('web', 'listen')) certificate = config.get('ssl', 'certificate') try: if config.getboolean('ssl', 'certificate'): certificate = None except ValueError: pass privatekey = config.get('ssl', 'privatekey') try: if config.getboolean('ssl', 'privatekey'): privatekey = None except ValueError: pass if certificate or privatekey: from werkzeug.serving import load_ssl_context ssl_args = dict( ssl_context=load_ssl_context(certificate, privatekey)) else: ssl_args = {} if options.dev and not options.coroutine: for module in get_modules(): info = get_module_info(module) for ext in ['xml', 'fodt', 'odt', 'fodp', 'odp', 'fods', 'ods', 'fodg', 'odg', 'txt', 'html', 'xhtml']: path = os.path.join(info['directory'], '**', '*.' + ext) extra_files.extend(glob.glob(path, recursive=True)) if options.coroutine: from gevent.pywsgi import WSGIServer logger = logging.getLogger('gevent') WSGIServer((hostname, port), app, log=logger, error_log=logger, **ssl_args).serve_forever() else: from werkzeug.serving import run_simple run_simple(hostname, port, app, threaded=True, extra_files=extra_files, use_reloader=options.dev, **ssl_args) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1707150267.0 trytond-7.0.30/bin/trytond-admin0000755000175000017500000000144714560205673014721 0ustar00cedced#!/usr/bin/env python3 # PYTHON_ARGCOMPLETE_OK # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import os import sys try: import argcomplete except ImportError: argcomplete = None DIR = os.path.abspath(os.path.normpath(os.path.join(__file__, '..', '..', 'trytond'))) if os.path.isdir(DIR): sys.path.insert(0, os.path.dirname(DIR)) import trytond.commandline as commandline from trytond.config import config parser = commandline.get_parser_admin() if argcomplete: argcomplete.autocomplete(parser) options = parser.parse_args() config.update_etc(options.configfile) commandline.config_log(options) # Import after application is configured import trytond.admin as admin admin.run(options) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/bin/trytond-console0000755000175000017500000000141714517761237015275 0ustar00cedced#!/usr/bin/env python3 # PYTHON_ARGCOMPLETE_OK # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import os import sys try: import argcomplete except ImportError: argcomplete = None DIR = os.path.abspath(os.path.normpath(os.path.join(__file__, '..', '..', 'trytond'))) if os.path.isdir(DIR): sys.path.insert(0, os.path.dirname(DIR)) import trytond.commandline as commandline from trytond.config import config parser = commandline.get_parser_console() if argcomplete: argcomplete.autocomplete(parser) options = parser.parse_args() config.update_etc(options.configfile) # Import after application is configured import trytond.console as console console.run(options) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/bin/trytond-cron0000755000175000017500000000157114517761237014575 0ustar00cedced#!/usr/bin/env python3 # PYTHON_ARGCOMPLETE_OK # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import os import sys try: import argcomplete except ImportError: argcomplete = None DIR = os.path.abspath(os.path.normpath(os.path.join(__file__, '..', '..', 'trytond'))) if os.path.isdir(DIR): sys.path.insert(0, os.path.dirname(DIR)) import trytond.commandline as commandline from trytond.config import config parser = commandline.get_parser_cron() if argcomplete: argcomplete.autocomplete(parser) options = parser.parse_args() config.update_etc(options.configfile) commandline.config_log(options) import trytond.cron as cron # Import after application is configured from trytond.pool import Pool with commandline.pidfile(options): Pool.start() cron.run(options) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/bin/trytond-stat0000755000175000017500000001143414517761237014606 0ustar00cedced#!/usr/bin/env python3 # PYTHON_ARGCOMPLETE_OK # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import curses import datetime as dt import math import os import sys from collections import defaultdict try: import argcomplete except ImportError: argcomplete = None DIR = os.path.abspath(os.path.normpath(os.path.join(__file__, '..', '..', 'trytond'))) if os.path.isdir(DIR): sys.path.insert(0, os.path.dirname(DIR)) import trytond.commandline as commandline from trytond.config import config parser = commandline.get_parser_stat() if argcomplete: argcomplete.autocomplete(parser) options = parser.parse_args() config.update_etc(options.configfile) import trytond.status as status def main(stdscr): global reverse stdscr.nodelay(1) reverse = True processes = {} status_pad = curses.newpad(1, 1) cache_pad = curses.newpad(1, 1) def refresh_status(): now = dt.datetime.now() height, width = stdscr.getmaxyx() def expired(process): return process['expire'] > now def format_status(since, id_, request): since = str(dt.timedelta(seconds=int(since))) pid, node = id_.split('@', 1) if len(node) > 12: node = node[:5] + '…' + node[:6] return f"{pid:>5} {node:<12} {since:>18} {request}" status_pad.clear() status = [format_status(*i) for i in sorted( ((msg['since'], p['id'], msg['request']) for p in filter(expired, processes.values()) for msg in p['status']), reverse=reverse)] prow = min(len(status) + 1, height // 2) pcol = max(max(map(len, status), default=0), width) status_pad.resize(len(status) + 1, pcol + 1) for i, line in enumerate(status, 1): status_pad.addnstr(i, 0, line.ljust(pcol), pcol) status_pad.addnstr( 0, 0, "{pid:>5} {node:^12} {since:>18} {request} ({n})".format( pid="pid", node="node", since="TIME" + ('↑' if reverse else '↓'), request="request", n=len(status), ).upper().ljust(pcol), pcol, curses.A_REVERSE) status_pad.noutrefresh(0, 0, 0, 0, prow, width - 1) def ratio(cache): if cache['hit'] or cache['miss']: return cache['hit'] / (cache['hit'] + cache['miss']) return 0 def format_cache(name, hit, miss, ratio, size): return f"{hit:{size}d} {miss:{size}d} {ratio * 100:6.2f} {name}" cache_pad.clear() cache_stats = defaultdict(lambda: defaultdict(lambda: 0)) for p in filter(expired, processes.values()): for cache in p['caches']: stats = cache_stats[cache['name']] stats['name'] = cache['name'] stats['hit'] += cache['hit'] stats['miss'] += cache['miss'] for cache in cache_stats.values(): cache['ratio'] = ratio(cache) try: size = math.ceil(math.log10( max(s['hit'] + s['miss'] for s in cache_stats.values()))) except ValueError: size = 1 size = max(size, 4) caches = [format_cache(size=size, **cache) for cache in sorted( cache_stats.values(), key=lambda c: (c['ratio'], c['miss']), reverse=reverse)] crow = max(len(caches) + 1, (height - prow)) ccol = max(max(map(len, caches), default=0), width) cache_pad.resize(crow + 1, ccol + 1) for i, line in enumerate(caches, 1): cache_pad.addnstr(i, 0, line.ljust(ccol), ccol) cache_pad.addstr( 0, 0, "{hit:>{size}} {miss:>{size}} {ratio:>6} {name} ({n})".format( size=size, hit="hit", miss="miss", ratio="% " + ('↑' if reverse else '↓'), name="name", n=len(caches), ).upper().ljust(ccol), curses.A_REVERSE) cache_pad.noutrefresh(0, 0, prow, 0, height - 1, width - 1) def refresh(): global reverse refresh_status() stdscr.refresh() key = stdscr.getch() if key == ord('q'): sys.exit() elif key == ord('r'): reverse = not reverse refresh() def update(data=None): if data: pid = data['id'] data['expire'] = dt.datetime.now() + dt.timedelta(seconds=10) processes[pid] = data refresh() refresh() return status.listen(config.get('database', 'path'), update) if not curses.wrapper(main): sys.stderr.write("status not supported on this platform\n") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1707150267.0 trytond-7.0.30/bin/trytond-worker0000755000175000017500000000160214560205673015133 0ustar00cedced#!/usr/bin/env python3 # PYTHON_ARGCOMPLETE_OK # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import os import sys try: import argcomplete except ImportError: argcomplete = None DIR = os.path.abspath(os.path.normpath(os.path.join(__file__, '..', '..', 'trytond'))) if os.path.isdir(DIR): sys.path.insert(0, os.path.dirname(DIR)) import trytond.commandline as commandline from trytond.config import config parser = commandline.get_parser_worker() if argcomplete: argcomplete.autocomplete(parser) options = parser.parse_args() config.update_etc(options.configfile) commandline.config_log(options) import trytond.worker as worker # Import after application is configured from trytond.pool import Pool with commandline.pidfile(options): Pool.start() worker.work(options) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1745680201.7097216 trytond-7.0.30/doc/0000755000175000017500000000000015003173512012156 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1725720314.0 trytond-7.0.30/doc/conf.py0000644000175000017500000000447714667063372013512 0ustar00cedced# This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import os base_url = os.environ.get('DOC_BASE_URL') if base_url: modules_url = base_url + '/modules-{module}/' tryton_url = base_url + '/client-desktop/' proteus_url = base_url + '/client-library/' else: modules_url = 'https://docs.tryton.org/${series}/modules-{module}/' tryton_url = 'https://docs.tryton.org/${series}/client-desktop/' proteus_url = 'https://docs.tryton.org/${series}/client-library/' def get_info(): import subprocess import sys module_dir = os.path.dirname(os.path.dirname(__file__)) info = dict() result = subprocess.run( [sys.executable, 'setup.py', '--name', '--description'], stdout=subprocess.PIPE, check=True, cwd=module_dir) info['name'], info['description'] = ( result.stdout.decode('utf-8').strip().splitlines()) result = subprocess.run( [sys.executable, 'setup.py', '--version'], stdout=subprocess.PIPE, check=True, cwd=module_dir) version = result.stdout.decode('utf-8').strip() major_version, minor_version, _ = version.split('.', 2) major_version = int(major_version) minor_version = int(minor_version) if minor_version % 2: info['series'] = 'latest' info['branch'] = 'branch/default' else: info['series'] = '.'.join(version.split('.', 2)[:2]) info['branch'] = 'branch/' + info['series'] return info info = get_info() html_theme = 'sphinx_book_theme' html_theme_options = { 'repository_provider': 'gitlab', 'repository_url': 'https://code.tryton.org/tryton', 'repository_branch': info['branch'], 'use_source_button': True, 'use_edit_page_button': True, 'use_repository_button': True, 'use_download_button': False, 'path_to_docs': 'trytond/doc', } html_title = info['description'] master_doc = 'index' project = info['name'] release = version = info['series'] default_role = 'ref' highlight_language = 'none' extensions = [ 'sphinx_copybutton', 'sphinx.ext.intersphinx', ] intersphinx_mapping = { 'python': ('https://docs.python.org/', None), } linkcheck_ignore = [r'/.*', r'https://demo.tryton.org/*'] del get_info, info, base_url, modules_url, tryton_url, proteus_url ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/index.rst0000644000175000017500000000224114517761237014036 0ustar00cedced.. _index: ============= Tryton Server ============= First steps =========== * **Installation:** :ref:`Installation ` | :ref:`Configuration ` | :ref:`Setup a database ` | :ref:`Start the server ` * **Tutorials:** :ref:`Create a module ` The model layer =============== * **Models:** :ref:`Model definition ` | :ref:`Field types ` | :ref:`Domain syntax ` | :ref:`Access rights ` | :ref:`Triggers ` * **Wizards:** :ref:`Wizards definition ` The view layer ============== * **Views:** :ref:`View types ` | :ref:`Extension ` * **Reports:** :ref:`Report definition ` * **Actions:** :ref:`Actions ` The development process ======================= * **Modules** :ref:`Module definition ` | :ref:`Create a module ` Contents ======== .. toctree:: :maxdepth: 2 topics/index ref/index modules/index tutorial/index releases ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1745680201.7097216 trytond-7.0.30/doc/modules/0000755000175000017500000000000015003173512013626 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/modules/index.rst0000644000175000017500000000025114517761237015505 0ustar00cedcedBuiltin Modules =============== Tryton comes with modules that are integral to every installation and are always activated. .. toctree:: :maxdepth: 2 res/index ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1745680201.7097216 trytond-7.0.30/doc/modules/res/0000755000175000017500000000000015003173512014417 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/modules/res/design.rst0000644000175000017500000000723514517761237016451 0ustar00cedced****** Design ****** The *Resource Module* introduces some important concepts. .. note:: For historical reasons the module's technical name is ``res``. .. _model-res.user: User ==== The *User* concept stores the details of the user accounts for the people who use Tryton. Each user is identified by their login name which must be unique. The login name is used when logging in to Tryton, along with other authentication data, such as their password. It also contains a set of other properties that let you store additional information about the user, such as their name, email address, and language. Users can belong to `Groups ` which define, amongst other things, their access rights. They have a list of `User Applications ` that are linked to the account, and a set of actions that are run when the user next logs in. .. note:: Once a user has been created they cannot be deleted, only deactivated. This is to preserve data integrity and ensure history is not lost. .. seealso:: A list of users is found by opening the main menu item: |Administration --> Users --> Users|__ .. |Administration --> Users --> Users| replace:: :menuselection:`Administration --> Users --> Users` __ https://demo.tryton.org/model/res.user Reports ------- .. _report-res.user.email_reset_password: Email Reset Password ^^^^^^^^^^^^^^^^^^^^ The *Email Reset Password* report provides the contents of the email that is sent to the `User ` when their password is reset. It provides information about how they can go about setting a new password. Wizards ------- .. _wizard-res.user.config: User Config ^^^^^^^^^^^ The *User Config* wizard is run from the module configuration wizard after the *Resource Module* is activated. It prompts the `User ` into creating one, or more, standard user accounts. .. _model-res.group: Group ===== The *Groups* concept is used to gather together `Users ` and make it easy to manage what data they can see, and what actions they can perform. Each group is made up of a set of users. Each of these user's `Access Rights ` are affected by the access permissions defined for the group. .. seealso:: A list of users is found by opening the main menu item: |Administration --> Users --> Groups|__ .. |Administration --> Users --> Groups| replace:: :menuselection:`Administration --> Users --> Groups` __ https://demo.tryton.org/model/res.group .. _model-res.user.application: User Application ================ The *User Application* concept stores a list of the secret keys for any `User Application ` that has requested to be connected to a `User ` account. Keys that are validated allow the associated user application to use the endpoints defined for that user application on behalf of the user. .. _model-res.user.login.attempt: Login Attempt ============= The *Login Attempt* concept is used to track and limit login attempts from IP addresses and networks. It is configured using settings from the ``[session]`` section of the `configuration file `. .. _model-res.user.device: User Device =========== The concept of a *User Device* allows the server to keep track of devices from which a user has successfully logged in. This is done using a device cookie. It allows the server to distinguish between connection attempts from trusted and untrusted devices and react accordingly. .. _model-res.user.warning: Warning ======= The user *Warning* concept is used to record whether a user wants to see a `specific warning ` again. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1725720314.0 trytond-7.0.30/doc/modules/res/index.rst0000644000175000017500000000074314667063372016305 0ustar00cedced.. _res: ############### Resource Module ############### The *Resource Module* provides some basic resources that practically every Tryton installation needs. This includes the concept of the users that use a Tryton system and the groups that they are gathered together in. It also provides the functionality that lets users login, and allows access restrictions to be setup which can limit what the users can see and do. .. toctree:: :maxdepth: 2 setup usage design ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/modules/res/setup.rst0000644000175000017500000000301214517761237016325 0ustar00cedced***** Setup ***** .. _Setting up initial users: Setting up initial users ======================== After you have just installed Tryton, the first time that you login you will need to use the ``admin`` account. Once you have successfully logged in you will be presented with a configuration wizard. As you progress through its stages you will reach one stage that allows you to `Configure Users `. It is often a good idea to use this opportunity to create at least one non-administrator `User `. Nearly all of the fields can either be left blank, or already have good default values. You will, however, need to fill in the :guilabel:`Login` name for the new user. It is also a good time to add some groups to the new user depending on what they will need to access. If you then enter in an email address you could later use the `Reset Password ` button to send them a temporary password. Alternatively you can directly fill in the :guilabel:`Password` for them. Once you have finished filling in the users details you can then click on the :guilabel:`Add` button to save the new user account and clear the screen ready to enter another new user. .. tip:: It is generally considered good practice to normally login to Tryton using a non-administrator account. The ``admin`` account is intended to be used when you need to make administrative changes to Tryton, such as activating new modules, or managing which `Groups ` a user belongs to. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/modules/res/usage.rst0000644000175000017500000000611214517761237016275 0ustar00cedced***** Usage ***** .. _Updating your preferences: Updating your preferences ========================= Some of the properties of your `User ` account can be viewed and updated by opening up your preferences. How you open your preferences depends on which client you are using, but it is often done from either a menu item called preferences, or a link somewhere in the header with your username. With your preferences open you are able to update things like your name, email address, language, signature and password. .. _Connecting user applications: Connecting user applications ============================ Tryton `User Applications ` are intended to be simple applications that have been written to do one thing well. When you configure the user application it connects to Tryton and requests a new key. This new key is stored in the associated `User's list of Applications `. To allow the user application to access and use Tryton you must :guilabel:`Validate` the key from inside `your preferences `. Once this is done the user application can perform it's predefined actions on your behalf. .. tip:: If you are concerned a key may have been compromised, you can easily revoke a user application's access, at any time, by deleting its key from your user preferences. .. _Managing user's access rights: Managing users access rights ============================ In Tryton `Groups ` help you manage and control what `Access Rights ` a `User ` has. By adding and removing users from groups you can control what parts of Tryton a user can access, and what they can see and do. You can find the users and groups under the [:menuselection:`Administration --> Users`] main menu item. If you want to see and change which users are in a group, then it is normally best to open the group to view it's members. If you are interested in seeing and updating which groups a single user belongs to, then it is often best to open the user account and then find their access permissions and groups. .. tip:: Many modules define standard groups that are useful to people who have activated that module. Often you only need to add the correct users to these groups to benefit from them. .. _Resetting users passwords: Resetting users passwords ========================= If a user has forgotten their password, or you are creating a new user and want them to set their password themselves, Tryton can send them a temporary password. On the User screen there is a :guilabel:`Reset Password` button which will send them an `Email Reset Password ` email to their email address. .. note:: This is only available if the email address for the user is set. The user can then login with this temporary password and update their password to one of their choosing. .. note:: The temporary password is only valid for a set amount of time, so the user must login and change their password before the temporary password expires. ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1745680201.713055 trytond-7.0.30/doc/ref/0000755000175000017500000000000015003173512012732 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1707150267.0 trytond-7.0.30/doc/ref/backend.rst0000644000175000017500000002400714560205673015071 0ustar00cedced.. _ref-backend: .. module:: trytond.backend ======= Backend ======= The backend manages the database connection and schema manipulation. .. contents:: :local: :backlinks: entry :depth: 1 .. attribute:: name The name of the backend configured. Database ======== .. class:: Database(name) Manage the connection to the named database. .. method:: Database.connect() Connect to the database and return the instance. .. method:: Database.get_connection([autocommit[, readonly]]) Retrieve a connection object as defined by :pep:`249#connection`. If autocommit is set, the connection is committed after each statement. If readonly is set, the connection is read only. .. method:: Database.put_connection(connection[, close]) Release the connection. If close is set, the connection is discarded. .. method:: Database.close() Close all connections. .. classmethod:: Database.create(connection, database_name) Create the named database using the connection. .. classmethod:: Database.drop(connection, database_name) Drop the named database using the connection. .. method:: Database.list([hostname]) Return a list of Tryton database names. ``hostname`` filters the databases with the same configured hostname. .. method:: Database.init() Initialize the database schema. .. method:: Database.test([hostname]) Return if the database is a Tryton database. If ``hostname`` is set, it checks also if it has the same configured hostname. .. method:: Database.nextid(connection, table[, count]) Return the next ``count`` IDs for the ``table`` using the ``connection``. .. note:: It may return ``None`` for some database. .. method:: Database.setnextid(connection, table, value) Set the ``value`` as current ID to the ``table`` using the ``connection``. .. method:: Database.currid(connection, table) Return the current ID of the ``table`` using the ``connection``. .. classmethod:: Database.lock(connection, table) Lock the ``table`` using the ``connection``. .. method:: Database.lock_id(id[, timeout]) Return the SQL expression to lock the ``id``. Set ``timeout`` to wait for the lock. .. method:: Database.has_constraint(constraint) Return if the database handle the ``constraint``. .. method:: Database.has_returning() Return if the database supports ``RETURNING`` in ``INSERT`` and ``UPDATE``. .. method:: Database.has_multirow_insert() Return if the database supports ``INSERT`` of multi-rows. .. method:: Database.has_select_for() Return if the database supports ``FOR UPDATE`` and ``FOR SHARE`` in ``SELECT``. .. method:: Database.get_select_for_skip_locked() Return For class with skip locked. .. method:: Database.has_window_functions() Return if the database supports window functions. .. method:: Database.has_unaccent() Return if the database suppport unaccentuated function. .. method:: Database.has_unaccent_indexable() Return if the database suppport unaccentuated function in index. .. method:: Database.unaccent(value) Return the SQL expression of unaccentuated ``value``. .. method:: Database.has_similarity() Return if the database suppports similarity function. .. method:: Database.similarity(column, value) Return the SQL expression that compare the similarity of ``column`` and ``value``. .. method:: Database.has_search_full_text() Return if the database suppports full text search. .. method:: Database.format_full_text(\*documents[, language]) Return the SQL expression that format the ``documents`` into text search vectors for the ``language``. The order of ``documents`` define the weight for proximity ranking. .. method:: Database.format_full_text_query(query[, language]) Convert the ``query`` expression into full text query. .. method:: Database.search_full_text(document, query) Return the SQL expression for searching ``document`` with the ``query``. .. method:: Database.rank_full_text(document, query[, normalize]) Return the SQL expression to rank ``document`` with the ``query``. .. classmethod:: Database.has_sequence() Return if the database supports sequence querying and assignation. .. method:: Database.sequence_exist(connection, name) Return if the named sequence exists using the ``connection``. .. method:: Database.sequence_create(connection, name[, number_increment[, start_value]]) Create a named sequence incremented by ``number_increment`` or ``1`` and starting at ``start_value`` or ``1`` using the ``connection``. .. method:: Database.sequence_update(connection, name[, number_increment[, start_value]]) Modify the named sequence with ``number_increment`` and ``start_value`` using the ``connection``. .. method:: Database.sequence_rename(connection, old_name, new_name) Rename the sequece from ``old_name`` to ``new_name`` using the ``connection``. .. method:: Database.sequence_delete(connection, name) Delete the named sequence using the ``connection``. .. method:: Database.sequence_next_number(connection, name) Return the next number fo the named sequence using the ``connection``. .. method:: Database.has_channel(connection, name) Return if the database supports ``LISTEN`` and ``NOTIFY`` on channel. .. method:: Database.sql_type(type_) Return the namedtuple('SQLType', 'base type') corresponding to the SQL ``type_``. .. method:: Database.sql_format(type_, value) Return the ``value`` casted for the SQL ``type_``. .. method:: Database.json_get(column[, key]) Return the JSON value of the JSON ``key`` from the ``column``. .. method:: Database.json_key_exists(column, key) Return the SQL expression to test if ``key`` exists in the JSON ``column``. .. method:: Database.json_any_keys_exist(column, keys) Return the SQL expression to test if any ``keys`` exist in the JSON ``column``. .. method:: Database.json_all_keys_exist(column, keys) Return the SQL expression to test if all ``keys`` exist in the JSON ``column``. .. method:: Database.json_contains(column, json) Rteurn the SQL expression to test if the JSON ``column`` contains ``json``. TableHandler ============ .. class:: TableHandler(model[, history]) Handle table for the ``model``. If ``history`` is set, the table is the one storing the history. .. attribute:: TableHandler.namedatalen The maximing length of named data for the database. .. attribute:: TableHandler.index_translators Contain the :class:`IndexTranslator` for the database. .. classmethod:: TableHandler.table_exist(table_name) Return if the named table exists. .. classmethod:: TableHandler.table_rename(old_name, new_name) Rename the table from ``old_name`` to ``new_name``. .. method:: TableHandler.column_exist(column_name) Return if the named column exists. .. method:: TableHandler.column_rename(old_name, new_name) Rename the column from ``old_name`` to ``new_name``. .. method:: TableHandler.alter_size(column_name, column_type) Modify the size of the named column using the column type. .. method:: TableHandler.alter_type(column_name, column_type) Modify the type of the named column. .. method:: TableHandler.column_is_type(column_name, type_[, size]) Return if the column is of type ``type_``. If ``type`` is ``VARCHAR``, ``size`` is also compared except if the value if negative. .. method:: TableHandler.db_default(column_name, value) Set the default ``value`` on the named column. .. method:: TableHandler.add_column(column_name, abstract_type[, default[, comment]]) Add the named column of abstract type. The ``default`` is a method that return the value to fill the new column. ``comment`` set as comment for the column. .. method:: TableHandler.add_fk(column_name, reference[, on_delete]) Add a foreign key constraint on the named column to target the ``reference`` table name. ``on_delete`` defines the method to use when foreign record is deleted. .. method:: TableHandler.drop_fk(column_name[, table]) Drop the foreign key constrant on the named column. ``table`` can be used to alter another table. .. method:: TableHandler.not_null_action(column_name[, action]) Add or remove ``NOT NULL`` on the named column. .. method:: TableHandler.add_constraint(ident, constraint) Add the SQL expression ``constraint`` as constraint named ``ident`` on the table. .. method:: TableHandler.drop_constraint(ident[, table]) Drop the named ``ident`` constraint. ``table`` can be used to alter another table. .. method:: TableHandler.set_indexes(indexes) Create the :class:`indexes ` if possible and drop others having ``idx_`` as prefix or ``_index`` as suffix. .. method:: TableHandler.drop_column(column_name) Drop the named column. .. classmethod:: TableHandler.drop_table(model, table[, cascade]) Drop the named ``table`` and clean ``ir.model.data`` from the given ``model``. Set ``cascade`` to drop objects that depend on the table. .. classmethod:: TableHandler.convert_name(name[, reserved]) Convert the data name to be lower than namedatalen minus reserved. .. method:: Database.index_translator_for(index) Return the best :class:`IndexTranslator` for the given index. IndexTranslator =============== .. class:: IndexTranslator Convert an :class:`~trytond.model.Index` into a concrete index. .. classmethod:: IndexTranslator.definition(index) Return the name, SQL query and parameters to create the :class:`index `. .. classmethod:: IndexTranslator.score(index) Return a score related to the fitness of using this translator for the :class:`index `. A score of ``0`` means that the translator is unsuited for the requested usage. Exceptions ========== .. exception:: DatabaseIntegrityError Exception raised when the relational integrity of the database is affected. .. exception:: DatabaseDataError Exception raised for errors that are due to problems with the processed data. .. exception:: DatabaseOperationalError Exception raised for errors that are related to the database’s operation. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/bus.rst0000644000175000017500000000630514517761237014301 0ustar00cedced.. _ref-bus: .. module:: trytond.bus Bus === The Tryton server listens on ``POST`` requests on the routes matching ``//bus`` and replies with JSON_ dictionary containing: ``channel`` The channel on which this message has been received. ``message`` A dictionary that is the message the client must handle. The specification of the message depends of its type. All messages should at least content a unique identifier in the key ``message_id`` and their type in the key of the same name. Client sending their requests on the route must be authenticated. The request must submit a JSON_ dictionary containing: ``last_message`` A value identifying the last message received by the client. This value can be ``null``. ``channels`` A list of strings denoting the channels the client is listening to. .. _JSON: https://en.wikipedia.org/wiki/JSON .. class:: Bus Expose two methods that are used by the framework: ``publish`` and ``subscribe``. .. classmethod:: Bus.publish(channel, message) Send a message to a specific channel. Implemented messages are: * :ref:`Notifications ` .. classmethod:: Bus.subscribe(database, channels[, last_message]) Subscribe a user client to some ``channels`` of messages. The ``message_id`` parameter defines the last message id received by the client. It defaults to ``None`` when not provided. The default implementation provides an helper method to construct the response: .. classmethod:: Bus.create_response(channel, message) Create a dictionary suitable as a response from a message and a timestamp. ``channel`` is the channel on which the message has been received. ``message`` is the content of the message sent to the client. .. note:: The implementation relies on the fact that the order of the messages received is consistent across different trytond instances allowing to dispatch the request to any trytond server running. Notification ------------ Tryton provides a shortcut to send a notification with the ``notify`` function. .. function:: notify(title[, body[, priority[, user[, client]]]]) Send a text message to a user's client to be displayed using a notification popup. The meaning of ``title``, ``body`` and ``priority`` is defined in :ref:`bus_notification_spec`. If ``user`` is not set, the current :attr:`~trytond.transaction.Transaction.user` is used. Otherwise ``user`` is the user id to notify. If ``client`` is not set then every client of the user receives the message. If ``client`` and ``user`` are not set, the system send the notification to the current user client. Otherwise the notification is sent to the client whose id matches ``client``. .. _bus_notification_spec: Notification message ~~~~~~~~~~~~~~~~~~~~ Notification messages are composed of four parts: ``kind`` The string ``notification``. ``title`` A string containing a one-line summary of the message. ``body`` A string containing a short informative message for the user. It can span multiple lines but no markup is allowed. ``priority`` An integer between 0 (low priority) to 3 (urgent). The notification priority on the platform supporting it. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/cache.rst0000644000175000017500000000514014517761237014547 0ustar00cedced.. _ref-cache: .. module:: trytond.cache Cache ===== .. class:: Cache(name[, duration[, context[, context_ignored_keys]]]) Use to cache values between server requests. The ``name`` should be unique and it's used to identify the cache. Usually ``.`` is used to make it unique. The ``duration`` parameter defines how long a cached value stays valid but if it is not set the value remains valid until it is cleared. And the ``context`` parameter is used to indicate if the cache depends on the user context and is ``True`` by default. Keys specified in ``context_ignored_keys`` are ignored. The cache is cleaned on :class:`~trytond.transaction.Transaction` starts and resets on :class:`~trytond.transaction.Transaction` commit or rollback. .. warning:: As there is no deepcopy of the values cached, they must never be mutated after being set in or retrieved from the cache. .. attribute:: Cache.size_limit The maximal number of values cached. The value comes from the entry with the same ``name`` under the ``cache`` section of the :ref:`configuration ` using the ``default`` entry as default value. .. attribute:: Cache.hit Count the number of times the cache returned a cached value. .. attribute:: Cache.miss Count the number of times the cache did not contain the key. .. classmethod:: Cache.stats() Yield statistics for each instance. .. method:: Cache.get(key[, default]) Retrieve the value of the key in the cache. If a ``default`` is specified it is returned when the key is missing otherwise it returns ``None``. .. method:: Cache.set(key, value) Set the ``value`` of the ``key`` in the cache. .. method:: Cache.clear() Clear all the keys in the cache. .. classmethod:: Cache.clear_all() Clear all cache instances. .. classmethod:: Cache.sync(transaction) Synchronize caches between servers using :class:`transaction ` instance. .. method:: Cache.sync_since(value) Return ``True`` if the last synchronization was done before ``value``. .. classmethod:: Cache.commit(transaction) Apply cache changes from transaction. .. classmethod:: Cache.rollback(transaction) Remove cache changes from transaction. .. classmethod:: Cache.drop(dbname) Drop all caches for named database. .. note:: By default Tryton uses a MemoryCache, but this behaviour can be overridden by setting a fully qualified name of an alternative class defined in the :ref:`configuration ` ``class`` of the ``cache`` section. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/exceptions.rst0000644000175000017500000000511014517761237015662 0ustar00cedced.. _ref-exceptions: .. module:: trytond.exceptions Exceptions ========== .. exception:: TrytonException The base class for all Tryton exceptions. .. exception:: UserError(message[, description[, domain]]) The base class for exceptions used to display an error message to users. The domain may be a 2-tuple containing a :ref:`domain ` and a dictionary of field definitions used to format the domain and append to the description. .. exception:: UserWarning(name, message[, description]) The base class for exceptions used to display a warning message to users. .. exception:: LoginExceptions(name, message[, type]) The exception used to request ``name`` parameter for the login process. .. exception:: ConcurrencyException(message) The exception raised on concurrent modification. .. exception:: RateLimitException The exception raised when user has sent too many login requests. .. exception:: MissingDependenciesException(missings) The exception raised when modules are missing. .. module:: trytond.model.exceptions .. exception:: AccessError The exception raised when trying to access a record without the rights. .. exception:: AccessButtonError The exception raised when trying to execute a button without the rights. .. exception:: ButtonActionException The exception raised to launch the ``action`` instead of executing the button method. The ``value`` attribute is the action value returned. .. exception:: ImportDataError The exception raises when importing data fails. .. exception:: ValidationError The base class for all record validation error. .. exception:: DomainValidationError The exception raised when the domain of a field is not valid. .. exception:: RequiredValidationError The exception raised when a required field is empty. .. exception:: SizeValidationError The exception raised when the size of a field is too big. .. exception:: DigitsValidationError The exception raised when the value of a field does not respect its digits. .. exception:: SelectionValidationError The exception raised when the value is not in the selection. .. exception:: TimeFormatValidationError The exception raised when the time format of a field is not respected. .. exception:: ForeignKeyError The exception raised when a foreign key is not respected. .. exception:: SQLConstraintError The exception raised when a :attr:`~trytond.model.ModelSQL._sql_constraints` is not respected. .. exception:: RecursionError The exception raised by :class:`~trytond.model.TreeMixin.check_recursion`. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/fields.rst0000644000175000017500000007635314517761237014770 0ustar00cedced.. _ref-models-fields: .. module:: trytond.model.fields ====== Fields ====== .. contents:: :local: :backlinks: entry :depth: 2 Field ===== .. class:: Field Fields define the behavior of the data on model's record. The following attributes are available to all field types. All are optional except :attr:`~Field.string`. .. attribute:: Field.string A string for the label of the field. .. attribute:: Field.help A multi-line help string for the field. .. attribute:: Field.required If ``True``, the field is not allowed to be empty. Default is ``False``. .. attribute:: Field.readonly If ``True``, the field is not editable in the client. Default is ``False``. .. warning:: For relational fields, it means only the new, delete, add and remove buttons are inactivated. The editable state of the target record must be managed at the target model level. .. attribute:: Field.domain A :ref:`domain ` constraint that is applied on the field value. The domain is enforced unless the field value is ``None``. .. note:: For :class:`Reference` field it is a dictionary that contains the domain per model name. .. attribute:: Field.states A dictionary that defines dynamic states of the field and overrides the static one. Possible keys are ``required``, ``readonly`` and ``invisible``. The values are :class:`~trytond.pyson.PYSON` statements that is evaluated with the values of the record. .. attribute:: Field.on_change A set of field names. If this attribute is set, the client calls the method ``on_change_`` of the model when the user changes the current field value and will give the values of each fields in this list. The method signature is:: on_change_() This method must change the value of the fields to be updated. .. note:: The on_change_ methods are running in a readonly transaction. The set of field names is filled by using the decorator :meth:`depends`. .. attribute:: Field.on_change_with A set of field names. Same as :attr:`on_change`, but defined the other way around. If this attribute is set, the client will call the method ``on_change_with_`` of the model when the user changes one of the fields defined in the list and will give the values of each fields in this list. The method signature is:: on_change_with_() This method must return the new value of the field. .. note:: The on_change_with_ methods are running in a readonly transaction. The set of field names is filled by using the decorator :meth:`depends`. .. attribute:: Field.depends A :py:class:`set` of extra field names on which the field depends. This means that the client read also these fields even if they are not defined on the view. :attr:`Field.depends` is used for example to ensure that :class:`~trytond.pyson.PYSON` statement could be evaluated. .. attribute:: Field.display_depends A computed set of field names on which the field depends when being displayed in a read only view. .. attribute:: Field.edition_depends A computed set of field names on which the field depends when being displayed in a writable view. .. attribute:: Field.validation_depends A computed set of field names on which the field depends when being validated. .. attribute:: Field.context A dictionary which updates the current context for *relation field*. .. warning:: The context could only depend on direct field of the record and without context. .. attribute:: Field.loading Define how the field must be loaded: ``lazy`` or ``eager``. .. attribute:: Field.name The name of the field. Instance methods: .. method:: Field.convert_domain(domain, tables, Model) Convert the simple :ref:`domain ` clause into a SQL expression or a new domain. :ref:`tables ` could be updated to add new joins. .. method:: Field.sql_format(value) Convert the value to use as parameter of SQL queries. .. method:: Field.sql_type() Return the namedtuple('SQLType', 'base type') which defines the SQL type to use for definition and casting. Or ``None`` if the field is not stored in the database. sql_type is using the ``_sql_type`` attribute to compute its return value. The backend is responsible for the computation. For the list of supported types by Tryton see :ref:`backend types `. .. method:: Field.sql_cast(expression) Return the SQL expression with cast with the type of the field. .. method:: Field.sql_column(table) Return the Column instance based on table. .. method:: Field.set_rpc(model) Add to :class:`model ` the default :class:`~trytond.rpc.RPC` instances needed by the field. .. method:: Field.definition(model, language) Return a dictionary with the definition of the field. .. method:: Field.definition_translations(model, language) Return a list of translation sources used by :meth:`~Field.definition`. .. method:: Field.searchable(model) Return True if the field is searchable. .. method:: Field.sortable(model) Return True if the field is sortable. Default value ============= See :ref:`default value ` Searching ========= A class method could be defined for each field which must return a SQL expression for the given domain instead of the default one. The method signature is:: domain_(domain, tables) Where ``domain`` is the simple :ref:`domain ` clause and ``tables`` is a nested dictionary, see :ref:`tables `. Ordering ======== A class method could be defined for each field which must return a list of SQL expression on which to order instead of the field. The method signature is:: order_(tables) Where ``tables`` is a nested dictionary, see :ref:`tables `. Depends ======= .. method:: depends([\*fields[, methods]]) A decorator to define the field names on which the decorated method depends. The ``methods`` argument can be used to duplicate the field names from other decorated methods. This is useful if the decorated method calls another method. .. _ref-models-fields-types: Field types =========== Boolean ------- .. class:: Boolean(string[, \**options]) A :py:class:`boolean ` field. Integer ------- .. class:: Integer(string[, \**options]) An :py:class:`integer ` field. Char ---- .. class:: Char(string[, size[, translate[, strip[, \**options]]]]) A single line :py:class:`string ` field. Search by similarity is used for the ``ilike`` operator and :meth:`~trytond.tools.is_full_text` value if the backend supports it and a threshold is set. The similarity threshold is defined for the context key ``..search_similarity`` or ``search_similarity``. The field is ordered using the similarity with the context value from the key ``..order`` if it is set. :class:`Char` has some extra arguments: .. attribute:: Char.size The maximum length (in characters) of the field. The size is enforced at the storage level and in the client input. The value can be a :class:`~trytond.pyson.PYSON` statement. .. attribute:: Char.translate If ``True``, the value of the field is translatable. The value readed and stored will depend on the ``language`` defined in the context. .. attribute:: Char.strip If ``True``, leading and trailing whitespace are removed. If ``leading``, leading whitespace are removed. If ``trailing``, trailing whitespace are removed. The default value is ``True``. .. attribute:: Char.autocomplete A set of field names. If this attribute is set, the client calls the method ``autocomplete_`` of the :class:`model ` when the user changes one of those field values. The method signature is:: autocomplete_() This method must return a list of string that is used by the client to make autocompletion proposal. The set of field names could be filled by using the decorator :meth:`depends`. .. attribute:: Char.search_unaccented If this attribute is set to ``True``, ``ilike`` searches is performed on unaccented strings. The default value is ``True``. .. warning:: The database backend must supports unaccented search. .. attribute:: Char.search_full_text If this attribute is set to ``True``, ``ilike`` searches with an :meth:`~trytond.tools.is_full_text` value use the full text search of the backend. The default value is ``False``. The context can be used to force the full text search behaviour. This is done using the key ``..search_full_text``. If ``True``, the full text search is used no matter what the value. If ``False``, no full text search is peformed. The full text ranking value is added to the similarity if the ``search_full_text`` is ``True``. .. note:: The database backend must support full text search otherwise ``ilike`` is always used. Text ---- .. class:: Text(string[, size[, translatable[, \**options]]]) A multi line :py:class:`string ` field. :class:`Text` has some extra arguments: .. attribute:: Text.size Same as :attr:`Char.size`. .. attribute:: Text.translate Same as :attr:`Char.translate`. .. attribute:: Text.search_unaccented Same as :attr:`Char.search_unaccented`. .. attribute:: Text.search_full_text Same as :attr:`Char.search_full_text`. The default value is ``True``. FullText -------- .. class:: FullText(\**options) An internal field to store a list of parsed strings ordered by weights. The field is ordered using the full text ranking with the context value from the key ``..order`` if it is set. Float ----- .. class:: Float(string[, digits[, \**options]]) A :py:class:`floating-point number ` field. It is represented in Python by a ``float`` instance. :class:`Float` has some extra arguments: .. attribute:: Float.digits A tuple of two :py:class:`integers `. The first integer defines the total of numbers in the integer part. The second integer defines the total of numbers in the decimal part. Integers can be replaced by a :class:`~trytond.pyson.PYSON` statement. If digits is ``None`` or any values of the tuple is ``None``, no validation on the numbers is done. The tuple can be replaced by a string containing the name of a :class:`Many2One` pointing to a :class:`~trytond.model.DigitsMixin`. Numeric ------- .. class:: Numeric(string[, digits[, \**options]]) A :py:class:`fixed-point number ` field. :class:`Numeric` has some extra arguments: .. attribute:: Numeric.digits Same as :attr:`Float.digits`. Date ---- .. class:: Date(string[, \**options]) A :py:class:`date ` field. Instance methods: .. method:: Date.sql_cast(expression[, timezone]) Return the SQL expression cast as date. If timezone is set the expression is first converted to this timezone. DateTime -------- .. class:: DateTime(string[, format, \**options]) A :py:class:`date and time ` field. It is stored in `UTC`_ while displayed in the user timezone. .. _`UTC`: https://en.wikipedia.org/wiki/Coordinated_Universal_Time :class:`DateTime` has some extra arguments: .. attribute:: DateTime.format A string format as used by :py:meth:`~datetime.datetime.strftime`. This format is used to display the time part of the field. The default value is ``%H:%M:%S``. The value can be replaced by a :class:`~trytond.pyson.PYSON` statement. Timestamp --------- .. class:: Timestamp(string[, \**options]) A :py:class:`timestamp ` field. Time ---- .. class:: Time(string[, format, \**options]) A :py:class:`time ` field. :class:`Time` has some extra arguments: .. attribute:: Time.format Same as :attr:`DateTime.format`. TimeDelta --------- .. class:: TimeDelta(string[, converter[, \**options]]) An :py:class:`interval ` field. :class:`TimeDelta` has some extra arguments: .. attribute:: TimeDelta.converter The name of the context key containing the time converter. A time converter is a dictionary with the keys: ``s`` (second), ``m`` (minute), ``h`` (hour), ``d`` (day), ``w`` (week), ``M`` (month), ``Y`` (year) and the value in second. Binary ------ .. class:: Binary(string[, \**options]) A :py:class:`binary ` field. .. warning:: If the context contains a key composed of the model name and field name separated by a dot and its value is the string ``size`` then the read value is the size instead of the content. :class:`Binary` has some extra arguments: .. attribute:: Binary.filename Name of the field that holds the data's filename. Default value is an empty string, which means the data has no filename (in this case, the filename is hidden, and the "Open" button is hidden when the widget is set to "image"). .. attribute:: Binary.file_id Name of the field that holds the ``FileStore`` identifier. Default value is ``None`` which means the data is stored in the database. The field must be on the same table and accept ``char`` values. .. warning:: Switching from database to file-store is supported transparently. But switching from file-store to database is not supported without manually upload to the database all the files. .. attribute:: Binary.store_prefix The prefix to use with the ``FileStore``. Default value is ``None`` which means the database name is used. Selection --------- .. class:: Selection(selection, string[, sort[, selection_change_with[, translate[, help_selection[, \**options]]]]]) A :py:class:`string ` field with limited values to choose from. :class:`Selection` has some extra arguments: .. attribute:: Selection.selection A list of 2-tuples that looks like this:: [('M', 'Male'), ('F', 'Female')] The first element in each tuple is the actual value stored. The second element is the human-readable name. It can also be the name of a class or instance method on the model, that returns an appropriate list. The signature of the method is:: selection() .. note:: The method is automaticly added to :attr:`trytond.model.Model.__rpc__` if not manually set. .. attribute:: Selection.sort If ``True``, the choices is sorted by human-readable value. Default value is ``True``. .. note:: If it is ``False``, search results ordered by the field uses the index of the selection instead of the human-readable name. .. attribute:: Selection.selection_change_with A set of field names. If this attribute is set, the client calls the ``selection`` method of the model when the user changes on of the fields defined in the list and gives the values of each fields in the list. The ``selection`` method should be an instance method. The set of field names is filled by using the decorator :meth:`depends`. .. attribute:: Selection.translate_selection If ``True``, the human-readable values will be translated. Default value is ``True``. .. attribute:: Selection.help_selection A dictionary mapping the selection value with its help string. Class methods: .. classmethod:: Selection.get_selection(model, name, inst) Returns a :py:class:`dictionary ` mapping the selection value to its human-readable value. .. classmethod:: Selection.get_selection_string(selection, value) Returns the human-readable form of ``value`` in regard to ``selection``. ``selection`` is acquired thanks to :meth:`Selection.get_selection`. ..note:: This method should be used instead of relying on dictionary access because this method take into account the internal representation of the ``Selection`` value. Instance methods: .. method:: Selection.translated([name]) Returns a descriptor for the translated value of the field. The descriptor must be used on the same class as the field. It uses the language defined in the context of the instance accessed. MultiSelection -------------- .. class:: MultiSelection(selection, string[, sort[, translate[, help_selection[, \**options]]]]) A :py:class:`tuple` field with limited values to choose from. :class:`MultiSelection` has some extra arguments: .. attribute:: MultiSelection.selection Same as :attr:`Selection.selection`. .. attribute:: MultiSelection.sort Same as :attr:`Selection.sort`. .. attribute:: MultiSelection.translate_selection Same as :attr:`Selection.translate_selection`. .. attribute:: MultiSelection.help_selection Same as :attr:`Selection.help_selection`. Class methods: .. classmethod:: MultiSelection.get_selection(model, name, inst) Same as :meth:`Selection.get_selection` .. classmethod:: MultiSelection.get_selection_string(selection, value) Same as :meth:`Selection.get_selection_string` Instance methods: .. method:: MultiSelection.translated([name]) Same as :meth:`Selection.translated` but returns a list of translated values. Reference --------- .. class:: Reference(string[, selection[, sort[, selection_change_with[, translate[, help_selection[,search_order[, search_context[, \**options]]]]]]]]) A :py:class:`string ` field that refers to a record of a model. ',' But a ``tuple`` can be used to search or set value. :class:`Reference` has some extra arguments: .. attribute:: Reference.selection Same as :attr:`Selection.selection` but only for model name. .. attribute:: Reference.sort Same as :attr:`Selection.sort`. .. attribute:: Reference.selection_change_with Same as :attr:`Selection.selection_change_with`. .. attribute:: Reference.translate_selection Same as :attr:`Selection.translate_selection`. .. attribute:: Reference.help_selection Same as :attr:`Selection.help_selection`. .. attribute:: Reference.datetime_field Same as :attr:`Many2One.datetime_field`. .. attribute:: Reference.search_order A dictionary that contains a :ref:`PYSON ` expression defining the default order used to display search results in the clients per model name. .. attribute:: Reference.search_context Same as :attr:`Many2One.search_context`. Instance methods: .. method:: Reference.translated([name]) Same as :meth:`~Selection.translated` but for the translated name of the target model. .. method:: Reference.sql_id(column, Model) Return the SQL expression that extract the record ID of the column. Many2One -------- .. class:: Many2One(model_name, string[, left[, right[, path[, ondelete[, datetime_field[, search_order[, search_context[, \**options]]]]]]]]) A many-to-one relation field that refers to a record of the named model. A :py:class:`integer ` as :attr:`~trytond.model.Model.id` is used for low level APIs. :class:`Many2One` has some extra arguments: .. attribute:: Many2One.model_name The name of the target model. .. attribute:: Many2One.left The name of the field that stores the left value for the `Modified Preorder Tree Traversal`_. It only works if the :attr:`model_name` is the same then the model. .. warning:: The MPTT Tree will be rebuild on database update if one record is found having left or right field value equals to the default or NULL. .. _`Modified Preorder Tree Traversal`: http://en.wikipedia.org/wiki/Tree_traversal .. attribute:: Many2One.right The name of the field that stores the right value. See :attr:`left`. .. attribute:: Many2One.path The name of the :class:`Char` field that stores the path. It only works if the :attr:`model_name` is the same as the model. .. note:: The path is used to optimize searches using the ``child_of`` or ``parent_of`` operators. .. warning:: The paths in the tree will be rebuilt during the database update if any of the records are found to have a path field equal to the default, or ``NULL``. .. attribute:: Many2One.ondelete Define the behavior of the record when the target record is deleted. Allowed values are: - ``CASCADE``: tries to delete the record. - ``RESTRICT``: prevents the deletion of the target record. - ``SET NULL``: clears the relation field. ``SET NULL`` is the default setting. .. note:: ``SET NULL`` is override into ``RESTRICT`` if :attr:`~Field.required` is ``True``. .. attribute:: Many2One.datetime_field If set, the target record will be read at the date defined by the datetime field name of the record. It is usually used in combination with :attr:`~trytond.model.ModelSQL._history` to request a value for a given date and time on a historicized model. .. attribute:: Many2One.search_order A :ref:`PYSON ` expression defining the default order used to display search results in the clients. .. attribute:: Many2One.search_context A dictionary defining the default context used when searching from the client. .. note:: ``search_context`` overrides the values from the client ``context``. One2Many -------- .. class:: One2Many(model_name, field, string[, add_remove[, order[, datetime_field[, size[, search_order[, search_context[, \**options]]]]]]]) A one-to-many relation field that refers to records of the named model. It requires to have the opposite :class:`Many2One` field or a :class:`Reference` field defined on the target model. A :py:class:`tuple ` composed of :py:class:`integer ` as :attr:`~trytond.model.Model.id` is used for low level APIs. :class:`One2Many` accepts as written and created value a :py:class:`list ` of :py:class:`tuples ` like this: - ``('create', [{: value, ...}, ...])``: create new target records and link them to this one. - ``('write', ids, {: value, ...}, ...)``: write values to target ids. - ``('delete', ids)``: delete the target ids. - ``('add', ids)``: link the target ids to this record. - ``('remove', ids)``: unlink the target ids from this record. - ``('copy', ids[, {: value, ...}, ...])``: copy the target ids to this record. Optional field names and values may be added to override some of the fields of the copied records. .. note:: :class:`~trytond.pyson.PYSON` statement or :attr:`Field.depends` of target records can access value of the parent record fields by prepending ``_parent_`` to the opposite field name and followed by the dotted notation. :class:`One2Many` has some extra arguments: .. attribute:: One2Many.model_name The name of the target model. .. attribute:: One2Many.field The name of the field that handles the opposite :class:`Many2One` or :class:`Reference`. :class:`One2Many` has some extra arguments: .. attribute:: One2Many.add_remove A :ref:`domain ` to select records to add. If set, the client will allow to add/remove existing records instead of only create/delete. .. attribute:: One2Many.filter A :ref:`domain ` that is not a constraint but only a filter on the records. .. warning:: Only a static domain is allowed, it cannot contain any :class:`~trytond.pyson.PYSON` statements. .. attribute:: One2Many.order A list of tuple defining the default order of the records like for :attr:`trytond.model.ModelSQL._order`. .. attribute:: One2Many.datetime_field Same as :attr:`Many2One.datetime_field`. .. attribute:: One2Many.size An integer or a PYSON expression denoting the maximum number of records allowed in the relation. .. attribute:: One2Many.search_order Same as :attr:`Many2One.search_order`. .. attribute:: One2Many.search_context Same as :attr:`Many2One.search_context`. Instance methods: .. method:: One2Many.remove(instance, records) Remove the target records from the instance instead of deleting them. Many2Many --------- .. class:: Many2Many(relation_name, origin, target, string[, order[, datetime_field[, size[, search_order[, search_context[, \**options]]]]]]) A many-to-many relation field that refers to records of the targeted model. It requires to have the opposite origin :class:`Many2One` field or a :class:`Reference` field defined on the relation model and a :class:`Many2One` field pointing to the target. A :py:class:`tuple ` composed of :py:class:`integer ` as :attr:`~trytond.model.Model.id` is used for low level APIs. :class:`Many2Many` accepts as written and created value a :py:class:`list ` of :py:class:`tuples ` like the :class:`One2Many`. :class:`Many2Many` has some extra arguments: .. attribute:: Many2Many.relation_name The name of the relation model. .. attribute:: Many2Many.origin The name of the field that has the :class:`Many2One` or :class:`Reference` to the record. .. attribute:: Many2Many.target The name of the field that has the :class:`Many2One` to the target record. .. note:: A :class:`Many2Many` field can be used on a simple :class:`~trytond.model.ModelView`, like in a :class:`~trytond.wizard.Wizard`. For this, :attr:`~Many2Many.relation_name` is set to the target model and :attr:`~Many2Many.origin` and :attr:`~Many2Many.target` are set to ``None``. :class:`Many2Many` has some extra arguments: .. attribute:: Many2Many.order Same as :attr:`One2Many.order`. .. attribute:: Many2Many.datetime_field Same as :attr:`Many2One.datetime_field`. .. attribute:: Many2Many.size An integer or a :class:`~trytond.pyson.PYSON` expression denoting the maximum number of records allowed in the relation. .. attribute:: Many2Many.add_remove An alias to the :attr:`~Field.domain` for compatibility with the :class:`One2Many`. .. attribute:: Many2Many.filter Same as :attr:`One2Many.filter`. .. attribute:: Many2Many.search_order Same as :attr:`Many2One.search_order`. .. attribute:: Many2Many.search_context Same as :attr:`Many2One.search_context`. Instance methods: .. method:: Many2Many.get_relation() Return the relation :class:`~trytond.model.Model`. .. method:: Many2Many.get_target() Return the target :class:`~trytond.model.Model`. .. method:: Many2Many.delete(instance, records): Delete the target records from the instance instead of removing them. One2One ------- .. class:: One2One(relation_name, origin, target, string[, datetime_field[, \**options]]) A one-to-one relation field that refers to a record of the targeted model. .. warning:: It is on the relation_name :class:`~trytond.model.Model` that the unicity of the couple (origin, target) must be checked. A :py:class:`integer ` as :attr:`~trytond.model.Model.id` is used for low level APIs. :class:`One2One` has some extra arguments: .. attribute:: One2One.datetime_field Same as :attr:`Many2One.datetime_field`. .. attribute:: One2One.filter Same as :attr:`One2Many.filter`. Instance methods: .. method:: One2One.get_relation() Return the relation :class:`~trytond.model.Model`. .. method:: One2One.get_target() Return the target :class:`~trytond.model.Model`. Function -------- .. class:: Function(field, getter[, setter[, searcher[, getter_with_context]]]) A function field can emulate any other given :class:`field `. :class:`Function` has some extra arguments: .. attribute:: Function.getter The name of the classmethod or instance of the :class:`~trytond.model.Model` for getting values. The signature of the classmethod is:: getter(instances, name) where ``name`` is the name of the field, and it must return a dictionary with a value for each instance. Or the signature of the classmethod is:: getter(instances, names) where ``names`` is a list of name fields, and it must return a dictionary containing for each names a dictionary with a value for each instance. The signature of the instancemethod is:: getter(name) where ``name`` is the name of the field, and it must return the value. .. attribute:: Function.setter The name of the classmethod of the :class:`~trytond.model.Model` to set the value. The signature of the method id:: setter(instances, name, value) where ``name`` is the name of the field and ``value`` the value to set. .. warning:: The modifications made to instances are not saved automatically. .. attribute:: Function.searcher The name of the classmethod of the :class:`~trytond.model.Model` to search on the field. The signature of the method is:: searcher(name, clause) where ``name`` is the name of the field and ``clause`` is a :ref:`domain clause `. It must return a list of :ref:`domain ` clauses but the ``operand`` can be a SQL query. .. attribute:: Function.getter_with_context A boolean telling if the getter result depends on the context. If it does not depend, the getter is called without context and the result is stored in the transaction cache when readonly. The default value is ``True``. Instance methods: .. method:: Function.get(ids, model, name[, values]) Call the :attr:`~Function.getter` classmethod where ``model`` is the :class:`~trytond.model.Model` instance of the field, ``name`` is the name of the field. .. method:: Function.set(ids, model, name, value) Call the :attr:`~Function.setter` classmethod where ``model`` is the :class:`~trytond.model.Model` instance of the field, ``name`` is the name of the field, ``value`` is the value to set. .. method:: Function.search(model, name, clause) Call the :attr:`~Function.searcher` classmethod where ``model`` is the :class:`~trytond.model.Model` instance of the field, ``name`` is the name of the field, ``clause`` is a clause of :ref:`domain `. MultiValue ---------- .. class:: MultiValue(field) A multivalue field that is like a :class:`Function` field but with predefined :attr:`~Function.getter` and :attr:`~Function.setter` that use the :class:`~trytond.model.MultiValueMixin` for stored values. .. warning:: The :meth:`~trytond.model.MultiValueMixin.get_multivalue` and :meth:`~trytond.model.MultiValueMixin.set_multivalue` should be prefered over the descriptors of the field. .. warning:: The :ref:`default ` method of the field must accept pattern as keyword argument. Dict ---- .. class:: Dict(schema_model[, \**options]) A :py:class:`dictionary ` field with predefined keys. .. note:: It is possible to store the dict as JSON in the database if the backend supports by manually altering the column type to JSON on the database. :class:`Dict` has some extra arguments: .. attribute:: Dict.schema_model The name of the :class:`~trytond.model.DictSchemaMixin` model that stores the definition of keys. .. attribute:: Dict.search_unaccented Same as :attr:`Char.search_unaccented` but when searching on key's value. Instance methods: .. method:: Dict.translated([name[, type_]]) Return a descriptor for the translated ``values`` or ``keys`` of the field following ``type_``. The descriptor must be used on the same class as the field. Default ``type_`` is ``values``. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/filestore.rst0000644000175000017500000000222314517761237015477 0ustar00cedced.. _ref-filestore: .. module:: trytond.filestore FileStore ========= .. class:: FileStore() Store and retrieve files from the directory defined in the configuration ``path`` of ``database`` section. It uses a two levels of directory composed of the 2 chars of the file hash. It is an append only storage. .. method:: FileStore.get(id[, prefix]) Retrieve the content of the file referred by the id in the prefixed directory. .. method:: FileStore.getmany(ids[, prefix]) Retrieve a list of contents for the sequence of ids. .. method:: FileStore.size(id[, prefix]) Return the size of the file referred by the id in the prefixed directory. .. method:: FileStore.sizemany(ids[, prefix]) Return a list of sizes for the sequence of ids. .. method:: FileStore.set(data[, prefix]) Store the data in the prefixed directory and return the identifiers. .. method:: FileStore.setmany(data[, prefix]) Store the sequence of data and return a list of identifiers. .. note:: The class can be overridden by setting a fully qualified name of a alternative class defined in the configuration ``class`` of the ``database`` section. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/i18n.rst0000644000175000017500000000123014517761237014257 0ustar00cedced.. _ref-i18n: .. module:: trytond.i18n Internationalization ==================== .. function:: gettext(message_id, [language[, \**variables]]) Return the message translated into the ``language``. The ``message_id`` is the ``XML`` id for the ``ir.message`` that is to be translated, and the ``variables`` keyword arguments are used as a mapping to format the string. If ``language`` is not set, then the :attr:`Transaction.language ` is used. .. function:: lazy_gettext(message_id, [language[, \**variables]]) Return a LazyString that will be translated with gettext later when actually used. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/index.rst0000644000175000017500000000044314517761237014614 0ustar00cedced.. _ref-index: ============= API Reference ============= Reference of the ``trytond`` API: .. toctree:: :maxdepth: 1 models fields wizard pyson transaction exceptions backend tools/index pool rpc i18n sendmail filestore cache bus tests ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1707150267.0 trytond-7.0.30/doc/ref/models.rst0000644000175000017500000010026114560205673014762 0ustar00cedced.. _ref-models: .. module:: trytond.model ====== Models ====== .. contents:: :local: :backlinks: entry :depth: 2 Model ===== .. class:: Model([id[, \**kwargs]]) The base class that every kind of :ref:`model ` inherits. Class attributes are: .. attribute:: Model.__name__ The a unique name to reference the model throughout the platform. .. attribute:: Model.__access__ A set that contains the names of relation field for which the access rights are also checked for this model. .. attribute:: Model.__rpc__ A dictionary with method name as key and an instance of :class:`~trytond.rpc.RPC` as value. .. attribute:: Model._rec_name The name of the field used as name of records. The default value is ``name``. .. attribute:: Model.id The definition of the :class:`~trytond.model.fields.Integer` field ``id`` of records. .. attribute:: Model.__queue__ Return a queue caller for the model. The called method will be pushed into the queue. .. attribute:: Model._fields A dictionary with the field name as key and its :class:`~fields.Field` instance as value. .. attribute:: Model._record The record class to store internaly the values of the instances. .. attribute:: Model._defaults A dictionary with the field name as key and its default method as value. Class methods: .. classmethod:: Model.__setup__() Setup the class before adding into the :class:`~trytond.pool.Pool`. See :meth:`trytond.pool.PoolBase.__setup__`. .. classmethod:: Model.__post_setup__() Setup the class after added into the :class:`~trytond.pool.Pool`. See :meth:`trytond.pool.PoolBase.__post_setup__`. .. classmethod:: Model.__register__(module_name) Register the model in ``ir.model`` and ``ir.model.field``. See :meth:`trytond.pool.PoolBase.__register__`. .. classmethod:: Model.default_get(fields_names[, with_rec_name]) Return a dictionary with the default values for each field in ``fields_names``. Default values are defined by the returned value of each instance method with the pattern ``default_()``. ``with_rec_name`` allow to add ``rec_name`` value for each many2one field. The ``default_rec_name`` key in the context can be used to define the value of the :attr:`~Model._rec_name` field. The ``default_`` keys in the context can be used to define the value of the field. .. classmethod:: Model.fields_get([fields_names[, level]]) Return the definition of each field on the model. ``level`` defines the number of relations to include in the relation field definition. .. classmethod:: Model.__names__([field[, record]]) Return a dictionary with the name of the ``model``, the ``field`` and the ``record`` and the ``value`` of the field. It is a convenience-method used to format messages which should include those names. Instance methods: .. method:: Model.pre_validate() Validate the instance before being stored. This method is called by the client to validate the instance. ModelView ========= .. class:: ModelView Add the requirements to display the record in a view. Class attributes: .. attribute:: ModelView._buttons A dictionary with button name as key and the states dictionary for the button. The keys are ``invisible``, ``readonly`` and ``icon`` which have a :class:`~trytond.pyson.PYSON` statement as value and ``depends`` which has a list of field names on which the states depend. This is used as default attributes of the buttons for the views that show them. Static methods: .. staticmethod:: ModelView.button() Decorate button's method to check group access and rule. .. staticmethod:: ModelView.button_action(action) Same as :meth:`~ModelView.button` but return the id of the XML id action or the action value updated by the returned value of the method. .. staticmethod:: ModelView.button_change([\*fields[, methods]]) Same as :meth:`~ModelView.button` but for button that change values of the fields on client side (similar to :ref:`on_change `). ``methods`` can be used to duplicate the field names from other decorated methods. This is useful if the decorated method calls another method. .. note:: Only on instance methods. Class methods: .. classmethod:: ModelView.fields_view_get([view_id[, view_type[, level]]]) Return a view definition used by the client. The definition is:: { 'model': model name, 'type': view type, 'view_id': view id, 'arch': XML description, 'fields': { field name: { ... }, }, 'field_childs': field for tree, } .. classmethod:: ModelView.view_toolbar_get() Returns the model specific actions and exports in a dictionary with keys: ``print`` a list of available reports. ``action`` a list of available actions. ``relate`` a list of available relations. ``exports`` a list of available exports. .. classmethod:: ModelView.view_attributes() Returns a list of XPath, attribute, value and an optional depends list. Each element from the XPath will get the attribute set with the JSON encoded value. If the depends list is set its fields are added to the view if the xpath matches at least one element. .. note:: The ``view_id`` is set to the :attr:`~trytond.transaction.Transaction.context` when this method is called. .. classmethod:: ModelView.parse_view(tree, type[, view_id[, field_children[, level[, view_depends]]]]) Return the sanitized XML and the corresponding fields definition. .. note:: This method is public mainly to allow modification the existing XML of the view by code. Instance methods: .. method:: ModelView.on_change(fieldnames) Return the list of changes by calling ``on_change`` method of each field. .. method:: ModelView.on_change_with(fieldnames) Return the new values of all fields by calling ``on_change_with`` method of each field. .. method:: ModelView.on_change_notify(fieldnames) Returns a list of type and message couple to display on the client side. Available types are ``info``, ``warning`` and ``error``. .. note:: To be called by the client, this method must be decorated by :meth:`~trytond.model.fields.depends` with the fields needed. .. method:: ModelView.on_scan_code(code) Modify the instance when ``code`` is scanned. If the instance is not modified the scan loop ends. .. note:: When extended, this method must be decorated by :meth:`~trytond.model.fields.depends` with the fields used. .. method:: ModelView.autocomplete(text[, domain[, limit[, order]]]) Return a list of dictionary for records completing ``text``. The dictionary is composed of ``id``, ``name`` and ``defaults``. The client call this method to provide completion. .. note:: The ``defaults`` is used when ``id`` is empty to get the default values for the record to create. ModelStorage ============ .. class:: ModelStorage Add storage capability of record. Class attributes are: .. attribute:: ModelStorage.create_uid The definition of the :class:`~fields.Many2One` field that points to the user who created the record. .. attribute:: ModelStorage.create_date The definition of the :class:`~fields.Timestamp` field that stores the creation time of the record. .. attribute:: ModelStorage.write_uid The definition of the :class:`~fields.Many2One` field that points to the last user who modified the record. .. attribute:: ModelStorage.write_date The definition of the :class:`~fields.Timestamp` field that stored the last modification time of the record. .. attribute:: ModelStorage.rec_name The name of the :class:`~fields.Field` used as record name. Static methods: .. staticmethod:: ModelStorage.default_create_uid() Return the default value for :attr:`create_uid`. .. staticmethod:: ModelStorage.default_create_date() Return the default value for :attr:`create_date`. Class methods: .. classmethod:: ModelStorage.log(records, event[, target[, user[, \**extra]]]) Log event for records. .. classmethod:: ModelStorage.create(vlist) Create records. ``vlist`` is list of dictionaries with fields names as key and created values as value and return the list of new instances. .. classmethod:: ModelStorage.trigger_create(records) Trigger create actions. It calls actions defined in ``ir.trigger`` with ``on_create`` set and ``condition`` is true. .. classmethod:: ModelStorage.read(ids, fields_names) Return a list of dictionary for the record ids. The dictionary is composed of the fields as key and their values. ``fields_names`` can contain dereferenced fields from related models. Their values will be returned under the referencing field suffixed by a ``.``. The number of *dots* in the name is not limited. ``fields_names`` can also contain ``:string`` for :class:`~fields.Selection` or :class:`~fields.MultiSelection` fields. Their human-readable value are returned. The virtual fields ``_write`` and ``_delete`` can be used the read the writeable and deleteable state of the records. Regarding the ``_timestamp`` virtual fields it contains a timestamp that is used in the context to make a soft lock preventing update collisions. .. note:: The order of the returned list is not guaranteed. .. classmethod:: ModelStorage.index_get_field(name) Return the index to order of the calls to field get. .. classmethod:: ModelStorage.write(records, values, [[records, values], ...]) Write ``values`` on the list of records. ``values`` is a dictionary with fields names as key and writen values as value. .. classmethod:: ModelStorage.trigger_write_get_eligibles(records) Return eligible records for write actions by triggers. This dictionary is to pass to :meth:`~ModelStorage.trigger_write`. .. classmethod:: ModelStorage.trigger_write(eligibles) Trigger write actions. It will call actions defined in ``ir.trigger`` with ``on_write`` set and ``condition`` was false before :meth:`~ModelStorage.write` and true after. .. classmethod:: ModelStorage.index_set_field(name) Return the index to order of the calls to field set. .. classmethod:: ModelStorage.delete(records) Delete records. .. classmethod:: ModelStorage.trigger_delete(records) Trigger delete actions. It will call actions defined in ``ir.trigger`` with ``on_delete`` set and ``condition`` is true. .. classmethod:: ModelStorage.copy(records[, default]) Duplicate the records. ``default`` is a dictionary of default value per field name for the created records. The values of ``default`` may be also callable that take a dictionary containing the fields and values of the record copied and return of the value. The keys of ``default`` may use the dotted notation for the :class:`~fields.One2Many` to define the default to pass to its ``copy`` operation. New records are returned following the input order. .. classmethod:: ModelStorage.search(domain[, offset[, limit[, order[, count]]]]) Return a list of records that match the :ref:`domain `. If ``offset`` or ``limit`` are set, the result starts at the offset and has the length of the limit. The ``order`` is a list of tuples defining the order of the result:: [ ('field name', 'ASC'), ('other field name', 'DESC'), ... ] The first element of the tuple is a field name of the model and the second is the sort ordering as ``ASC`` for ascending, ``DESC`` for descending or empty for a default order. This second element may contain ``NULLS FIRST`` or ``NULLS LAST`` to sort null values before or after non-null values. If neither is specified the default behavior of the backend is used. In case the field used is a :class:`~fields.Many2One`, it is also possible to use the dotted notation to sort on a specific field from the target record. Or for a :class:`~fields.Dict` field, the dotted notation is used to sort on the key's value. If ``count`` is set to ``True``, then the result is the number of records. The count result is limited upto the value of ``limit`` if set. .. classmethod:: ModelStorage.search_count(domain[, offset[, limit]]) Return the number of records that match the :ref:`domain `. The result is limited upto the value of ``limit`` if set and reduced by offset. .. classmethod:: ModelStorage.search_read(domain[, offset[, limit[, order[, fields_names]]]]) Call :meth:`search` and :meth:`read` at once. Useful for the client to reduce the number of calls. .. classmethod:: ModelStorage.search_rec_name(name, clause) :attr:`~fields.Function.searcher` for the :class:`~fields.Function` field :attr:`rec_name`. .. classmethod:: ModelStorage.search_global(cls, text) Yield tuples (record, name, icon) for records matching text. It is used for the global search. .. classmethod:: ModelStorage.estimated_count() Return an estimation of the number of records stored. .. classmethod:: ModelStorage.browse(ids) Return a list of record instance for the ``ids``. .. classmethod:: ModelStorage.export_data(records, fields_names[, header]) Return a list of list of values for each ``records``. The list of values follows ``fields_names``. The result includes the description of the fields if ``header`` is set. Relational fields are defined with ``/`` at any depth. Descriptor on fields are available by appending ``.`` and the name of the method on the field that returns the descriptor. .. classmethod:: ModelStorage.export_data_domain(domain, fields_names[, offset[, limit[, order[, header]]]]) Call :meth:`search` and :meth:`export_data` together. Useful for the client to reduce the number of calls and the data transfered. .. classmethod:: ModelStorage.import_data(fields_names, data) Create or update records for all values in ``data``. The field names of values must be defined in ``fields_names``. It returns the number of imported records. .. classmethod:: ModelStorage.check_xml_record(records, values) Raise an :exc:`~trytond.model.exceptions.AccessError` if the records can not be modified because they originate from XML data. ``values`` is a dictionary of written values or ``None`` for deletion. It is used by :meth:`~ModelStorage.write` and :meth:`~ModelStorage.delete` to prevent modification of data coming from XML files. .. note:: This method must be overiden to change this behavior. .. classmethod:: ModelStorage.validate(records) Validate the integrity of records after creation and modification. This method must be overridden to add validation and must raise an :exc:`~trytond.model.exceptions.ValidationError` if validation fails. .. classmethod:: ModelStorage.validate_fields(records, field_names) Validate the integrity of records after modification of the fields. This method must be overridden to add validation for the field names set and must raise an exception if validation fails. Dual methods: .. classmethod:: ModelStorage.save(records) Save the modification made on the records. .. warning:: Fields that have a container as a value must be reassigned to the parent record in order to be saved when the parent record is saved. Instance methods: .. method:: ModelStorage.resources() Return a dictionary with the number of attachments (``attachment_count``), notes (``note_count``) and unread note (``note_unread``). .. method:: ModelStorage.get_rec_name(name) :attr:`~fields.Function.getter` for the :class:`~fields.Function` field :attr:`rec_name`. ModelSQL ======== .. class:: ModelSQL Implement :class:`ModelStorage` for an SQL database. Class attributes are: .. attribute:: ModelSQL._table The name of the database table which is mapped to the class. If not set, the value of :attr:`~Model.__name__` is used with dots converted to underscores. .. attribute:: ModelSQL._order The default ``order`` parameter of :meth:`~ModelStorage.search` method. .. attribute:: ModelSQL._order_name The name of the field on which the records must be sorted when sorting on a field refering to the model. If not set, :attr:`~Model._rec_name` is used. .. attribute:: ModelSQL._history If true, all changes on records are stored in an history table. .. attribute:: ModelSQL._sql_constraints A list of SQL constraints that are added on the table:: [ (, , ), ... ] constraint name The name of the SQL constraint in the database. constraint An instance of :class:`Constraint` xml id The message id for :meth:`~trytond.i18n.gettext` .. attribute:: ModelSQL._sql_indexes A :py:class:`set ` containing the :class:`Index` that are created on the table. Class methods: .. classmethod:: ModelSQL.__table__() Return a SQL Table instance for the Model. .. classmethod:: ModelSQL.__table_history__() Return a SQL Table instance for the history of Model. .. classmethod:: ModelSQL.__table_handler__([module_name[, history]]) Return a :class:`~trytond.backend.TableHandler` instance for the Model. .. classmethod:: ModelSQL.table_query() Could be defined to use a custom SQL query instead of a table of the database. It should return a SQL FromItem. .. warning:: By default all CRUD operation raises an error on models implementing this method so the :meth:`~ModelStorage.create`, :meth:`~ModelStorage.write` and :meth:`~ModelStorage.delete` methods may also been overriden if needed. .. classmethod:: ModelSQL.history_revisions(ids) Return a sorted list of all revisions for ids. The list is composed of the date, id and username of the revision. .. classmethod:: ModelSQL.restore_history(ids, datetime) Restore the record ids from history at the specified date time. Restoring a record still generates an entry in the history table. .. warning:: No access rights are verified, the restored records are not validated and no triggers are called. .. classmethod:: ModelSQL.restore_history_before(ids, datetime) Restore the record ids from history before the specified date time. Restoring a record still generates an entry in the history table. .. warning:: No access rights are verified, the restored records are not validated and not triggers are called. .. classmethod:: ModelSQL.search(domain[, offset[, limit[, order[, count[, query]]]]]) Same as :meth:`ModelStorage.search` with the additional ``query`` argument. The ``domain`` is converted by :meth:`~ModelSQL.search_domain`. If ``query`` is set to ``True``, the the result is the SQL query. .. classmethod:: ModelSQL.search_domain(domain[, active_test[, tables]]) Convert a :ref:`domain ` into a SQL expression by returning the updated tables dictionary and a SQL expression. If ``active_test`` is set to ``False``, no clause against :attr:`DeactivableMixin.active` field is added to the domain. .. _ref-tables: Where ``tables`` is a nested dictionary containing the existing joins:: { None: (, None), 'party': { None: (
, ), 'addresses': { None: (
, ), }, }, } Dual methods: .. classmethod:: ModelSQL.lock([records]) Take a lock for update on the records or take a lock on the whole table. Constraint ---------- .. class:: Constraint(table) Represent a SQL constraint for the ``table``. Instance attributes: .. attribute:: Constraint.table The SQL Table on which the constraint is defined. Check ^^^^^ .. class:: Check(table, expression) Represent a check :class:`Constraint` which enforce the validity of the ``expression``. Instance attributes: .. attribute:: Check.expression The SQL expression to check. Unique ^^^^^^ .. class:: Unique(table, \*columns) Represent a unique :class:`Constraint` which enforce the uniqueness of the group of columns. Instance attributes: .. attribute:: Unique.columns The tuple of SQL Column instances. .. attribute:: Unique.operators The tuple of ``Equal`` operators. Exclude ^^^^^^^ .. class:: Exclude(table[, (expression, operator), ...[, where]]) Represent an exclude :class:`Constraint` which guarantees that if any two rows are compared on the specified expression using the specified operator not all of these comparisons will return ``TRUE``. Instance attributes: .. attribute:: Exclude.excludes The tuple of expression and operator. .. attribute:: Exclude.columns The tuple of expressions. .. attribute:: Exclude.operators The tuple of operators. .. attribute:: Exclude.where The clause for which the exclusion applies. Index ----- .. class:: Index(table[, \*expressions, [, \*\*options]]) Represent a SQL index for the ``table`` for the sequence of ``expressions``. An ``expression`` is a :py:class:`tuple ` of SQL expression and a :attr:`~Index.Usage`. Available options are: * ``include``: a list of columns to include in the index * ``where``: the where clause for partial index .. attribute:: Index.Unaccent(expression) Apply unaccent function if the database supports it. .. attribute:: Index.Usage(\*\*options) Represent a usage of a SQL expression. Available options are: * ``collation``: the name of the collation * ``order``: the sort order .. attribute:: Index.Equality(\*\*options) Represent an equality usage. .. attribute:: Index.Range(\*\*options) Represent an range usage. .. attribute:: Index.Similarity(\*\*options) Represent a similar usage only for text. Additional options are available: * ``begin``: optimize for constant pattern and anchored to the beginning of the string convert_from ------------ .. method:: convert_from(table, tables[, type_]) Return a SQL ``FromItem`` constructed by joining ``table`` and :ref:`tables ` using ``type_`` with default value ``LEFT``. Workflow ======== .. class:: Workflow A mixin_ to handle transition check. Class attribute: .. attribute:: Workflow._transition_state The name of the field that will be used to check state transition. The default value is 'state'. .. attribute:: Workflow._transitions A set containing tuples of from and to state. Static methods: .. staticmethod:: Workflow.transition(state) Decorate method to filter records for which the transition is valid and finally to update the state of the filtered record. ModelSingleton ============== .. class:: ModelSingleton Modify :class:`ModelStorage` into a singleton_. This means that there will be only one record of this model. It is commonly used to store configuration value. .. _singleton: http://en.wikipedia.org/wiki/Singleton_pattern Class methods: .. classmethod:: ModelSingleton.get_singleton() Return the instance of the unique record if there is one. DictSchemaMixin =============== .. class:: DictSchemaMixin A mixin_ for the schema of :class:`~fields.Dict` field. Class attributes are: .. attribute:: DictSchemaMixin.name A :class:`~fields.Char` field for the name of the key. .. attribute:: DictSchemaMixin.string A :class:`~fields.Char` field for the string of the key. .. attribute:: DictSchemaMixin.help The :class:`~fields.Char` field used as the help text for the key. .. attribute:: DictSchemaMixin.type\_ The :class:`~fields.Selection` field for the type of the key. The available types are: * boolean * integer * char * float * numeric * date * datetime * selection .. attribute:: DictSchemaMixin.digits The :class:`~fields.Integer` field for the digits number when the type is ``float`` or ``numeric``. .. attribute:: DictSchemaMixin.domain A :ref:`domain ` constraint on the dictionary key that will be enforced only on the client side. The key must be referenced by its name in the left operator of the domain. The :ref:`PYSON ` evaluation context used to compute the domain is the dictionary value. Likewise the domain is tested using the dictionary value. .. attribute:: DictSchemaMixin.selection The :class:`~fields.Text` field to store the couple of key and label when the type is ``selection``. The format is a key/label separated by ":" per line. .. attribute:: DictSchemaMixin.selection_sorted If the :attr:`selection` must be sorted on label by the client. .. attribute:: DictSchemaMixin.selection_json The :class:`~fields.Function` field to return the JSON_ version of the :attr:`selection`. Static methods: .. staticmethod:: DictSchemaMixin.default_digits() Return the default value for :attr:`digits`. Class methods: .. classmethod:: DictSchemaMixin.get_keys(records) Return the definition of the keys for the records. .. classmethod:: DictSchemaMixin.get_relation_fields() Return a dictionary with the field definition of all the keys like the result of :meth:`Model.fields_get`. It is possible to disable this method (returns an empty dictionary) by setting in the ``dict`` section of the configuration, the :attr:`Model.__name__` to ``False``. Instance methods: .. method:: DictSchemaMixin.get_selection_json(name) :attr:`~fields.Function.getter` for the :attr:`selection_json`. .. method:: DictSchemaMixin.format(value[, lang]) Format the value using the key definition and the language. MatchMixin ========== .. class:: MatchMixin A mixin_ to add to a :class:`Model` a match method on pattern. The pattern is a dictionary with field name as key and the value to compare. The record matches the pattern if for all dictionary entries, the value of the record is equal or not defined. Instance methods: .. method:: MatchMixin.match(pattern[, match_none]) Return if the instance match the pattern. If ``match_none`` is set ``None`` value of the instance will be compared. UnionMixin ========== .. class:: UnionMixin A mixin_ to create a :class:`ModelSQL` which is the UNION_ of some :class:`ModelSQL`'s. The ids of each models are sharded to be unique. Static methods: .. staticmethod:: UnionMixin.union_models() Return the list of :class:`ModelSQL`'s names Class methods: .. classmethod:: UnionMixin.union_shard(column, model) Return a SQL expression that shards the column containing record id of model name. .. classmethod:: UnionMixin.union_unshard(record_id) Return the original instance of the record for the sharded id. .. classmethod:: UnionMixin.union_column(name, field, table, Model) Return the SQL column that corresponds to the field on the union model. .. classmethod:: UnionMixin.union_columns(model) Return the SQL table and columns to use for the UNION for the model name. SymbolMixin =========== .. class:: SymbolMixin A mixin_ to manage the display of symbols on the client side. Instance methods: .. method:: SymbolMixin.get_symbol(sign, [symbol]) Return a symbol and its position. The position indicates whether the symbol should appear before (0) or after (1) the value. If no symbol parameter is supplied then the mixin uses the value of attribute named ``symbol``. DigitsMixin =========== .. class:: DigitsMixin A mixin_ to manage the digits of :attr:`fields.Float.digits` and :attr:`fields.Numeric.digits` from a :class:`Model`. Instance methods: .. method:: DigitsMixin.get_digits() Return a tuple of two integers to use a ``digits`` attribute. sequence_ordered ================ .. function:: sequence_ordered([field_name, [field_label, [order]]]) Return a mixin_ class which defines the order of a :class:`ModelSQL` with an :class:`~fields.Integer` field. ``field_name`` indicates the name of the field to be created and its default values is ``sequence``. ``field_label`` defines the label which will be used by the field and defaults to ``Sequence``. Order specifies the order direction and defaults to ``ASC NULLS FIRST``. sort ==== .. function:: sort(records, order) Return a new list of records ordered by the ``order`` list defined like in :meth:`~ModelStorage.search`. MultiValueMixin =============== .. class:: MultiValueMixin A mixin_ for :class:`Model` to help having :class:`~fields.MultiValue` fields with multi-values on a :class:`ValueMixin`. The values are stored by creating one record per pattern. The patterns are the same as those on :class:`MatchMixin`. Class methods: .. classmethod:: MultiValueMixin.multivalue_model(field) Return the :class:`ValueMixin` on which the values are stored for the field name. The default is class name suffixed by the field name. .. classmethod:: MultiValueMixin.setter_multivalue(records, name, value, \*\*pattern) :attr:`~fields.Function.getter` method for the :class:`trytond.model.fields.Function` fields. Instance methods: .. method:: MultiValueMixin.multivalue_records(field) Return the list of all :class:`ValueMixin` records linked to the instance. By default, it returns the value of the first found :class:`~fields.One2Many` linked to the multivalue model or all the records of this one. .. method:: MultiValueMixin.multivalue_record(field, \*\*pattern) Return a new record of :class:`ValueMixin` linked to the instance. .. method:: MultiValueMixin.get_multivalue(name, \*\*pattern) Return the value of the field ``name`` for the pattern. .. method:: MultiValueMixin.set_multivalue(name, value[, save], \*\*pattern) Store the value of the field ``name`` for the pattern. If ``save`` is true, it will be stored in the database, otherwise the modified :class:`ValueMixin` records are returned unsaved. ``save`` is true by default. .. warning:: To customize the pattern, both methods must be override the same way. ValueMixin ========== .. class:: ValueMixin A mixin_ to store the values of :class:`MultiValueMixin`. DeactivableMixin ================ .. class:: DeactivableMixin A mixin_ to add soft deletion to the model. It renders all the fields as read-only when the record is inactive. Class attributes are: .. attribute:: DeactivableMixin.active The definition of the :class:`trytond.model.fields.Boolean` field to store soft deletion state. False values is considered as soft deletion. tree ==== .. function:: tree([parent[, name[, separator]]]) Return a mixin_ class :class:`TreeMixin`. ``parent`` indicates the name of the field that defines the parent of the tree and its default value is ``parent``. ``name`` indicates the name of the field that defines the name of the record and its default value is ``name``. If ``separator`` is set, the :meth:`~ModelStorage.get_rec_name` constructs the name by concatenating each parent names using it as separator and :meth:`~ModelStorage.search_rec_name` is adapted to search across the tree. .. class:: TreeMixin .. classmethod:: TreeMixin.check_recursion(records) Helper method that checks if there is no recursion in the tree defined by :meth:`tree`. .. function:: sum_tree(records, values[, parent]) Helper method to sum ``values`` following up ``records`` tree using ``parent``. ``records`` must contain a complete branch of the tree. ``values`` is a dictionary with record id as key. avatar_mixin ============ .. function:: avatar_mixin([size[, default]]) Return a mixin_ :class:`AvatarMixin`. ``size`` defines the size of the avatar image and its default value is ``64``. ``default`` indicates the name of the field to use for generating a default avatar, if it's not set then no default avatar is generated. .. class:: AvatarMixin .. attribute:: AvatarMixin.avatars The :class:`~fields.One2Many` field used to store the ``ir.avatar`` records. .. attribute:: AvatarMixin.avatar The :class:`~fields.Binary` field that contains the avatar. .. attribute:: AvatarMixin.avatar_url The :class:`~fields.Char` field that containts the URL for the avatar. .. attribute:: AvatarMixin.has_avatar Indicate whether the record has an avatar. .. classmethod:: AvatarMixin.generate_avatar(records, field) Generate a default avatar for each record using the field. .. _mixin: http://en.wikipedia.org/wiki/Mixin .. _JSON: http://en.wikipedia.org/wiki/Json .. _UNION: http://en.wikipedia.org/wiki/Union_(SQL)#UNION_operator ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/pool.rst0000644000175000017500000000377114517761237014465 0ustar00cedced.. _ref-pool: .. module:: trytond.pool Pool ==== .. class:: Pool([database_name]) Store the instances of :class:`~trytond.model.Model`, :class:`~trytond.wizard.Wizard` and *Report* per database. Static methods: .. staticmethod:: Pool.register(klass, ..., type_, module[, depends]) Register the classes of type (``model``, ``report`` or ``wizard``) for the module. If ``depends`` is set, the registration happens only if all the modules are activated. .. staticmethod:: Pool.register_mixin(mixin, classinfo, module) Register the mixin for the module. The ``mixin`` are included to all subclasses of ``classinfo``. Class methods: .. classmethod:: Pool.start() Start the pool by registering all Tryton modules found. .. classmethod:: Pool.stop(database_name) Stop the pool by removing instances for the database. .. classmethod:: Pool.database_list() List all started databases. Instance methods: .. method:: Pool.get(name[, type]) Return the named object of ``type`` from the pool. .. method:: Pool.iterobject([type]) Return an interator over objects of ``type``. .. method:: Pool.fill(module, modules) Fill the pool with the registered classes from the module and for the activated modules and return a list of classes for each type in a dictionary. .. method:: Pool.setup([classes]) Call all setup methods of the classes provided or for all the registered classes. .. method:: Pool.setup_mixin([type[, name]]) Include all the mixin registered for the filled modules to the corresponding registered type of classes or named. PoolMeta -------- .. class:: PoolMeta A metaclass helper to setup __name__ on class to be registered in the :class:`Pool`. PoolBase -------- .. class:: PoolBase The base class of registered classes. Class methods: .. classmethod:: PoolBase.__setup__() Setup the class. .. classmethod:: PoolBase.__post_setup__() Post setup the class. .. classmethod:: PoolBase.__register__() Registare the class. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/pyson.rst0000644000175000017500000002112314517761237014653 0ustar00cedced.. _ref-pyson: .. module:: trytond.pyson PYSON ===== PYSON is the Python Statement and Object Notation. There is also a more :ref:`practical introduction into PYSON statements `. .. class:: PYSON Base class of any PYSON statement. It is never used directly. Instance methods: .. method:: PYSON.pyson() Return the internal dictionary representation of the statement. .. method:: PYSON.types() Return a set of all possible types which the statement can become when evaluated. Class methods: .. classmethod:: PYSON.eval(dct, context) Return the evaluation of the statement given in ``dct`` within the ``context``. ``dct`` contains a dictionary which is the internal representation of a PYSON statement. ``context`` contains a dictionary with contextual values. Encoder and Decoder ------------------- .. class:: PYSONEncoder() Encoder for PYSON statements into string representations. Instance methods: .. method:: PYSONEncoder.encode(object) Return a string representation of a given PYSON statement. ``object`` contains a PYSON statement. .. class:: PYSONDecoder([context[, noeval]]) Decoder for string into the evaluated or not PYSON statement. Instance methods: .. method:: PYSONDecoder.decode(object) Return a PYSON statement evaluated or not of a given string. ``object`` contains a string. Statements ---------- The following classes can be used as :class:`PYSON` statement: .. contents:: :local: :backlinks: entry :depth: 1 Eval ^^^^ .. class:: Eval(value[, default]) Represent the PYSON statement for evaluations. When evaluated, it returns the value of the statement named by ``value``, if defined in the evaluation context, otherwise the ``default`` value (empty string by default). .. note:: The default value determines the type of the statement. .. note:: If the ``value`` includes dots the value will be dereferenced. For example:: Eval('_parent_sale.number') The ``number`` value of the ``_parent_sale`` key of the evaluation context will be returned. Not ^^^ .. class:: Not(value) Represent the PYSON statement for logical negations. When evaluated, returns the boolean negation of the value of the statement named by ``value``, if defined in the evaluation context. Returns an instance of itself. Bool ^^^^ .. class:: Bool(value) Represent the PYSON statement for boolean evaluations. Returns the boolean representation of the value of the statement named by ``value``. And ^^^ .. class:: And(\*statements) Represent the PYSON statement for logical *and* operations. Returns the result of the logical conjunction of two or more values named by the statements in the ``statements`` tuple. Or ^^ .. class:: Or(\*statements) Represent the PYSON statement for logical *or* operations. Returns the result of the logical disjunction of two or more values named by the statements in the ``statements`` tuple. Equal ^^^^^ .. class:: Equal(statement1, statement2) Represent the PYSON statement for equation comparisons. Returns ``True`` when a value of a statement named by ``statement1`` and the value of a statement named by ``statement2`` are equal, otherwise returns ``False``. Greater ^^^^^^^ .. class:: Greater(statement1, statement2[, equal]) Represent the PYSON statement for *greater-than* comparisons. Returns ``True`` when the value of the statement named by ``statement1`` is strictly greater than the value of the statement named by ``statement2``, otherwise returns false. Is the value of the variable named by ``equal`` is ``True``, then returns also ``True`` when both values of statements named by ``statement1`` and ``statement2`` are equal. In this case :class:`Greater` works as a *greater-than or equal* operator. .. note:: ``None`` value is replaced by ``0`` for the comparison. Less ^^^^ .. class:: Less(statement1, statement2[, equal]) Represent the PYSON statement for *less-than* comparisons. Returns ``True`` when the value of the statement named by ``statement1`` is strictly less than the value of the statement named by ``statement2``, otherwise returns ``False``. Is the value of the variable named ``equal`` is true, then returns also true when both values of the statements named by ``statement1`` and ``statement2`` are equal. In this case :class:`Less` works as a *less-than or equal* operator. .. note:: ``None`` value is replaced by ``0`` for the comparison. If ^^ .. class:: If(condition, then_statement, else_statement) Represent the PYSON statement for conditional flow control operations. Returns the value of the statement named by ``then_statement`` when the value of the statement named by ``condition`` evaluates true. Otherwise returns the value of the statement named by ``else_statement``. Get ^^^ .. class:: Get(obj, key[, default]) Represent the PYSON statement for dictionary look-up operations and evaluation. Look up and returns the value of a key named by ``key`` in an object named by ``obj`` if defined. Otherwise returns the value of the variable named by ``default``. In ^^ .. class:: In(key, obj) Represent the PYSON statement for look-up dictionary or integer objects. Returns true when a list (or dictionary) object named by ``obj`` contains the value of the variable (or key) named by ``key``. Otherwise returns false. Date ^^^^ .. class:: Date([year[, month[, day[, delta_years[, delta_month[, delta_days[, start]]]]]]]) Represent the PYSON statement for date related conversions and basic calculations. Returns a date object which represents the values of arguments named by the *variables* explained below. Missing values of arguments named by ``year`` or ``month`` or ``day`` take their defaults from ``start`` or the actual date. When values of arguments named by ``delta_*`` are given, they are added to the values of the appropriate arguments in a date and time preserving manner. Arguments: ``year`` A PYSON statement of type int or long. ``month`` A PYSON statement of type int or long. ``day`` A PYSON statement of type int or long. ``delta_years`` A PYSON statement of type int or long. ``delta_month`` A PYSON statement of type int or long. ``delta_days`` A PYSON statement of type int or long. ``start`` A PYSON statement of type date. DateTime ^^^^^^^^ .. class:: DateTime([year[, month[, day[, hour[, minute[, second[, microsecond[, delta_years[, delta_months[, delta_days[, delta_hours[, delta_minutes[, delta_seconds[, delta_microseconds[, start]]]]]]]]]]]]]]]) Represent the PYSON statement for date and time related conversions and calculations. Returns a date time object which represents the values of variables named by the *arguments* explained below. Missing values of arguments named by ``year``, ``month``, ``day``, ``hour``, ``minute``, ``second``, ``microseconds`` take their defaults from ``start`` or the actual date and time in `UTC`_. When values of arguments named by ``delta_*`` are given, these are added to the appropriate attributes in a date and time preserving manner. Arguments: ``year`` A PYSON statement of type int or long. ``month`` A PYSON statement of type int or long. ``day`` A PYSON statement of type int or long. ``hour`` A PYSON statement of type int or long. ``minute`` A PYSON statement of type int or long. ``second`` A PYSON statement of type int or long. ``microsecond`` A PYSON statement of type int or long. ``delta_years`` A PYSON statement of type int or long. ``delta_month`` A PYSON statement of type int or long. ``delta_days`` A PYSON statement of type int or long. ``delta_hours`` A PYSON statement of type int or long. ``delta_minutes`` A PYSON statement of type int or long. ``delta_seconds`` A PYSON statement of type int or long. ``delta_microseconds`` A PYSON statement of type int or long. ``start`` A PYSON statement of type datetime. .. _`UTC`: https://en.wikipedia.org/wiki/Coordinated_Universal_Time Len ^^^ .. class:: Len(value) Represent the PYSON statement for length of a dictionary, list or string. Returns the number of items in ``value``. Id ^^ .. class:: Id(module, fs_id) Represent the PYSON statement for filesystem id evaluations. When converted into the internal dictionary, it returns the database id stored in ``ir.model.data``. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1707150267.0 trytond-7.0.30/doc/ref/rpc.rst0000644000175000017500000000302714560205673014265 0ustar00cedced.. _ref-rpc: .. module:: trytond.rpc RPC === .. class:: RPC([readonly[, instantiate[, [decorator, result[, check_access[, unique[, fresh_session[, cache]]]]]]]]) Define the behavior of Remote Procedure Call. Instance attributes are: .. attribute:: RPC.readonly The transaction mode .. attribute:: RPC.instantiate The position or the slice of the argument to be instanciated .. attribute:: RPC.decorator The function to decorate the called procedure with .. attribute:: RPC.result The function to transform the result .. attribute:: RPC.check_access Set ``_check_access`` in the context to activate the access right on model and field. Default is ``True``. .. attribute:: RPC.unique If set, it ensures the instantiated records are unique. Default is ``True``. .. attribute:: RPC.fresh_session If set, it requires a fresh session. Default is ``False``. .. attribute:: RPC.cache A :class:`RPCCache` instance to compute the cache duration for the answer. RPCCache -------- .. class:: RPCCache([days[, seconds]) Define cache duration of RPC result. Instance attributes are: .. attribute:: RPC.duration A :py:class:`datetime.timedelta` instance. Instance methods are: .. method:: RCP.headers Return a dictionary of the headers. Exceptions ========== .. exception:: RPCReturnException The base class of exceptions to return the result of ``result`` method instead of raising an exception. The :class:`~trytond.transaction.Transaction` is rollbacked and tasks are cleared. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/sendmail.rst0000644000175000017500000000407514517761237015306 0ustar00cedced.. _ref-sendmail: .. module:: trytond.sendmail Sendmail ======== .. function:: sendmail_transactional(from_addr, to_addrs, msg[, transaction[, datamanager[, strict]]]) Send email message only if the current transaction is successfully committed. The required arguments are an :rfc:`5322` from-address string, a list of :rfc:`5322` to-address strings (a bare string is treated as a list with 1 address), and an email message. The caller may pass a :class:`~trytond.transaction.Transaction` instance to join otherwise the current one is joined. A specific data manager can be specified otherwise the default :class:`SMTPDataManager` is used for sending email. The strict value is passed to instantiate the default :class:`SMTPDataManager`. .. warning:: An SMTP failure is only logged without raising any exception. .. function:: sendmail(from_addr, to_addrs, msg[, server[, strict]]) Send email message like :meth:`sendmail_transactional` but directly without caring about the transaction and return the ``server``. The caller may pass a server instance from `smtplib`_. It may return a new server instance if a reconnection was needed and if the instance comes from :meth:`get_smtp_server`. If strict is ``True``, an exception is raised if it is not possible to connect to the server. .. function:: get_smtp_server([uri[, strict]]) Return a SMTP instance from `smtplib`_ using the ``uri`` or the one defined in the ``email`` section of the :ref:`configuration `. If strict is ``True``, an exception is raised if it is not possible to connect to the server. .. class:: SMTPDataManager([uri[, strict]]) Implement a data manager which send queued email at commit. An option optional ``uri`` can be passed to configure the SMTP connection. If strict is ``True``, the data manager prevents the transaction if it fails to send the emails. .. method:: SMTPDataManager.put(from_addr, to_addrs, msg) Queue the email message to send. .. _`smtplib`: https://docs.python.org/2/library/smtplib.html ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1707150267.0 trytond-7.0.30/doc/ref/tests.rst0000644000175000017500000001101714560205673014641 0ustar00cedced.. _ref-test: .. module:: trytond.tests.test_tryton Tests ===== .. attribute:: DB_NAME The name of the database to use for testing. Its value is taken from the environment variable of the same name. .. attribute:: USER The user id used to test the transactions .. attribute:: CONTEXT The context used to test the transactions .. function:: activate_module(name) Activate the named module for the tested database. In case database does not exist and the ``DB_CACHE`` environment variable is set then Tryton restores a backup found in the directory pointed by ``DB_CACHE``. ``DB_CACHE`` can also be set to the value ``postgresql://``, in that case Tryton create the database using the template found on the server. Otherwise it procees to the creation of the database and the activation of the module. ``DB_CACHE_JOBS`` environment variable defines the number of jobs used for dump and restore operations. The default value is the number of CPU. ModuleTestCase -------------- .. class:: ModuleTestCase() A subclass of `unittest.TestCase`_ that tests a Tryton module. Some tests are included to ensure that the module works properly. It creates a temporary database with the module activated in setUpClass_ and drops it in the tearDownClass_ method. .. attribute:: ModuleTestCase.module Name of the tested module. .. attribute:: ModuleTestCase.extras A list of extra modules to activate .. attribute:: ModuleTestCase.language The language to activate. Default value is ``en``. RouteTestCase ------------- .. class:: RouteTestCase() A subclass of `unittest.TestCase`_ to test Tryton routes. It creates a temporary database with the module activated in setUpClass_ and drops it in the tearDownClass_ method. .. attribute:: RouteTestCase.module Name of the tested module. .. attribute:: RouteTestCase.extras A list of extra modules to activate .. attribute:: RouteTestCase.language The language to activate. Default value is ``en``. .. attribute:: RouteTestCase.db_name Returns the name of the database .. classmethod:: RouteTestCase.setUpDatabase() A method called by setUpClass_ after activating the modules in a :class:`~trytond.transaction.Transaction`. It is used to setup data in the database. .. method:: RouteTestCase.client() Return a client to simulate requests to the WSGI application. .. _`unittest.TestCase`: https://docs.python.org/library/unittest.html#test-cases .. _setUpClass: https://docs.python.org/library/unittest.html#unittest.TestCase.setUpClass .. _tearDownClass: https://docs.python.org/library/unittest.html#unittest.TestCase.tearDownClass Helpers ------- .. function:: with_transaction(user=1, context=None) Return a decorator to run a test case inside a :class:`~trytond.transaction.Transaction`. It is rolled back and the cache cleared at the end of the test. doctest helpers --------------- .. function:: doctest_setup Prepare the run of the `doctest`_ by creating a database and dropping it beforehand if necessary. This function should be used as the ``setUp`` parameter. .. deprecated:: 4.2 The ``doctest_setup`` function should not be used anymore to set up :py:func:`~doctest.DocFileSuite`. New modules should use :func:`~trytond.tests.tools.activate_modules` instead. .. function:: doctest_teardown() Clean up after the run of the doctest_ by dropping the database. It should be used as ``tearDown`` parameter when creating a ``DocFileSuite``. .. attribute:: doctest_checker A specialized doctest checker to ensure the Python compatibility. .. function:: load_doc_tests(name, path, loader, tests, pattern) An helper that follows the ``load_tests`` protocol to load as :py:class:`~doctest.DocTest` all ``*.rst`` files in ``directory``, with the module ``name`` and the ``path`` to the module file from which the doc tests are registered. If a file with the same name but the extension ``.json`` exists, the test is registered for each globals defined in the JSON list. .. function:: suite() A function returning a subclass of ``unittest.TestSuite`` that drops the database if it does not exist prior to the run of the tests. .. _doctest: https://docs.python.org/library/doctest.html .. module:: trytond.tests.tools Tools ----- .. function:: activate_modules(modules) Activate a list of ``modules`` for scenario based on proteus doctests. .. function:: set_user(user, config) Set the user of the ``config`` proteus connection to ``user``. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1745680201.7163882 trytond-7.0.30/doc/ref/tools/0000755000175000017500000000000015003173512014072 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/tools/barcode.rst0000644000175000017500000000106514517761237016245 0ustar00cedced.. _ref-tools-barcode: .. module:: trytond.tools.barcode barcode ======= .. function:: generate_svg(name, code[, width[, height[, border,[ font_size[, text_distance[, background[, foreground]]]]]]]) Return a :py:class:`~io.BytesIO` containing the SVG image of the named barcode. .. function:: generate_png(name, code[, width[, height[, border[, font_size[, text_distance[, background[, foreground]]]]]]]) Return a :py:class:`~io.BytesIO` containing the PNG image of the named barcode. .. attribute:: BARCODES A set of available barcode names. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/tools/email.rst0000644000175000017500000000065014517761237015734 0ustar00cedced.. _ref-tools-email_: .. module:: trytond.tools.email_ Email ===== .. function:: set_from_header(message, sender, from\_) Fill email headers to appear at best from the address. .. function:: validate_email(email) Validate the email address. .. function:: normalize_email(email) Return the email address normalized. .. function:: convert_ascii_email(email): Return the equivalent email address in ASCII. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/tools/immutabledict.rst0000644000175000017500000000023514517761237017467 0ustar00cedced.. _ref-immutabledict: .. module:: trytond.tools.immutabledict ImmutableDict ============= .. class:: ImmutableDict Implement an immutable dictionary. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/tools/index.rst0000644000175000017500000000027014517761237015752 0ustar00cedced.. _ref-tools-index: ===== Tools ===== Tools API reference. .. toctree:: :maxdepth: 1 barcode email immutabledict logging misc qrcode singleton timezone ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/tools/logging.rst0000644000175000017500000000114514517761237016273 0ustar00cedced.. _ref-tools-logging: .. module:: trytond.tools.logging logging ======= .. class:: format_args(args, kwargs[, verbose[, max_args[, max_items]]]) If ``verbose`` is False, the string representation of this class is a shortened version of the arguments taken from ``args`` and from the keyword arguments in ``kwargs``. Otherwise, they are fully represented. ``max_args`` is the maximum number of arguments shown before using an ellipse. ``max_items`` is the maximum number of items shown in each argument before using an ellipse. In the shortened version, strings and bytes are shortened. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1707150267.0 trytond-7.0.30/doc/ref/tools/misc.rst0000644000175000017500000000350714560205673015577 0ustar00cedced.. _ref-tools: .. module:: trytond.tools Miscellaneous ============= .. function:: entry_points() Return a collection of entry points. .. function:: import_module(name) Import the named Tryton module. .. function:: file_open(name[, mode[, subdir[, encoding]]]) Open the named file in subdir from the root directory. .. function:: find_path(name[, subdir]) Return the path of the named file in subdir from root directory. .. function:: find_dir(name[, subdir]) Return the path of the named directory in subdir from root directory. .. function:: pairwise_longest(iterable) Return successive overlapping pairs taken from the input iterable. The number of 2-tuples in the output iterator will be the number of inputs and ends with the ``None``. It will be empty if the input iterable has fewer than two values. .. function:: resolve(name) Resolve a dotted name to a global object. .. method:: safe_join(directory, \*pathnames) Safely join zero or more untrusted path components to a base directory to avoid escaping the base directory. .. function:: unescape_wildcard(string[, wildcards[, escape]]) Return the string without the wild card escapes. .. function:: is_full_text(value[, escape]) Determine if the value can be used as full text search. This is the case when the value starts and ends with a ``%`` or does not contain any wild cards. .. function:: likify(string[, escape]) Convert the string for full text if it does not contain any wild cards. .. function:: sql_pairing(x, y) Return an SQL expression that pairs SQL integers x and y. .. function:: firstline(text) Return first non-empty line of a text field. .. function:: remove_forbidden_chars(value) Return a copy of the string with forbidden char from :class:`~trytond.model.fields.Char` replaced by space. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/tools/qrcode.rst0000644000175000017500000000066214517761237016125 0ustar00cedced.. _ref-tools-qrcode: .. module:: trytond.tools.qrcode qrcode ====== .. function:: generate_svg(code[, box_size[, border[, error_correction[, background[, foreground]]]]]) Return a :py:class:`~io.BytesIO` containing the SVG image of the QR Code. .. function:: generate_png(code[, box_size[, border[, error_correction[, background[, foreground]]]]]) Return a :py:class:`~io.BytesIO` containing the SVG image of the QR Code. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/tools/singleton.rst0000644000175000017500000000033214517761237016644 0ustar00cedced.. _ref-tools-singleton: .. module:: trytond.tools.singleton Singleton ========= .. class:: Singleton A metaclass to create a `singleton`_ object. .. _`singleton`: http://en.wikipedia.org/wiki/Singleton_pattern ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/tools/timezone.rst0000644000175000017500000000114014517761237016472 0ustar00cedced.. _ref-tools-timezone: .. module:: trytond.tools.timezone timezone ======== .. function:: get_tzinfo(zoneid) Get a class representing a IANA time zone specified by the string ``zoneid``. .. function:: available_timezones() Return a set of all the valid IANA keys available. .. attribute:: UTC The UTC :py:class:`datetime.tzinfo` instance. .. attribute:: SERVER The server timezone :py:class:`datetime.tzinfo` instance. Tryton tests the environment variables ``TRYTOND_TZ`` and ``TZ`` in this order to select to IANA key to use. If they are both empty, it defaults to ``UTC``. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/transaction.rst0000644000175000017500000001265614517761237016043 0ustar00cedced.. _ref-transaction: .. module:: trytond.transaction Transaction =========== .. exception:: TransactionError The base class for transaction error that need to retry the transaction. .. method:: TransactionError.fix(extras) Update the extras argument of :meth:`~Transaction.start` to restart the transaction without the error. .. class:: Transaction Represents a Tryton transaction that contains thread-local parameters of a database connection. The Transaction instances are `context manager`_ that commits or rollbacks the database transaction. In the event of an exception the transaction is rolled back, otherwise it is commited. .. attribute:: Transaction.database The database. .. attribute:: Transaction.readonly .. attribute:: Transaction.connection The database connection as defined by the `PEP-0249`_. .. attribute:: Transaction.user The id of the user. .. attribute:: Transaction.context .. attribute:: Transaction.create_records .. attribute:: Transaction.delete_records .. attribute:: Transaction.trigger_records .. attribute:: Transaction.check_warnings The set of warnings already checked. .. attribute:: Transaction.timestamp .. attribute:: Transaction.started_at The monotonic timestamp when the transaction started. .. attribute:: Transaction.language The language code defines in the context. .. attribute:: Transaction.counter Count the number of modification made in this transaction. .. attribute:: Transaction.check_access If the access must be enforced. .. attribute:: Transaction.active_records If the active test is enabled for :class:`~trytond.model.DeactivableMixin`. .. staticmethod:: Transaction.monotonic_time Return a monotonic time used to populate :attr:`~Transaction.started_at`. .. method:: Transaction.start(database_name, user[, readonly[, context[, close[, autocommit, \**extras]]]]) Start a new transaction and return a `context manager`_. The non-readonly transaction will be committed when exiting the ``with`` statement without exception. The other cases will be rollbacked. .. method:: Transaction.stop([commit]) Stop the transaction. If commit is ``True``, the transaction will be committed otherwise it will be rollbacked. The `context manager`_ returned by :meth:`~Transaction.start` should be used instead of calling this method. .. method:: Transaction.set_context(context, \**kwargs) Update the transaction context and return a `context manager`_. The context is restored when exiting the ``with`` statement. .. method:: Transaction.reset_context() Clear the transaction context and return a `context manager`_. The context is restored when exiting the ``with`` statement. .. method:: Transaction.set_user(user[, set_context]) Modify the user of the transaction and return a `context manager`_. ``set_context`` will put the previous user id in the context to simulate the record rules. The user will be restored when exiting the ``with`` statement. .. method:: Transaction.lock_table(table) Raise a :exc:`TransactionError` to retry the transaction if the table has not been locked at the start. .. method:: Transaction.set_current_transaction(transaction) Add a specific ``transaction`` on the top of the transaction stack. A transaction is commited or rollbacked only when its last reference is popped from the stack. .. method:: Transaction.new_transaction([autocommit[, readonly, \**extras]]) Create a new transaction with the same database, user and context as the original transaction and adds it to the stack of transactions. .. method:: Transaction.commit() Commit the transaction and all data managers associated. .. method:: Transaction.rollback() Rollback the transaction and all data managers associated. .. method:: Transaction.join(datamanager) Register in the transaction a data manager conforming to the `Two-Phase Commit protocol`_. This method returns the registered datamanager. It could be a different yet equivalent (in term of python equality) datamanager than the one passed to the method. .. method:: Transaction.atexit(func, \*args, \*\*kwargs) Register a function to be executed upon normal transaction termination. The function can not use the current transaction because it will be already committed or rollbacked. .. function:: check_access([func]) When called with a function, it decorates the function to be executed with check of access rights. Otherwise it returns a `context manager`_ that check access rights until exiting. .. function:: without_check_access([func]) When called with a function, it decorates the function to be executed without check of access rights. Otherwise it returns a `context manager`_ that disable check access rights until exiting. .. function:: active_records([func]) When called with a function, it decorates the function to be executed with active test enabled. Otherwise it returns a `context manager`_ that enable active test. .. function:: inactive_records(func) When called with a function, it decorates the function to be executed with active test disabled. Otherwise it returns a `context manager`_ that disables active test. .. _`context manager`: http://docs.python.org/reference/datamodel.html#context-managers .. _`PEP-0249`: https://www.python.org/dev/peps/pep-0249/ .. _`Two-Phase Commit protocol`: https://en.wikipedia.org/wiki/Two-phase_commit_protocol ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/ref/wizard.rst0000644000175000017500000001366014517761237015012 0ustar00cedced.. _ref-wizard: .. module:: trytond.wizard Wizard ====== A wizard is a `finite state machine`_. There is also a more :ref:`practical introduction into wizards `. .. _`finite state machine`: http://en.wikipedia.org/wiki/Finite-state_machine .. class:: Wizard(session_id) This is the base for any wizard. It contains the engine for the finite state machine. A wizard must have some :class:`State` instance attributes that the engine uses. Class attributes are: .. attribute:: Wizard.__name__ The unique name to reference the wizard throughout the platform. .. attribute:: Wizard.start_state The name of the starting state. .. attribute:: Wizard.end_state The name of the ending state. If an instance method with this name exists on the wizard, it is called on deletion of the wizard and it may return one of the :ref:`client side action keywords `. .. attribute:: Wizard.__rpc__ Same as :attr:`trytond.model.Model.__rpc__`. .. attribute:: Wizard.states A dictionary with state name as key and :class:`State` as value. .. attribute:: model The :class:`~trytond.model.Model` class on which the wizard is executed. .. attribute:: record The :class:`~trytond.model.Model` instance on which the wizard is executed. .. attribute:: records The list of :class:`~trytond.model.Model` instances on which the wizard is executed. Class methods are: .. classmethod:: Wizard.__setup__() Setup the class before adding into the :class:`~trytond.pool.Pool`. .. classmethod:: Wizard.__post_setup__() Setup the class after added into the :class:`~trytond.pool.Pool`. .. classmethod:: Wizard.__register__(module_name) Register the wizard. .. classmethod:: Wizard.create() Create a session for the wizard and returns a tuple containing the session id, the starting and ending state. .. classmethod:: Wizard.delete(session_id) Delete the session. .. classmethod:: Wizard.execute(session_id, data, state_name) Execute the wizard for the state. ``session_id`` is a session id. ``data`` is a dictionary with the session data to update. ``active_id``, ``active_ids``, ``active_model`` and ``action_id`` must be set in the context according to the records on which the wizard is run. State ----- .. class:: State() The base for any wizard state. Instance attributes are: .. attribute:: State.name The name of the state. StateView --------- .. class:: StateView(model_name, view, buttons) A :class:`StateView` is a state that will display a form in the client. The form is defined by the :class:`~trytond.model.ModelView` with the name ``model_name``, the ``XML`` id in ``view`` and the ``buttons``. The default values of the view can be set with a method on wizard having the same name as the state but starting with ``default_``. The values of the view can be also set with a method on wizard having the same name as the state but starting with ``value_``. .. note:: The difference between default values and values is that the client calls :meth:`~trytond.model.ModelView.on_change` and :meth:`~trytond.model.ModelView.on_change_with` for the default values. Instance attributes are: .. attribute:: StateView.model_name The name of the :class:`~trytond.model.ModelView`. .. attribute:: StateView.view The XML id of the form view. .. attribute:: StateView.buttons The list of :class:`Button` instances to display on the form. Instance methods are: .. method:: StateView.get_view(wizard, state_name) Return the view definition like :meth:`~trytond.model.ModelView.fields_view_get`. ``wizard`` is a :class:`Wizard` instance. ``state_name`` is the name of the :class:`StateView` instance. .. method:: StateView.get_defaults(wizard, state_name, fields) Return default values for the fields. ``wizard`` is a :class:`Wizard` instance. ``state_name`` is the name of the :class:`State`. ``fields`` is the list of field names. .. method:: StateView.get_values(wizard, state_name, fields) Return values for the fields. ``wizard`` is a :class:`Wizard` instance. ``state_name`` is the name of the :class:`State`. ``fields`` is the list of field names. .. method:: StateView.get_buttons(wizard, state_name) Return button definitions of the wizard. ``wizard`` is a :class:`Wizard` instance. ``state_name`` is the name of the :class:`StateView` instance. StateTransition --------------- .. class:: StateTransition() A :class:`StateTransition` brings the wizard to the ``state`` returned by the method having the same name as the state but starting with ``transition_``. StateAction ----------- .. class:: StateAction(action_id) A :class:`StateTransition` which let the client launch an ``ir.action``. This action definition can be customized with a method on wizard having the same name as the state but starting with ``do_``. Instance attributes are: .. attribute:: StateAction.action_id The XML id of the ``ir.action``. Instance methods are: .. method:: StateAction.get_action() Return the ``ir.action`` definition. StateReport ----------- .. class:: StateReport(report_name) A :class:`StateAction` which find the report action by name instead of XML id. Button ------ .. class:: Button(string, state[, icon[, default[, validate]]]) Define of a wizard button. Instance attributes are: .. attribute:: Button.string The label display on the button. .. attribute:: Button.state The next state to reach if button is clicked. .. attribute:: Button.icon The name of the icon to display on the button. .. attribute:: Button.default A boolean to set it as default on the form. .. attribute:: Button.validate A boolean or None. If ``True``, validation of the form will occur, if ``False`` it won't. If the value is ``None`` the validation will occur only if the state of the button is not the wizard ending state. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/releases.rst0000644000175000017500000000013214517761237014527 0ustar00cedced.. _releases-index: ============= Release notes ============= .. include:: ../CHANGELOG ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/requirements-doc.txt0000644000175000017500000000004414517761237016223 0ustar00cedcedsphinx_book_theme sphinx_copybutton ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1745680201.723055 trytond-7.0.30/doc/topics/0000755000175000017500000000000015003173512013457 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1707150267.0 trytond-7.0.30/doc/topics/access_rights.rst0000644000175000017500000000720514560205673017051 0ustar00cedced.. _topics-access_rights: ============= Access Rights ============= There are 5 levels of access rights: `Model`_ , `Actions`_, `Field`_, `Button`_ and `Record Rule`_. They are based on the user's group membership. If any of those levels are violated, an error is raised. The access rights are checked if the :attr:`Transaction.context ` has the key ``_check_access`` set to ``True`` (set by default by :attr:`RPC.check_access `) and if the :attr:`~trytond.transaction.Transaction.user` is not ``root``. Model ===== They are defined by records of ``ir.model.access`` which define for each couple of model and group, the ``read``, ``write``, ``create`` and ``delete`` permission. The permissions are related to the :class:`~trytond.model.ModelStorage` methods with the same name and on :meth:`~trytond.model.ModelStorage.search` using the ``read`` permission. If any group the user belongs to has the checked permission activated, then the user is granted this permission. If there is no record for the model, then access is granted to all users. .. note:: Relation fields for which the user has no read access are automatically removed from the :ref:`views `. Actions ======= Each ``ir.action`` has a ``groups`` field which contains a list of user groups that are allowed to see and launch it. There is a special case for :ref:`wizard ` for which the read access on the model is also checked and also the write access if there is no groups linked. Field ===== They are defined by records of ``ir.model.field.access`` and work like those for `Model`_ but are applied to :ref:`fields `. .. note:: Fields for which the user has no read access are automatically removed from the :ref:`views `. Button ====== For each button of a model the records of ``ir.model.button`` define the list of groups that are allowed to call it. The user only needs to belong to one of the groups to be granted the permission to use it. If no group is defined for a button, the ``write`` permission to the model is checked instead. The ``read`` permission to the model is always enforced. .. note:: Buttons for which the user has no access are marked readonly. Button Rule ----------- The ``ir.model.button`` can contain a list of rules which define how many different users must click on the button. Each rule, for which the condition is met, must be passed to actually trigger the action. The counter can be reset when another defined button is clicked. Record Rule =========== The record rules are conditions that records must meet for the user to be granted permission to use them. They are defined by records of ``ir.rule.group`` which contains: - a model on which it applies - the permissions granted - a set of user groups to which the rule applies - a global flag to always enforce - a default flag to add to all users - a list of ``ir.rule`` with a :ref:`domain ` to select the records to which the rule applies. A rule group matches a record if the record is validated by at least one of the domains. The access is granted to a record: - if the user belongs to a group which has at least one matching rule group that has the permission, - or if there is a default matching rule group with the permission, - or if there is a global matching rule group with the permission. Otherwise the access is denied if there is any matching rule group. .. note:: Records for which the user has no ``read`` access are filtered out from the :meth:`~trytond.model.ModelStorage.search` result. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/actions.rst0000644000175000017500000000174014517761237015673 0ustar00cedced.. _topics-actions: ======= Actions ======= Actions are used to describe specific behaviors in the client. There are four types of actions: * Report * Window * Wizard * URL Keyword ------- Keywords define where to display the action in the client. There are five places: * Open tree (``tree_open``) * Print form (``form_print``) * Action form (``form_action``) * Form relate (``form_relate``) * Open Graph (``graph_open``) Report ====== .. TODO Window ====== The window action describe how to create a new tab in the client. View ---- .. TODO Domain ------ The window action could have a list of domains which could be activated on the view. The boolean field count indicates if the client must display the number of records for this domain. .. warning:: The counting option must be activated only on domains which have not too much records otherwise it may overload the database. Wizard ====== .. TODO URL === .. TODO ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/backend_types.rst0000644000175000017500000000765614517761237017062 0ustar00cedced.. _topics-backend_types: Backend Types supported ======================= This table give a comprehensive list of the SQL Types that are expected to be supported by the database backends. If the type is not supported then the backend will have to emulate the behavior described here. The columns are in the following order: * The SQL type [#]_ representing the field * The python type expected on input * The python type received on output .. _`SQL 92`: https://en.wikipedia.org/wiki/SQL-92 .. _`PostgreSQL type`: https://www.postgresql.org/docs/current/static/datatype.html ``None`` will represent the ``NULL`` value and vice versa, it can be used as input or output for any SQL type. +----------------------+----------------------+----------------------+ | SQL Type | Python input type | Python output type | +======================+======================+======================+ | ``BOOL`` | bool | bool | +----------------------+----------------------+----------------------+ | ``SMALLINT`` | int | int | +----------------------+----------------------+----------------------+ | ``INTEGER`` | int | int | +----------------------+----------------------+----------------------+ | ``BIGINT`` | int | int | +----------------------+----------------------+----------------------+ | ``REAL`` | float / int | float | +----------------------+----------------------+----------------------+ | ``FLOAT`` | float / int | float | +----------------------+----------------------+----------------------+ | ``NUMERIC`` | decimal.Decimal_ | decimal.Decimal_ | +----------------------+----------------------+----------------------+ | ``VARCHAR`` / | str | str | | ``VARCHAR(length)`` | | | +----------------------+----------------------+----------------------+ | ``TEXT`` | str | str | +----------------------+----------------------+----------------------+ | ``TIMESTAMP`` | datetime.datetime_ | datetime.datetime_ | | | [#utc_tz]_ | [#utc_tz]_ | +----------------------+----------------------+----------------------+ | ``DATETIME`` | datetime.datetime_ | datetime.datetime_ | | | without microseconds | without microseconds | | | [#utc_tz]_ | [#utc_tz]_ | +----------------------+----------------------+----------------------+ | ``DATE`` | datetime.date_ | datetime.date_ | +----------------------+----------------------+----------------------+ | ``TIME`` | datetime.time_ | datetime.time_ | +----------------------+----------------------+----------------------+ | ``INTERVAL`` | datetime.timedelta_ | datetime.timedelta_ | +----------------------+----------------------+----------------------+ | ``BLOB`` | bytes | bytes | +----------------------+----------------------+----------------------+ | ``JSON`` | dict | dict | +----------------------+----------------------+----------------------+ .. [#] Corresponding to the `SQL 92`_ standard or to a `PostgreSQL type`_. .. [#utc_tz] datetime objects are in UTC but without timezone. .. _datetime.date: https://docs.python.org/library/datetime.html#date-objects .. _datetime.datetime: https://docs.python.org/library/datetime.html#datetime-objects .. _datetime.time: https://docs.python.org/library/datetime.html#time-objects .. _datetime.timedelta: https://docs.python.org/library/datetime.html#timedelta-objects .. _decimal.Decimal: https://docs.python.org/library/decimal.html#decimal-objects ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/bus.rst0000644000175000017500000000142414517761237015023 0ustar00cedced.. _topics-notification: ===================== Sending notifications ===================== Tryton embeds a bus system allowing the system to send text messages to clients logged in the system. It allows the server to warn quickly the client user about some events using the :meth:`~trytond.bus.notify` function. Sending the notifications is done in a transactional way and will occur at then end of the transaction. For example, we warn the user of low stock level when selecting a product: .. code-block:: python from trytond.bus import notify class SaleLine: __name__ = 'sale.line' def on_change_product(self): super().on_change_product() if compute_stock(self.product) < 0: notify('Not enough stock', priority=3) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1707150267.0 trytond-7.0.30/doc/topics/configuration.rst0000644000175000017500000003466414560205673017110 0ustar00cedced.. _topics-configuration: ============================= Configuration file for Tryton ============================= The configuration file controls some aspects of the behavior of Tryton. The file uses a simple ini-file format. It consists of sections, led by a ``[section]`` header and followed by ``name = value`` entries: .. highlight:: ini :: [database] uri = postgresql://user:password@localhost/ path = /var/lib/trytond For more information see ConfigParser_. .. _ConfigParser: http://docs.python.org/2/library/configparser.html The default value of any option can be changed using environment variables with names using this syntax: ``TRYTOND_
__``. Sections ======== This section describes the different main sections that may appear in a Tryton configuration file, the purpose of each section, its possible keys, and their possible values. Some modules could request the usage of other sections for which the guideline asks them to be named like their module. .. contents:: :local: :backlinks: entry :depth: 2 web --- Defines the behavior of the web interface. listen ~~~~~~ Defines the couple of host (or IP address) and port number separated by a colon to listen on. Default ``localhost:8000`` .. note:: To listen on all IPv4 interfaces use the value ``0.0.0.0:8000`` and for all IPv6 interfaces use ``[::]:8000``. hostname ~~~~~~~~ Defines the hostname to use when generating a URL when there is no request context available, for example during a cron job. root ~~~~ Defines the root path served by ``GET`` requests. Default: Under the ``www`` directory of user's home running ``trytond``. num_proxies ~~~~~~~~~~~ The number of proxy servers in front of ``trytond``. Default: 0 cache_timeout ~~~~~~~~~~~~~ The cache timeout in seconds. Default: 12h cors ~~~~ The list (one per line) of origins allowed for `Cross-Origin Resource sharing `_. For example:: cors = http://example.com https://example.com avatar_base ~~~~~~~~~~~ The base URL without a path for avatar URL. Default: ``''`` .. note:: It can be used to setup a CDN. avatar_timeout ~~~~~~~~~~~~~~ The time in seconds that the avatar can be stored in cache. Default: 7 days database -------- Defines how the database is managed. uri ~~~ Contains the URI to connect to the SQL database. The URI follows the :rfc:`3986`. The typical form is: database://username:password@host:port/?param1=value1¶m2=value2 The parameters are database dependent, check the database documentation for a list of valid parameters. Default: The value of the environment variable ``TRYTOND_DATABASE_URI`` or ``sqlite://`` if not set. The available databases are: PostgreSQL ********** ``psycopg2`` supports two type of connections: - TCP/IP connection: ``postgresql://user:password@localhost:5432/`` - Unix domain connection: ``postgresql://username:password@/`` Please refer to `psycopg2 for the complete specification of the URI `_. A list of parameters supported by PostgreSQL can be found in the `documentation `__. .. note:: ``fallback_application_name`` parameter from aforementioned documentation can be set directly thanks to the ``TRYTOND_APPNAME`` environment variable. SQLite ****** The URI is defined as ``sqlite://`` If the name of the database is ``:memory:``, the parameter ``mode`` will be set to ``memory`` thus using a pure in-memory database. The recognized query parameters can be found in SQLite's `documentation `__. path ~~~~ The directory where Tryton stores files and so the user running :command:`trytond` must have write access on this directory. Default: The :file:`db` folder under the user home directory running :command:`trytond`. list ~~~~ A boolean value to list available databases. Default: ``True`` retry ~~~~~ The number of retries when a database operational error occurs during a request. Default: ``5`` subquery_threshold ~~~~~~~~~~~~~~~~~~ The number of records in the target relation under which a sub-query is used. Default: ``1000`` language ~~~~~~~~ The main language of the database that will be used for storage in the main table for translations. Default: ``en`` avatar_filestore ~~~~~~~~~~~~~~~~ This configuration value indicates whether the avatars should be stored in the :py:mod:`trytond.filestore` (``True``) or the database (``False``). Default: ``False`` avatar_prefix ~~~~~~~~~~~~~ The prefix to use with the :ref:`FileStore ` to store avatars. Default: ``None`` default_name ~~~~~~~~~~~~ The name of the database to use for operations without a database name. Default: ``template1`` for PostgreSQL, ``:memory:`` for SQLite. timeout ~~~~~~~ The timeout duration in seconds after which the connections to unused databases are closed. Default: ``1800`` (30 minutes) minconn ~~~~~~~ The minimum number of connections to keep in the pool (if the backend supports pool) per process. Default: ``1`` maxconn ~~~~~~~ The maximum number of simultaneous connections to the database per process. Default: ``64`` unaccent_function ~~~~~~~~~~~~~~~~~ The name of the unaccent function. Default: ``unaccent`` similarity_function ~~~~~~~~~~~~~~~~~~~ The name of the similarity function. Default: ``similarity`` request ------- max_size ~~~~~~~~ The maximum size in bytes of unauthenticated request (zero means no limit). Default: 2MB max_size_authenticated ~~~~~~~~~~~~~~~~~~~~~~ The maximum size in bytes of an authenticated request (zero means no limit). Default: 2GB cache ----- Defines size of various cache. transaction ~~~~~~~~~~~ The number of contextual caches kept per transaction. Default: ``10`` model ~~~~~ The number of different model kept in the cache per transaction. Default: ``200`` record ~~~~~~ The number of record loaded kept in the cache of the list. It can be changed locally using the ``_record_cache_size`` key in :attr:`Transaction.context `. Default: ``2000`` field ~~~~~ The number of field to load with an ``eager`` :attr:`Field.loading `. Default: ``100`` default ~~~~~~~ The default :attr:`~trytond.cache.Cache.size_limit` of :class:`~trytond.cache.Cache`. Default: ``1024`` clean_timeout ~~~~~~~~~~~~~ The minimum number of seconds between two cleanings of the cache. If the value is 0, the notification between processes will be done using channels if the back-end supports them. Default: ``300`` count_timeout ~~~~~~~~~~~~~ The cache timeout duration in seconds of the estimation of records. Default: ``86400`` (1 day) count_clear ~~~~~~~~~~~ The number of operations after which the counting estimation of records is cleared. Default: ``1000`` queue ----- worker ~~~~~~ Activate asynchronous processing of the tasks. Otherwise they are performed at the end of the requests. Default: ``False`` clean_days ~~~~~~~~~~ The number of days after which processed tasks are removed. Default: ``30`` batch_size ~~~~~~~~~~ The default number of the instances to process in a batch. Default: ``20`` error ----- clean_days ~~~~~~~~~~ The number of days after which reported errors are removed. Default: ``90`` table ----- This section allows to override the default generated table name for a :class:`~trytond.model.ModelSQL`. The main goal is to bypass limitation on the name length of the database backend. For example:: [table] account.invoice.line = acc_inv_line account.invoice.tax = acc_inv_tax ssl --- Activates SSL_ on the web interface. .. note:: It is recommended to delegate the SSL support to a proxy. privatekey ~~~~~~~~~~ The path to the private key. certificate ~~~~~~~~~~~ The path to the certificate. .. tip:: Set only one of ``privatekey`` or ``certificate`` to ``true`` if the SSL is delegated. email ----- .. note:: Email settings can be tested with the ``trytond-admin`` command uri ~~~ The SMTP-URL_ to connect to the SMTP server which is extended to support SSL_ and STARTTLS_. The available protocols are: - ``smtp``: simple SMTP - ``smtp+tls``: SMTP with STARTTLS - ``smtps``: SMTP with SSL The uri accepts the following additional parameters: * ``local_hostname``: used as FQDN of the local host in the HELO/EHLO commands, if omited it will use the value of ``socket.getfqdn()``. * ``timeout``: A number of seconds used as timeout for blocking operations. A ``socket.timeout`` will be raised when exceeded. If omited the default timeout will be used. Default: ``smtp://localhost:25`` from ~~~~ Defines the default ``From`` address (using :rfc:`5322`) for emails sent by Tryton. For example:: from: "Company Inc" Default: The login name of the :abbr:`OS (Operating System)` user. retry ~~~~~ The number of retries when the SMTP server returns a temporary error. Default: ``5`` session ------- authentications ~~~~~~~~~~~~~~~ A comma separated list of the authentication methods to try when attempting to verify a user's identity. Each method is tried in turn, following the order of the list, until one succeeds. In order to allow `multi-factor authentication`_, individual methods can be combined together using a plus (``+``) symbol. Example:: authentications = password+sms,ldap Each combined method can have options to skip them if they are met except for the first method. They are defined by appending their name to the method name after a question mark (``?``) and separated by colons (``:``). Example:: authentications = password+sms?ip_address:device_cookie By default, Tryton only supports the ``password`` method. This method compares the password entered by the user against a stored hash of the user's password. By default, Tryton supports the ``ip_address`` and ``device_cookie`` options. The ``ip_address`` compares the client IP address with the known network list defined in `authentication_ip_network`_. The ``device_cookie`` checks the client device is a known device of the user. Other modules can define additional authentication methods and options, please refer to their documentation for more information. Default: ``password`` authentication_ip_network ~~~~~~~~~~~~~~~~~~~~~~~~~ A comma separated list of known IP networks used to check for ``ip_address`` authentication method option. Default: ``''`` max_age ~~~~~~~ The time in seconds that a session stay valid. Default: ``2592000`` (30 days) timeout ~~~~~~~ The time in seconds without activity before the session is no more fresh. Default: ``300`` (5 minutes) max_attempt ~~~~~~~~~~~ The maximum authentication attempt before the server answers unconditionally ``Too Many Requests`` for any other attempts. The counting is done on all attempts over a period of ``timeout``. Default: ``5`` max_attempt_ip_network ~~~~~~~~~~~~~~~~~~~~~~ The maximum authentication attempt from the same network before the server answers unconditionally ``Too Many Requests`` for any other attempts. The counting is done on all attempts over a period of ``timeout``. Default: ``300`` ip_network_4 ~~~~~~~~~~~~ The network prefix to apply on IPv4 address for counting the authentication attempts. Default: ``32`` ip_network_6 ~~~~~~~~~~~~ The network prefix to apply on IPv6 address for counting the authentication attempts. Default: ``56`` password -------- length ~~~~~~ The minimal length required for the user password. Default: ``8`` forbidden ~~~~~~~~~ The path to a file containing one forbidden password per line. reset_timeout ~~~~~~~~~~~~~ The time in seconds until the reset password expires. Default: ``86400`` (24h) passlib ~~~~~~~ The path to the `INI file to load as CryptContext `_. If no path is set, Tryton will use the schemes ``argon2``, ``scrypt``, ``bcrypt`` or ``pbkdf2_sha512``. Default: ``None`` attachment ---------- Defines how to store the attachments filestore ~~~~~~~~~ A boolean value to store attachment in the :ref:`FileStore `. Default: ``True`` store_prefix ~~~~~~~~~~~~ The prefix to use with the ``FileStore``. Default: ``None`` bus --- allow_subscribe ~~~~~~~~~~~~~~~ A boolean value to allow clients to subscribe to bus channels. Default: ``False`` url_host ~~~~~~~~ If set redirects bus requests to the host URL. long_polling_timeout ~~~~~~~~~~~~~~~~~~~~ The time in seconds to keep the connection to the client opened when using long polling for bus messages Default: ``300`` cache_timeout ~~~~~~~~~~~~~ The number of seconds a message should be kept by the queue before being discarded. Default: ``300`` select_timeout ~~~~~~~~~~~~~~ The timeout duration of the select call when listening on a channel. Default: ``5`` html ---- src ~~~ The URL pointing to `TinyMCE `_ editor. Default: ``https://cloud.tinymce.com/stable/tinymce.min.js`` plugins ~~~~~~~ The space separated list of TinyMCE plugins to load. It can be overridden for specific models and fields using the names: ``plugins--`` or ``plugins-``. Default: ``''`` css ~~~ The JSON list of CSS files to load. It can be overridden for specific models and fields using the names: ``css--`` or ``css-``. Default: ``[]`` class ~~~~~ The class to add on the body. It can be overridden for specific models and fields using the names: ``class--`` or ``class-``. Default: ``''`` wsgi middleware --------------- The section lists the `WSGI middleware`_ class to load. Each middleware can be configured with a section named ``wsgi `` containing ``args`` and ``kwargs`` options. Example:: [wsgi middleware] ie = werkzeug.contrib.fixers.InternetExplorerFix [wsgi ie] kwargs={'fix_attach': False} .. note:: The options can be set using environment variables with names like: ``TRYTOND_WSGI___``. .. _JSON-RPC: http://en.wikipedia.org/wiki/JSON-RPC .. _XML-RPC: http://en.wikipedia.org/wiki/XML-RPC .. _SMTP-URL: https://datatracker.ietf.org/doc/html/draft-earhart-url-smtp-00 .. _SSL: http://en.wikipedia.org/wiki/Secure_Sockets_Layer .. _STARTTLS: http://en.wikipedia.org/wiki/STARTTLS .. _WSGI middleware: https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface#Specification_overview .. _`multi-factor authentication`: https://en.wikipedia.org/wiki/Multi-factor_authentication ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1726506098.0 trytond-7.0.30/doc/topics/cron.rst0000644000175000017500000000262514672062162015170 0ustar00cedced.. _topics-cron: ================= Scheduled Actions ================= Tryton provides a scheduler (aka cron) which can execute methods of :ref:`models ` periodically at set intervals. The planning is managed by ``ir.cron`` records which store the method to call and the interval of time between calls. The method must be a class method of a :class:`~trytond.model.Model` which can be called without any parameters. .. note:: The timezone used to schedule the action is :attr:`timezone.SERVER `. To register a new method with the scheduler, you must extend the ``ir.cron`` model and append the new method to the :attr:`~trytond.model.fields.Selection.selection` attribute of the ``method`` field in :meth:`~trytond.model.Model.__setup__`. The name of the selection must be the model name and the method name joined together with a ``|`` between them. Example: .. highlight:: python :: from trytond.model import Model from trytond.pool import PoolMeta class Cron(metaclass=PoolMeta): __name__ = 'ir.cron' @classmethod def __setup__(cls): super().__setup__() cls.method.selection.append( ('my_model|my_method', "Run my method"), ) class MyModel(Model): "My Model" __name__ = 'my_model' @classmethod def my_method(cls): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1743202527.0 trytond-7.0.30/doc/topics/domain.rst0000644000175000017500000001752214771624337015510 0ustar00cedced.. _topics-domain: ====== Domain ====== Domains_ represent a set of records. A domain is a list of none or more clauses. A clause is a condition, which returns true or false. A record belongs to a domain, when the final result of the list of clauses returns true. .. _Domains: http://en.wikipedia.org/wiki/Data_domain Syntax ====== The definition of a simple domain with one clause is represented by this pattern:: domain = [(, , )] ``field name`` Is the name of a :mod:`~trytond.model.fields` or a :ref:`pyson ` statement, that evaluates to a string. A field of type :class:`~trytond.model.fields.Many2One` or :class:`~trytond.model.fields.Many2Many` or :class:`~trytond.model.fields.One2Many` or :class:`~trytond.model.fields.One2One` or :class:`~trytond.model.fields.Reference` can be dereferenced to related models. This is illustrated by the following example:: domain = [('country.name', '=', 'Japan')] The number of *dots* in a clause is not limited. .. note:: Negative operators match records for which any of the field before the last dot is empty. Except if the operand is or contains ``None``. .. warning:: For :class:`trytond.model.fields.Reference`, an extra ending clause is needed to define the target model to join, for example:: domain = [('origin.party.name', '=', 'John Doe', 'sale.sale')] A field of type :class:`~trytond.model.fields.Dict` can be searched by key also by using one *dot*. For example:: domain = [('attributes.color', '=', 'yellow')] .. warning:: Order comparison of ``date`` and ``datetime`` types is not supported. ``operator`` Is an operator out of `Domain Operators`_ or a :ref:`pyson ` statement, that evaluates to a domain operator string. ``operand`` Is an operand or a :ref:`pyson ` statement. The type of operand depends on the kind of . The definition of an empty domain is:: domain = [] An empty domain without clauses will always return all *active* records. A record is active, when its appropriate :class:`~trytond.model.Model` contains a :class:`~trytond.model.fields.Boolean` field with name ``active``, and set to true. When the appropriate :class:`~trytond.model.Model` does not contain a :class:`~trytond.model.fields.Boolean` field with name ``active`` all records are returned. A domain can be setup as a combination of clauses, like shown in this pattern:: domain = [ ('field name1', 'operator1', 'operand1'), ('field name2', 'operator2', 'operand2'), ('field name3', 'operator3', 'operand3'), ] The single clauses are implicitly combined with a logical AND_ operation. In the domain syntax it is possible to provide explicitly the combination operation of the clauses. These operations can be AND_ or OR_. This is illustrated by the following pattern:: domain = ['OR', [ ('field name1', 'operator1', 'operand1'), ('field name2', 'operator2', 'operand2'), ], [ ('field name3', 'operator3', 'operand3'), ], ] .. _AND: http://en.wikipedia.org/wiki/Logical_and .. _OR: http://en.wikipedia.org/wiki/Logical_or Here the domain is evaluated like this: ``((clause1 AND clause2) OR clause3)``. Please note that the ``AND`` operation is implicit assumed when no operator is given. While the ``OR`` operation must be given explicitly. The former pattern is equivalent to the following completely explicit domain definition:: domain = ['OR', ['AND', [ ('field name1', 'operator1', 'operand1'), ], [ ('field name2', 'operator2', 'operand2'), ], ], [ ('field name3', 'operator3', 'operand3'), ], ] Obviously the use of the implicit ``AND`` operation makes the code more readable. Domain Operators ================ The following operators are allowed in the domain syntax. ````, ```` and ```` are dereferenced to their values. The description of each operator follows this pattern, unless otherwise noted:: (, , ) ``=`` ----- Is a parity operator. Returns true when ```` equals to ````. ``!=`` ------ Is an imparity operator. It is the negation of the `=`_ operator. ``like`` -------- Is a pattern matching operator. Returns true when ```` is contained in the pattern represented by ````. In ```` an underscore (``_``) matches any single character, a percent sign (``%``) matches any string with zero or more characters. To use ``_`` or ``%`` as literal, use the backslash ``\`` to escape them. All matching is case sensitive. ``not like`` ------------ Is a pattern matching operator. It is the negation of the `like`_ operator. ``ilike`` --------- Is a pattern matching operator. The same use as `like`_ operator, but matching is case insensitive. ``not ilike`` ------------- Is a pattern matching operator. The negation of the `ilike`_ operator. ``in`` ------ Is a list member operator. Returns true when ```` is in ```` list. ``not in`` ---------- Is a list non-member operator. The negation of the `in`_ operator. ``<`` ----- Is a *less than* operator. Returns true for type string of ```` when ```` is alphabetically sorted before ````. Returns true for type number of ```` when ```` is less than ````. ``>`` ----- Is a *greater than* operator. Returns true for type string of ```` when ```` is alphabetically sorted after ````. Returns true for type number of ```` when ```` is greater ````. ``<=`` ------ Is a *less than or equal* operator. Returns the same as using the `<`_ operator, but also returns true when ```` is equal to ````. ``>=`` ------ Is a *greater than or equal* operator. Returns the same as using the `>`_ operator, but also returns true when ```` is equal to ````. ``child_of`` ------------ Is a parent child comparison operator. Returns true for records that are a child of ````. ```` is a list of ``ids`` and ```` must be a :class:`~trytond.model.fields.Many2One` or a :class:`~trytond.model.fields.Many2Many`. In case ```` is not linked to itself, the clause pattern extends to:: (, ['child_of'|'not_child_of'], , ) Where ```` is the name of the field constituting the :class:`~trytond.model.fields.Many2One` on the target model. ``not child_of`` ---------------- Is a parent child comparison operator. It is the negation of the `child_of`_ operator. ``parent_of`` ------------- Is a parent child comparison operator. It is the same as `child_of`_ operator but if ```` is a parent of ````. ``not parent_of`` ----------------- Is a parent child comparison operator. It is the negation of this `parent_of`_ operator. ``where`` --------- Is a :class:`trytond.model.fields.One2Many` / :class:`trytond.model.fields.Many2Many` domain operator. It returns true for every row of the target model that match the domain specified as ````. ``not where`` ------------- Is a :class:`trytond.model.fields.One2Many` / :class:`trytond.model.fields.Many2Many` domain operator. It returns true for every row of the target model that does not match the domain specified as ````. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/index.rst0000644000175000017500000000103014517761237015332 0ustar00cedced.. _topics-index: ============= Using trytond ============= Introduction key parts of ``trytond``: .. toctree:: :maxdepth: 1 install configuration setup_database logs start_server models/index backend_types models/fields_default_value models/fields_on_change domain pyson access_rights user_errors_warnings triggers actions views/index views/extension wizard reports/index rpc task_queue cron user_application bus modules/index translation testing ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1707150267.0 trytond-7.0.30/doc/topics/install.rst0000644000175000017500000000172714560205673015701 0ustar00cedced.. _topics-install: ====================== How to install Tryton ====================== Install Tryton ============== There are three options to install Tryton: * Install the version provided by your operating system distribution. This is the quickest and recommended option for those who has operating system that distributes Tryton. * Install the published package. You first need to have `pip `_ installed. Then to install ``trytond`` run: .. code-block:: console $ python -m pip install trytond You can also install for example the ``sale`` module with: .. code-block:: console $ python -m pip install trytond_sale * Without installation, you need to make sure you have all the dependencies installed and then run: .. code-block:: console $ python bin/trytond You can register modules by linking them into the ``trytond/modules`` folder. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/logs.rst0000644000175000017500000000212414517761237015174 0ustar00cedced.. _topics-logs: ===================== Logging configuration ===================== Without any configuration, ``trytond`` writes messages to standard output. For each verbose flag set, the log level decreases. Logs can be configured using a `configparser-format`_ file. The filename can be specified using ``trytond`` ``logconf`` parameter. .. _`configparser-format`: https://docs.python.org/library/logging.config.html#configuration-file-format Example ======= This example allows to write messages from INFO level on standard output and on a disk log file rotated every day. .. highlight:: ini :: [formatters] keys=simple [handlers] keys=rotate,console [loggers] keys=root [formatter_simple] format=[%(asctime)s] %(levelname)s:%(name)s:%(message)s datefmt=%a %b %d %H:%M:%S %Y [handler_rotate] class=handlers.TimedRotatingFileHandler args=('/tmp/tryton.log', 'D', 1, 30) formatter=simple [handler_console] class=StreamHandler formatter=simple args=(sys.stdout,) [logger_root] level=INFO handlers=rotate,console ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1745680201.723055 trytond-7.0.30/doc/topics/models/0000755000175000017500000000000015003173512014742 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/models/fields_default_value.rst0000644000175000017500000000151014517761237021657 0ustar00cedced.. _topics-fields_default_value: ======================= Default value of fields ======================= When a record is created, each field, which doesn't have a value specified, is set with the default value if exists. The following class method: .. rstcheck: ignore-next-code-block .. code-block:: python Model.default_() Return the default value for ``field name``. This example defines an ``Item`` model which has a default ``since``: .. code-block:: python import datetime from trytond.model import ModelView, ModelSQL, fields class Item(ModelSQL, ModelView): "Item" __name__ = 'item' since = fields.Date('since') @classmethod def default_since(cls): return datetime.date.today() See also method :meth:`~trytond.model.Model.default_get`. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/models/fields_on_change.rst0000644000175000017500000000225514517761237020767 0ustar00cedced.. _topics-fields_on_change: =================== on_change of fields =================== Tryton allows developers to define methods that can be called once a field's value has been changed by the user. The instance method has the following name:: on_change_ An instance of :class:`~trytond.model.Model` is created by using the values from the client's fields specified by the :attr:`~trytond.model.fields.Field.on_change` list defined on the field. Any change made on the instance will be pushed back to the client-side record. There is also a way to define a method that must update the value of a field whenever any field from a predefined list is modified. This list is defined by the :attr:`~trytond.model.fields.Field.on_change_with` attribute of the field. The method that will be called has the following name:: on_change_with_ Just like for the classic ``on_change``, an instance of :class:`~trytond.model.Model` is created by using the values from the client's fields specified by the :attr:`~trytond.model.fields.Field.on_change_with` attribute. The returned value of the method is pushed back to the client-side record as the new value of the field. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/models/index.rst0000644000175000017500000000254014517761237016624 0ustar00cedced.. _topics-models: ====== Models ====== A model represents a single business logic or concept. It contains fields and defines the behaviors of the record. Most of the time, each model stores records in a single database table. The basics: * Each model is a Python class that subclasses one of :class:`~trytond.model.Model`. * :ref:`Fields ` are defined as model attributes. * Tryton generates the table definitions * Tryton provides an API following the `active record pattern`_ to access the records. .. _active record pattern: http://en.wikipedia.org/wiki/Active_record Example ======= This example defines a ``Party`` model which has a ``name`` and a ``code`` fields:: from trytond.model import ModelView, ModelSQL, fields class Party(ModelSQL, ModelView): "Party" __name__ = "party.party" name = fields.Char('Name') code = fields.Char('Code') The class must be registered in the :class:`~trytond.pool.Pool` by the ``register()`` method of the :ref:`module `. Model classes are essentially data mappers to records and Model instances are records. Model attributes define meta-information of the model. They are class attributes starting with an underscore. Some model properties are instance attributes allowing to update them at other places in the framework. ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1745680201.723055 trytond-7.0.30/doc/topics/modules/0000755000175000017500000000000015003173512015127 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/modules/index.rst0000644000175000017500000001360614517761237017016 0ustar00cedced.. _topics-modules: ======= Modules ======= The modules of Tryton extend the functionality of the platform. The server comes by default with only a basic functionality included in these modules: ``ir``, ``res``. Module Structure ================ A module is a directory in :file:`trytond/modules` which contains at least two files: :file:`__init__.py` A Tryton module must be a Python module. :file:`tryton.cfg` A Configuration file that describes the Tryton module. .. _topics-modules-init: :file:`__init__.py` file ------------------------ It is the Python :file:`__init__.py` to define a module. It must contains a method named ``register()`` that must register to the pool all the objects of the module. .. _topics-modules-tryton-cfg: :file:`tryton.cfg` file ----------------------- It is a configuration file using the format of `ConfigParser`_ that must contain ``tryton`` section with this following keys: ``version`` The version number of the module. ``depends`` A one per line list of modules on which this module depends. ``extras_depend`` A one per line list of modules on which this module *may* depend. ``xml`` The one per line list of the XML files of the module. They will be loaded in the given order when the module is activated or updated. Here is an example: .. code-block:: ini [tryton] version=0.0.1 depends: ir res country xml: party.xml category.xml address.xml contact_mechanism.xml Python Files ============ The Python files define the models for the modules. .. _topics-modules-xml-files: XML Files ========= The XML files define data that are inserted into the database on activation. There is an RNC for those files stored in :file:`trytond/tryton.rnc`. The following snippet gives a first idea of what an XML file looks: .. highlight:: xml :: Party Administration party.party tree ]]> Here is the list of the tags: ``tryton`` The main tag of the XML ``data`` Define a set of data inside the file. It can have the attributes: ``noupdate`` Prevent the framework to update the records, ``depends`` Import data only if all modules in the comma separated module list value are activated, ``grouped`` Create records at the end with a grouped call. ``language`` Import data only if the language is translatable. ``record`` Create a record of the model defined by the attribute ``model`` in the database. The ``id`` attribute can be used to refer to the record later in any XML file. ``field`` Set the value of the field with the name defined by the attribute ``name``. Here is the list of attributes: ``search`` Only for relation field. It contains a domain which is used to search for the value to use. The first value found will be used. ``ref`` Only for relation field. It contains an XML id of the relation to use as value. It must be prefixed by the module name with an ending dot, if the record is defined in an other module. ``eval`` Python code to evaluate and use result as value. The following expressions are available: ``time`` The python time_ module. ``version`` The current Tryton version. ``ref`` A function that converts an XML id into a database id. ``Decimal`` The python Decimal_ object. ``datetime`` The python datetime_ module. ``pyson`` Convert the evaluated value into :ref:`PYSON ` string. ``depends`` Set value only if all modules in the comma separated module list value are activated. .. note:: Field content is considered as a string. So for fields that require other types, it is required to use the ``eval`` attribute. ``menuitem`` Shortcut to create ``ir.ui.menu`` records. Here is the list of attributes: ``id`` The id of the menu. ``name`` The name of the menu. ``icon`` The icon of the menu. ``sequence`` The sequence value used to order the menu entries. ``parent`` The XML id of the parent menu. ``action`` The XML id of the action linked to the menu. ``groups`` A list of XML id of group, that have access to the menu, separated by commas. ``active`` A boolean telling if the menu is active or not. .. _ConfigParser: http://docs.python.org/library/configparser.html .. _time: http://docs.python.org/library/time.html .. _Decimal: https://docs.python.org/library/decimal.html .. _datetime: https://docs.python.org/library/datetime.html .. _RNG: https://en.wikipedia.org/wiki/RELAX_NG ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/pyson.rst0000644000175000017500000000745714517761237015416 0ustar00cedced.. _topics-pyson: ===== PYSON ===== PYSON is the PYthon Statement and Object Notation. It is a lightweight `domain specific language`_ for the general representation of statements. PYSON is used to encode statements which can be evaluated in different programming languages, serving for the communication between trytond and any third party software. A PYSON parser can easily be implemented in other programming languages. So third party softwares do not need to depend on Python to be able to fully communicate with the Tryton server. PYSON is a `deterministic algorithm`_ which will always succeed to evaluate statements. There is a default behavior for unknown values. It is statically typed and checked on instantiation. There is also a :ref:`reference documentation of the API `. .. _`domain specific language`: http://en.wikipedia.org/wiki/Domain-specific_language .. _`deterministic algorithm`: http://en.wikipedia.org/wiki/Deterministic_algorithm Syntax ====== The syntax of a PYSON statement follows this pattern:: Statement(argument1[, argument2[, ...]]) where arguments can be another statement or a value. The evaluation direction is inside out, deepest first. PYSON Examples ============== Given the PYSON statement:: Eval('active_id', -1) :class:`~trytond.pyson.Eval` checks the evaluation context for the variable ``active_id`` and returns its value or ``-1`` if not defined. A similar expression in Python looks like this:: 'active_id' in locals() and active_id or -1 Given the PYSON statement:: Not(Bool(Eval('active'))) :class:`~trytond.pyson.Eval` checks the evaluation context for a variable ``active`` and returns its value to :class:`~trytond.pyson.Bool` or ``''`` if not defined. :class:`~trytond.pyson.Bool` returns the corresponding boolean value of the former result to :class:`~trytond.pyson.Not`. :class:`~trytond.pyson.Not` returns the boolean negation of the previous result. A similar expression in Python looks like this:: 'active' in locals() and active == False Given the PYSON statement:: Or(Not(Equal(Eval('state'), 'draft')), Bool(Eval('lines'))) In this example are the results of two partial expressions ``Not(Equal(Eval('state'), 'draft'))`` and ``Bool(Eval('lines'))`` evaluated by a logical *OR* operator. The first expression part is evaluated as follow: When the value of ``Eval('state')`` is equal to the string ``'draft'`` then return true, else false. :class:`~trytond.pyson.Not` negates the former result. A similar expression in Python looks like this:: 'states' in locals() and 'lines' in locals() and state != 'draft' or bool(lines) Given the PYSON statement:: If(In('company', Eval('context', {})), '=', '!=') In this example the result is determined by an `if-then-else`_ condition. ``In('company', Eval('context', {}))`` is evaluated like this: When the key ``'company'`` is in the dictionary ``context``, returns true, otherwise false. :class:`~trytond.pyson.If` evaluates the former result and returns the string ``'='`` if the result is true, otherwise returns the string ``'!='``. A similar expression in Python looks like this:: 'context' in locals() and isinstance(context, dict) and 'company' in context and '=' or '!=' .. _if-then-else: https://en.wikipedia.org/wiki/Conditional_(computer_programming)#If%E2%80%93then(%E2%80%93else) Given the PYSON statement:: Get(Eval('context', {}), 'company', 0)) :class:`~trytond.pyson.Eval` checks the evaluation context for a variable ``context`` if defined, return the variable ``context``, otherwise return an empty dictionary ``{}``. :class:`~trytond.pyson.Get` checks the former resulting dictionary and returns the value of the key ``'company'``, otherwise it returns the number ``0``. A similar expression in Python looks like this:: 'context' in locals() and context.get('company', 0) or 0 ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1745680201.723055 trytond-7.0.30/doc/topics/reports/0000755000175000017500000000000015003173512015155 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/reports/index.rst0000644000175000017500000002104614517761237017041 0ustar00cedced.. _topics-reports: ======= Reports ======= Tryton can generate dynamic reports in many formats from templates. The reports are generated in one step as follows: a report template in a special file format, explained later, is interpolated with dynamic data and placed into a document of the same file format. Tryton's ability to generate documents in this way allows documents to be generated for any editor that supports the Open Document Format which can be converted to third party formats, such as PDF. `LibreOffice`_ must be installed on the server host for format conversion. .. _LibreOffice: https://www.libreoffice.org/ Report Templates ================ Report templates are files with a format supported by relatorio_, that contain snippets of the Genshi_ templating language. Here is an example of the text that would be placed in an open document text document, ``*.odt``, that displays the full name and the address lines of the first address of each party. The Genshi code is placed in the template using "Placeholder Text Fields". These are specific to ODT files. .. _relatorio: https://relatorio.tryton.org/ .. _Genshi: https://genshi.edgewall.org/ When defining an ``ir.action.report`` the following attributes are available: ``name`` The name of the report. ``report_name`` The ``__name__`` of the report model. ``model`` The :attr:`~trytond.model.Model.__name__` of the :class:`~trytond.model.Model` the report is based. Report that is not for a specific model, needs to leave this empty. ``report`` The path to the template file starting with the module directory. ``template_extension`` The template format. ``single`` ``True`` if the template works only for one record. If such report is called with more than one record, a zip file containing all the reports will be generated. ``record_name`` A Genshi Expression to compute the filename for each record. Report Usage ============ Using Genshi and Open Office ---------------------------- Setting up an ODT file ^^^^^^^^^^^^^^^^^^^^^^ If you are creating a report from scratch you should perform the following steps: - Remove user data * Open :menuselection:`File --> Properties...` * Uncheck "Apply user data" * Uncheck "Save preview image with this document" * Click on "Reset Properties" - Set some parameters * Set the zoom to 100% (View>Zoom) * Set the document to read-only mode (:menuselection:`File --> Properties.. --> Security`) (Decreases the time it takes to open the document.) - Usage * Use Liberation fonts (Only necessary if being officially included in Tryton) * Try to use styles in report templates so that they can be extended. Using Genshi in an ODT file ^^^^^^^^^^^^^^^^^^^^^^^^^^^ The Genshi code is placed in the template using "Placeholder Text Fields". These are specific to ``*.odt`` files and can be found in the open office :menuselection:`Insert --> Fields --> More Fields...` menu and then by selecting Functions tab, Placeholder Type and Text Format. The Genshi code is placed into the Placeholder value. There are alternatives for embedding Genshi that are supported by relatorio but their use is not encouraged within Tryton. See Genshi's documentation for more information: `Genshi XML Template Language`_. .. _Genshi XML Template Language: https://genshi.edgewall.org/wiki/Documentation/xml-templates.html Accessing models from within the report --------------------------------------- By default instances of the models, the report is for, are passed in to the report via a list of ``records`` (or ``record`` if ``single`` is ``True``). These records behave just as they would within ``trytond`` itself. You can access any of the models relations as well. For example within the invoice report each record is an invoice and you can access the name of the party of the invoice via ``invoice.party.name``. Additional objects can be passed to a report. This is discussed below in `Passing custom values to a report`_ Within Tryton the model, the report is based on, can be found by opening the menu item:: |Administration --> Models --> Models|__ .. |Administration --> Models --> Models| replace:: :menuselection:`Administration --> Models --> Models` __ https://demo.tryton.org/model/ir.model Furthermore in Tryton the fields for that model can be found by opening the menu item:: |Administration --> Models --> Models --> Fields|__ .. |Administration --> Models --> Models --> Fields| replace:: :menuselection:`Administration --> Models --> Models --> Fields` __ https://demo.tryton.org/model/ir.model.field Creating a simple report template for a model from the client ------------------------------------------------------------- Once you have created a report template it has to be uploaded to the server. This can be done by creating a new record by opening the menu item:: |Administration --> User Interface --> Actions --> Reports|__ .. |Administration --> User Interface --> Actions --> Reports| replace:: :menuselection:`Administration --> User Interface --> Actions --> Reports` __ https://demo.tryton.org/model/ir.action.report Just make sure to include the template file in the content field. In order to make the report printable from a record create a ``Print form`` keyword related to the model where the report should be available. Customizing an existing report from the client ---------------------------------------------- The content of existing reports can be updated from the menu item: :menuselection:`Administration --> User Interface --> Actions --> Reports` The easiest way is to download the existing content, edit it and upload it back to the server. .. note:: It is possible to restore the original content by clearing the content and saving the record. Creating a simple report template for a model within a module ------------------------------------------------------------- Once you have created a report template stored in your module, you must create an XML record of ``ir.action.report`` and another XML record of ``ir.action.keyword`` like: .. code-block:: xml My Report my_module.my_report model.name my_module/report.fodt odt form_print model.name,-1 Replacing existing Tryton reports withing a module -------------------------------------------------- To replace an existing report you must deactivate the old report and activate the new report. For example to deactivate the sale report: .. code-block:: xml Then you must create your new sale report: .. code-block:: xml Sale sale.sale sale.sale my_module/sale.odt odt form_print sale.sale,-1 Passing custom values to a report --------------------------------- In this example ``Report.get_context`` is overridden and an employee record is set into context. Now the invoice report will be able to access the employee record. .. code-block:: python from tryton.pool import Pool from trytond.report import Report from trytond.transaction import Transaction class InvoiceReport(Report): __name__ = 'account.invoice' @classmethod def get_context(cls, records, header, data): pool = Pool() Employee = pool.get('company.employee') context = super().get_context(records, header, data) employee_id = Transaction().context.get('employee') employee = Employee(employee_id) if employee_id else None context['employee'] = employee return context ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/rpc.rst0000644000175000017500000000254514517761237015023 0ustar00cedced.. _topics-rpc: ===================== Remote Procedure Call ===================== There are two protocols supported by trytond: `JSON-RPC`_ (Version 1.0) and `XML-RPC`_. The URL of the calls must end with the database name with a trailing '/'. The available methods are: common.db.login --------------- It takes as parameters: the user name and a dictionary of login parameters. It returns in case of success the user ID and the session. If the parameters are not valid to authenticate the user, it returns nothing. Otherwise if it misses a key in the parameters, it raises a ``LoginException`` exception with the missing key name, type and the message to ask to the user. common.db.logout ---------------- It takes no parameters and it invalidate the current session. .. TODO - other methods .. _`JSON-RPC`: https://en.wikipedia.org/wiki/JSON-RPC .. _`XML-RPC`: https://en.wikipedia.org/wiki/XML-RPC Authorization ============= Most of the calls require authorization, there are two methods: Basic ----- It follows the `Basic access authentication`_. .. _`Basic access authentication`: https://en.wikipedia.org/wiki/Basic_access_authentication Session ------- The authorization field is constructed by the username, the user ID and the session combined with a single colon and encoded in Base64. The session is retrieved by calling the method ``common.db.login``. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1732989966.0 trytond-7.0.30/doc/topics/setup_database.rst0000644000175000017500000000336214722652016017211 0ustar00cedced.. _topics-setup-database: ======================= How to setup a database ======================= The database section of the :ref:`configuration ` must be set before starting. Create a database ================= Depending of the database backend choosen, you must create a database (see the documentation of the choosen backend). The user running ``trytond`` must be granted the priviledge to create tables. For backend that has the option, the encoding of the database must be set to ``UTF-8``. Initialize a database ===================== A database can be initialized using this command line: .. code-block:: console $ trytond-admin -c -d --all At the end of the process, ``trytond-admin`` will ask to set the password for the ``admin`` user. Update a database ================= To upgrade to a new series, the command line is: .. code-block:: console $ trytond-admin -c -d --all .. warning:: Prior to upgrade see if there is no manual action to take on the `migration topic`_. .. _`migration topic`: https://docs.tryton.org/migration To activate a new language on an existing database, the command line is: .. code-block:: console $ trytond-admin -c -d --all -l Once activated, the language appears in the user preferences. When installing new modules, the list of modules must be updated with: .. code-block:: console $ trytond-admin -c -d --update-modules-list Once updated, the new modules can be activated from the client or activated with: .. code-block:: console $ trytond-admin -c -d -u --activate-dependencies ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/start_server.rst0000644000175000017500000000554014517761237016760 0ustar00cedced.. _topics-start-server: ======================= How to start the server ======================= Web service =========== You can start the default web server bundled in ``trytond`` with this command line: .. code-block:: console $ trytond -c The server will wait for client connections on the interface defined in the ``web`` section of the :ref:`configuration `. .. note:: When using multiple config files the order is important as last entered files will override the items of first files .. warning:: This runs the of `Werkzeug`_ development server which should not be used on production systems. .. _`Werkzeug`: https://werkzeug.palletsprojects.com/ WSGI server ----------- If you prefer to run Tryton inside your own WSGI server instead of the simple server of Werkzeug, you can use the application ``trytond.application.app``. Following environment variables can be set: * ``TRYTOND_CONFIG``: Point to :ref:`configuration ` file. * ``TRYTOND_LOGGING_CONFIG``: Point to :ref:`logging ` file. * ``TRYTOND_LOGGING_LEVEL``: An integer to set the default `logging level`_ (default: ``ERROR``). * ``TRYTOND_COROUTINE``: Use coroutine for concurrency. * ``TRYTOND_DATABASE_NAMES``: A list of database names in CSV format, using python default dialect. .. warning:: You must manage to serve the static files from the web root. .. _`logging level`: https://docs.python.org/library/logging.html#logging-levels Coroutine server ---------------- The Werkzeug server uses thread for concurrency. This is not optimal for the long-polling request on the :ref:`bus ` as each client consumes permanently one thread. You can start the server with coroutine using the option ``--coroutine``. .. note:: This will use the pure-Python, gevent-friendly `WSGI server `_. Cron service ============ If you want to run some :ref:`scheduled actions `, you must also run the cron server with this command line: .. code-block:: console $ trytond-cron -c -d The server will wake up every minutes and preform the scheduled actions defined in the ``database``. You can also launch the command every few minutes from a scheduler with the option ``--once``. Worker service ============== If you want to use a pool of workers to run :ref:`asynchronously some tasks `, you must activate the worker in the ``queue`` section of the :ref:`configuration ` and run the worker manager with this command line: .. code-block:: console $ trytond-worker -c -d The manager will dispatch tasks from the queue to a pool of worker processes. Services options ================ You will find more options for those services by using ``--help`` arguments. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/task_queue.rst0000644000175000017500000000426514517761237016406 0ustar00cedced.. _topics-task-queue: ========== Task Queue ========== Tryton provides a way to run asynchronously some tasks. You must activate the worker in the ``queue`` section of the :ref:`configuration ` and :ref:`run the worker manager ` otherwise the tasks will be run at the end of the transaction. A task is the parameters that defines how to call a method from a :class:`~trytond.model.Model`. This include the :attr:`~trytond.transaction.Transaction.context`, the :attr:`~trytond.transaction.Transaction.user` and the arguments. The first argument of the method must be an instance or a list of instances of :class:`~trytond.model.Model`. This other arguments must be JSON-ifiable. A task is pushed into the ``queue`` by calling the desired method on the :attr:`~trytond.model.Model.__queue__`. This stores in the queue all the current parameters of the call and it will be execute by a worker or at the end of the transaction if no worker is configured. The following :attr:`~trytond.transaction.Transaction.context` keys are used as parameters for the queue: ``queue_name`` The name of the queue. Default value is ``default``. ``queue_scheduled_at`` A ``datetime.timedelta`` to add to current time to define when the task should be started. Default value is ``None`` which means directly. ``queue_expected_at`` A ``datetime.timedelta`` to add to current time to define when the task should be finished. Default value is ``None`` which means as soon as possible. ``queue_batch`` An ``integer`` to divide the instances by batch of this size. If the value is ``true`` then the size is the value defined by the configuration ``queue`` of ``batch_size``. Default is ``None`` which means no division. .. warning:: There is no access right verification during the execution of the task. Example: .. highlight:: python :: from trytond.model import Model class MyModel(Model): "My Model" __name__ = 'my_model' @classmethod def launch(cls, records): for record in records: cls.__queue__.process(record, 42) def process(self, value): self.value = value ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1707150267.0 trytond-7.0.30/doc/topics/testing.rst0000644000175000017500000000550014560205673015701 0ustar00cedced.. _topics-testing: ======= Testing ======= Tryton supports both functional and unit tests. Testing your module ~~~~~~~~~~~~~~~~~~~ Functional tests ---------------- Functional tests are written as doctests_ using proteus. Unit tests ---------- Tryton provides the :class:`~trytond.tests.test_tryton.ModuleTestCase` class that bundles a set of tests that are useful for every module. Unit tests in :class:`~trytond.tests.test_tryton.ModuleTestCase` can be decorated with :func:`~trytond.tests.test_tryton.with_transaction` to run the test in a transaction. To use it in your own module you just have to inherit from :class:`~trytond.tests.test_tryton.ModuleTestCase` and set the class attribute :attr:`~trytond.tests.test_tryton.ModuleTestCase.module` to the name of your module. .. code-block:: python from trytond.tests.test_tryton import ModuleTestCase, with_transaction class MyModuleTestCase(ModuleTestCase): "My Module Test Case" module = 'my_module' @with_transaction() def test_method(self): "Test method" self.assertTrue(True) del ModuleTestCase .. note:: The ``ModuleTestCase`` must be deleted to not be discovered by ``unittest`` as it fails to run without module declaration. .. _doctests: https://docs.python.org/library/doctest.html .. _unittest: https://docs.python.org/library/unittest.html Running trytond's tests ----------------------- You can run a specific test file using ``unittest`` command line like: .. code-block:: console $ python -m unittest trytond.tests.test_tools To run all trytond's tests using discover of ``unittest`` with: .. code-block:: console $ python -m unittest discover -s trytond.tests To run all modules tests: .. code-block:: console $ python -m unittest discover -s trytond.modules Running your module's tests --------------------------- You just need to replace the directory path with the one of your module: .. code-block:: console $ python -m unittest discover -s trytond.modules.my_module.tests Extending trytond's tests ------------------------- Python modules extending ``trytond`` core can define additional classes to register in ``tests`` module. Those modules must create an entry point ``trytond.tests`` which defines a ``register`` function to be called with the module name. Testing options ~~~~~~~~~~~~~~~ Tryton runs tests against the configured database backend. You can specify the name of the database to use via the environment variable ``DB_NAME``. Otherwise it generates a random name. A configuration file can be used by setting its path to the environment variable ``TRYTOND_CONFIG``. The tests recreate frequently the database. You can accelerate the creation by setting a cache directory in ``DB_CACHE`` environment which will be used to dump and restore initial databases backups. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/translation.rst0000644000175000017500000000421714517761237016573 0ustar00cedced.. _topics-translation: =========== Translation =========== The translation of the user interface is provided module-wise. Translations are stored in the ``locale/`` directory of a module, each language in a `PO-file `_. The official language files are named after the `POSIX locale `_ standard, e.g. de.po, es.po, es_AR.po, es_EC.po... The names of custom language files must match the code of the language in the :class:`~trytond.model.Model` ``ir.lang``. If a language is set ``translatable``, the translations is loaded into the database on each update. Tryton supports derivative translations. This means that if the translation of a term is missing in one language, it will search on the parent languages. Also when activate a children language, you must also activate all parents. Translation Wizards =================== Set Translations ---------------- The wizard adds new translations to the base language ``en``. Clean Translations ------------------ The wizard deletes obsolete translations from the database. Synchronize Translations ------------------------ The wizard updates the translations of the selected language based on the translations of the base language ``en``. It will also remove duplicate translations with its direct parent. Export Translations ------------------- The wizard requires to select a language and a module and will export the translations for this selection into a PO-file. Override translations ===================== Translations of a module can be overridden by another module. This can be done by putting a PO file into the :file:`locale/override` directory of the module that shall contain the translations to override. To override the translation of another module the ``msgctxt`` string must have the following content: ``type:name:module.xml_id`` type The field type of ir.translation. name The field name of ir.translation. module The field module ir.translation. xml_id The XML id that is stored in ``ir.model.data`` as ``fs_id``. It is optional and can be omitted if it is None. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/triggers.rst0000644000175000017500000000163214517761237016061 0ustar00cedced.. _topics-triggers: ======== Triggers ======== Triggers allow to define methods of :class:`~trytond.model.Model` that are called at the end of the transaction when one of those events happen to a record: * On Creation * On Modification * On Deletions * On Time: When a condition changes over time. The method signature is:: (cls, records, trigger) Where ``records`` is the list of records that triggered the event and ``trigger`` is the ``ir.trigger`` instance which is triggered. Triggers are defined by records of ``ir.trigger``. Each record must define a pyson condition which will be evaluated when the event occurs. Only those records for which the condition is evaluated to true will be processed by the trigger with the exception of modification triggers which will only process the records for which the condition is evaluated to false before and evaluated to true after the modification. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/user_application.rst0000644000175000017500000000504414517761237017575 0ustar00cedced.. _topics-user_application: ================ User Application ================ Tryton provides a way to connect URL rules to an callable endpoint using the decorator method ``route`` of the ``trytond.wsgi.app`` instance. This allows you to define a custom API based on HTTP that can be used to create a specific user application. The decorator takes as first parameter a string which follow the `Rule Format`_ of Werkzeug and as second parameter sequence of HTTP methods. Example:: from trytond.wsgi import app @app.route('/hello', methods=['GET']) def hello(request): return 'Hello world' .. _Rule Format: http://werkzeug.pocoo.org/docs/latest/routing/#rule-format The following converter is added by Tryton: ``base64`` This converter accepts any Base64_ string and transforms it into its corresponding bytes value. .. _Base64: https://en.wikipedia.org/wiki/Base64 Tryton also provides some wrappers in ``trytond.protocols.wrappers`` to ease the creation of such route. ``set_max_request_size(size)`` Change the default limit of the request to the size in bytes. ``allow_null_origin`` Allow requests which have their ``Origin`` set to ``null``. ``with_pool`` Take the first parameter as database name and replace it by the corresponding instance of the :ref:`Pool `. ``with_transaction([readonly])`` Start a :class:`~trytond.transaction.Transaction` using the :ref:`Pool ` from ``with_pool``. If ``readonly`` is not set, the transaction will not be readonly for ``POST``, ``PUT``, ``DELETE`` and ``PATCH`` methods and readonly for all others. ``user_application(name[, json])`` Set the :attr:`~trytond.transaction.Transaction.user` from the ``Authorization`` header using the type ``bearer`` and a valid key for the named user application. User Application Key ==================== Tryton also provides a easy way to manage access to user application using keys per named application. A key is created with a ``POST`` request on the ``URL`` ``//user/application/`` which returns the key. The request must contain as data a JSON object with the keys: ``user`` The user login. ``application`` The name of the application. After the creation, the key must be validated by the user from the preferences of a Tryton client. A key can be deleted with a ``DELETE`` request on the same ``URL``. The request must contain as data a JSON object with the keys: ``user`` The user login. ``key`` The key to delete. ``application`` The name of the application of the key. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/user_errors_warnings.rst0000644000175000017500000000376214517761237020523 0ustar00cedced.. _topics-user_errors_warnings: ======================== User Errors and Warnings ======================== When processing a request, you can stop the flow by raising an exception that will be displayed to the user as an error message or a warning. They are respectively :exc:`~trytond.exceptions.UserError` and :exc:`~trytond.exceptions.UserWarning`. User Errors =========== An error displays a message and optionally a description to the user. Example: .. highlight:: python :: from trytond.exceptions import UserError from trytond.model import Model class MyModel(Model): "My Model" __name__ = 'my_model' def process(self): if check_failed: raise UserError("You cannot process.", "because…") .. note:: They are often used in combination with :meth:`~trytond.i18n.gettext` to translate the messages. User Warnings ============= A warning displays a confirmation message with optionally a description to the user. The user can decide to continue so the request is processed again without stopping at the warning. Otherwise the user can cancel its request. The warning instance is identified by a name which allows to skip it the next time it is checked, that's why they often build using the ``format`` method which uses record instances to generate a unique name based on ids. Example: .. highlight:: python :: from trytond.exceptions import UserWarning from trytond.model import Model from trytond.pool import Pool class MyModel(Model): "My Model" __name__ = 'my_model' def process(self): pool = Pool() Warning = pool.get('res.user.warning') warning_name = Warning.format('mywarning', [self]) if Warning.check(warning_name): raise UserWarning(warning_name, "Process cannot be canceled.") .. note:: If there is no user interaction the warnings can be skipped by setting the ``_skip_warnings`` key of the context to ``True``. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1745680201.7263882 trytond-7.0.30/doc/topics/views/0000755000175000017500000000000015003173512014614 5ustar00cedced././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/views/extension.rst0000644000175000017500000000215214517761237017402 0ustar00cedced.. _topics-extension: ============== Extending View ============== Extending a view means, that the original view will be modified by a set of rules which are defined with XML. For this purpose, the extension engine uses XPath_ expressions. The view is defined with the field ``inherit`` of the ``ir.ui.view``. If the field :ref:`domain ` is not set or evaluated to ``True``, the inheritance will be proceeded. .. _XPath: https://en.wikipedia.org/wiki/XPath Example: .. highlight:: xml :: data ---- Each view must start with this tag. xpath ----- ``expr`` The XPath expression to find the nodes in the inherited view. ``position`` Define the position in relation to the nodes found. It can be ``before``, ``after``, ``replace``, ``inside`` or ``replace_attributes`` which will change the attributes. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1698685599.0 trytond-7.0.30/doc/topics/views/index.rst0000644000175000017500000006146414517761237016510 0ustar00cedced.. _topics-views: ===== Views ===== The views are used to display records of an :class:`ModelView ` to the user. In Tryton, :class:`ModelView ` can have several views. An ``action`` opens a window and defines which view to show. The views are built from XML that is stored in the :file:`view` directory of the module or in the databases thanks to the model ir.ui.view. So generally, they are defined in XML files with this kind of XML where name is the name of the XML file in the :file:`view` directory: .. highlight:: xml :: model name type name view_name There are different types of views: .. contents:: :local: :backlinks: entry :depth: 2 Some attributes are shared by many form elements: .. _common-attributes-id: ``id`` A unique identifier for the tag if there is no name attribute. .. _common-attributes-yexpand: ``yexpand`` A boolean to specify if the label should expand to take up any extra vertical space. .. _common-attributes-yfill: ``yfill`` A boolean to specify if the label should fill the vertical space allocated to it in the table cell. .. _common-attributes-yalign: ``yalign`` The vertical alignment, from 0.0 to 1.0. .. _common-attributes-xexpand: ``xexpand`` The same as ``yexpand`` but for horizontal space. .. _common-attributes-xfill: ``xfill`` The same as ``yfill`` but for horizontal space. .. _common-attributes-xalign: ``xalign`` The horizontal alignment, from ``0.0`` to ``1.0``. .. _common-attributes-colspan: ``colspan`` The number of columns the widget must take in the table. .. _common-attributes-col: ``col`` The number of columns the container must have. A negative value (or zero) remove the constraint on the number of columns. The default value is ``4``. .. _common-attributes-states: ``states`` A string of :ref:`PYSON statement ` that is evaluated with the values of the current record. It must return a dictionary where keys can be: ``invisible`` If true, the widget is hidden. ``required`` If true, the field is required. ``readonly`` If true, the field is readonly. ``icon`` Only for button, it must return the icon name to use or False. ``pre_validate`` Only for button, it contains a domain to apply on the record before calling the button. ``depends`` Only for button, it must return the list of field on which the button depends. .. _common-attributes-help: ``help`` The string that is displayed when the cursor hovers over the widget. .. _common-attributes-pre_validate: ``pre_validate`` A boolean only for fields :class:`trytond.model.fields.One2Many` to specify if the client must pre-validate the records using :meth:`trytond.model.Model.pre_validate`. .. _common-attributes-completion: ``completion`` A boolean only for fields :class:`trytond.model.fields.Many2One`, :class:`trytond.model.fields.Many2Many` and :class:`trytond.model.fields.One2Many` to specify if the client must auto-complete the field. The default value is ``True``. .. _common-attributes-create: ``create`` A boolean to specify if the user can create targets from the widget. The default value is ``True``. ``delete`` A boolean to specify if the user can delete targets from the widget. The default value is ``True``. .. _common-attributes-factor: ``factor`` A factor to apply on fields :class:`trytond.model.fields.Integer`, :class:`trytond.model.fields.Float` and :class:`trytond.model.fields.Numeric` to display on the widget. The default value is ``1``. .. _common-attributes-symbol: ``symbol`` Only on numerical fields, the name of field which provides the symbol to display. .. _common-attributes-grouping: ``grouping`` A boolean only on numerical fields to specify if the client must use grouping separators to display on the widget. The default value is ``True``. .. _common-attributes-help_field: ``help_field`` The name of Dict field mapping the Selection value with its help string. Form ==== A form view is used to display one record. Elements of the view are put on the screen following the rules: * Elements are placed on the screen from left to right, from top to bottom, according to the order of the XML. * The screen composed of a table with a fixed number of columns and enough rows to handle all elements. * Elements take one or more columns when they are put in the table. If there are not enough free columns on the current row, the elements are put at the beginning of the next row. .. _example_form_view: Example: .. highlight:: xml ::