Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][MIG][spec_driven_model] #2882

Merged
merged 178 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
178 commits
Select commit Hold shift + click to select a range
3ae943d
[ADD] spec_driven_model module for genDS mixins; WIP
rvalyi Dec 1, 2019
8b71dca
[WIP] Export xml from spec models
mileo Jan 9, 2020
4cfbaff
[NEW] Export button
mileo Jan 9, 2020
04ec081
[WIP] Export related fields
mileo Jan 9, 2020
4a21e72
[NEW] Export to xml many2one, monetary, datetime fields
mileo Jan 9, 2020
4efde1d
[NEW] Export XML One2many fields
mileo Jan 9, 2020
d876305
[REF] Clean code and improve performance
mileo Jan 10, 2020
1d44824
[REF] Clean code
mileo Jan 10, 2020
6f8010e
[IMP] Float and monetary export
mileo Jan 10, 2020
d5f2caf
[WIP] Stacked model recursion
mileo Jan 10, 2020
d91e393
[ADD] Print item xml
gabrielcardoso21 Jan 10, 2020
3b2ef8f
[ADD] Export all xml tags from xsd
gabrielcardoso21 Jan 21, 2020
0d95071
[REF] Clean code
mileo Jan 22, 2020
b542ea7
[REF] Remove prints
mileo Jan 22, 2020
5cab6ab
[REM] Unwanted tags
gabrielcardoso21 Jan 27, 2020
b26352d
[REM] Empty tags
gabrielcardoso21 Jan 30, 2020
1e8761c
[ADD] Export only correct ICMS tag
gabrielcardoso21 Jan 30, 2020
ac0aa3b
[ADD] Export CST tag
gabrielcardoso21 Jan 30, 2020
c334482
[ADD] Correct export of tag IPI
gabrielcardoso21 Jan 30, 2020
27e420e
[ADD] Correct export of tag PIS
gabrielcardoso21 Jan 30, 2020
af2ae9f
[ADD] Correct export of tag PIS
gabrielcardoso21 Jan 31, 2020
fb4f626
[REM] Tag ISSQN if not service
gabrielcardoso21 Jan 31, 2020
be2c7b0
[REF] Show only the correct tags
gabrielcardoso21 Jan 31, 2020
5d4f715
[ADD] Barcode logic
gabrielcardoso21 Feb 4, 2020
820221a
[ADD] modBC field
gabrielcardoso21 Feb 4, 2020
fa4104b
[REM] ISSQNtot when there is not any service
gabrielcardoso21 Feb 4, 2020
78102aa
[REM] Tags II, PISST and COFINSST
gabrielcardoso21 Feb 4, 2020
5b7f764
[NEW] ExportDS and ExportXML
mileo Feb 5, 2020
a7d8749
[FIX] Pep8 spec_driven_model
gabrielcardoso21 Feb 6, 2020
f139a59
[FIX] Replace print with logs and other lint errors
mileo Feb 10, 2020
0581fce
[FIX] Mensagens do _logger.info
gabrielcardoso21 Feb 11, 2020
ff8d39f
[ADD] Mensagem no nome fantasia do destinatário para notas em homolog…
gabrielcardoso21 Feb 19, 2020
cb74aef
[FIX] Campo valor do produto sem erros devidos a precisão
gabrielcardoso21 Feb 19, 2020
8b9c3f1
[ADD] Valor correto do campo
gabrielcardoso21 Feb 19, 2020
86e1ee6
[REF] Use _get_concrete function
gabrielcardoso21 Feb 6, 2020
b85f52c
[REM] Logging
gabrielcardoso21 Feb 11, 2020
bdd4531
[ADD] Campo nItem
gabrielcardoso21 Feb 27, 2020
7f2c5dc
[FIX] Erro na criação das views
gabrielcardoso21 Feb 28, 2020
600b813
[FIX] pep8
mileo Mar 7, 2020
b8c8c4f
[FIX] v['related'] len
sadamo Mar 13, 2020
57d8706
[REM] Unnecessary comments
gabrielcardoso21 Mar 19, 2020
ab50fe5
[REF] Rename function
gabrielcardoso21 Mar 19, 2020
09b12e9
[REF] Encapsulation
gabrielcardoso21 Mar 19, 2020
55c75d1
[REM] Unnecessary comments
gabrielcardoso21 Mar 23, 2020
691c6f6
[REF] Encapsulation
gabrielcardoso21 Mar 23, 2020
4740fa8
[REM] Stacked from res_partner and res_company
gabrielcardoso21 Mar 27, 2020
00a38c1
[FIX] Pep8
gabrielcardoso21 Apr 7, 2020
68969de
[FIX] Import
gabrielcardoso21 Jun 23, 2020
4382cf3
[REF] One2many export
gabrielcardoso21 Oct 1, 2020
872ccec
avoids logger error and logs StackModel init
rvalyi Dec 9, 2020
7d64f68
spec.mixin dynamically injected -> no dep required
rvalyi Dec 9, 2020
b432354
removed most of NFe schema specifics
rvalyi Dec 9, 2020
0c297d9
skip int/float/monetary defaults because None->0
rvalyi Dec 9, 2020
7bb8d7a
assume XSD tags can be skipped from generated models
rvalyi Dec 9, 2020
04e7a15
better dry-run support (no create)
rvalyi Dec 9, 2020
a1ef0ae
propagate path in _build_many2one for better import control
rvalyi Dec 9, 2020
b889f6b
normal py3 StringIO import
rvalyi Dec 9, 2020
7c8d416
important: map_concrete spec classes injected in SpecModel
rvalyi Dec 10, 2020
87b5735
class _prepare_import_dict hook when m2o are created
rvalyi Dec 10, 2020
ea1aeaf
_inject_spec_mixin before super -> less loops inside method
rvalyi Dec 11, 2020
ca6a3fb
document spec model attributes without inconsistently shadowing spec.…
rvalyi Dec 11, 2020
2d6cf9e
flake8 + comment
rvalyi Dec 11, 2020
1afe9bd
overrideable create_m2o in _prepare_import_dict
rvalyi Dec 12, 2020
7c88e10
license headers -> LGPL 3
rvalyi Dec 12, 2020
07ca7c8
[UPD] Update spec_driven_model.pot
oca-travis Dec 15, 2020
6eefc5f
Added translation using Weblate (Portuguese (Brazil))
marcelsavegnago Dec 17, 2020
72642c9
Translated using Weblate (Portuguese (Brazil))
marcelsavegnago Dec 17, 2020
412a9b5
make XML export schema agnostic
rvalyi Dec 17, 2020
6285b0a
Translated using Weblate (Portuguese (Brazil))
marcelsavegnago Dec 18, 2020
457b721
skip non spec fields like o2m foreign keys
rvalyi Jan 28, 2021
4cde665
[FIX] flake8
marcelsavegnago Feb 10, 2021
5d63a7e
domain and field views fixes for form test compat
rvalyi Feb 9, 2021
2219b1e
same field can appear several times in a form
rvalyi Feb 9, 2021
8844023
disable Gabriel debug export_xml button as it breaks views
rvalyi Feb 9, 2021
0f79afd
[FIX] flake8
marcelsavegnago Feb 9, 2021
56137ef
made spec_driven_model spec_view schema agnostic
rvalyi Feb 9, 2021
d327420
trigger model DDL only when updating module
rvalyi Feb 17, 2021
7100a66
avoid cluttering the view with large related fields
rvalyi Feb 17, 2021
f6ced64
lint: default import vals should be passed by ctx
rvalyi Feb 18, 2021
844571d
proper display_name
rvalyi Mar 2, 2021
f1626a0
fields aren't stacked yet when _visit_stack
rvalyi Mar 2, 2021
8b7e686
auto_init hook trigger fix when removing module
rvalyi Mar 2, 2021
e27fa40
removed auto m2o filtering, tests coming...
rvalyi Mar 2, 2021
29680dd
ensure proper _table of stacked classes
rvalyi Mar 2, 2021
3924e2e
remove stacking fields and mutate fields in _setup_fields
rvalyi Mar 2, 2021
e46315e
import: docstrings and missing @api.model
rvalyi Mar 3, 2021
fc8397e
import: fully schema agnostic, tested in l10n_br_nfe
rvalyi Mar 3, 2021
89e3250
export: stacking points update + docstring + ensure.one
rvalyi Mar 3, 2021
dcd98ed
flake8
rvalyi Mar 3, 2021
59328b4
flake8
rvalyi Mar 3, 2021
914f44c
attempt to fix import bad key create warning
rvalyi Mar 8, 2021
e4316c4
faster import (less SQL calls)
rvalyi Mar 8, 2021
2538e65
fixed stacking field addition
rvalyi Mar 8, 2021
979ae09
simplified _setup_fields
rvalyi Mar 8, 2021
9fddf9c
hooks are now schema agnostic
rvalyi Mar 11, 2021
4ea2b2f
basic module author information
rvalyi Mar 11, 2021
4d8a818
secure ACL
rvalyi Mar 11, 2021
5c2849a
multi-schemas spec_module class lookup
rvalyi Mar 24, 2021
bff8808
makes simple type detection more robust
rvalyi Mar 24, 2021
32fd85a
simplify dry_run import params
rvalyi Mar 24, 2021
21c6d9c
solid coverage with MS PurchaseOrderSchema.xsd
rvalyi Mar 24, 2021
c0cd2eb
flake8
rvalyi Mar 24, 2021
ce5b636
pylint workaround for generated code in tests
rvalyi Mar 24, 2021
9a906c6
cleaner SQL request
rvalyi Mar 30, 2021
acbd515
small edit to make pylint work with generated code
rvalyi Mar 30, 2021
e0ccdb9
[FIX] Avoid translations loop / replace model original description
mileo Apr 17, 2021
c3b5c27
spec_driven_model 12.0.1.1.0
OCA-git-bot Apr 18, 2021
30b7215
optimize doc importation: no fields_get() query
rvalyi Jun 1, 2021
03d522d
[REF] Standard OCA website spec_driven_model
rvalyi Jun 4, 2021
dfad930
[ADD] Remove blank spaces
gabrielcardoso21 Jun 11, 2021
8483783
drier: no more _concrete_rec_name
rvalyi May 20, 2021
22be9bc
[REF] api.model 1st, ds_class -> binding_class
rvalyi Jun 20, 2021
2100771
[IMP] spec_driven_model: black, isort, prettier
rvalyi Jun 21, 2021
128f7ef
flake8, mostly B009
rvalyi Jun 21, 2021
1374158
[REF] build_arch lower complexity: extract 2 meths
rvalyi Jun 21, 2021
5c6c036
[UPD] Update spec_driven_model.pot
oca-travis Jul 4, 2021
593458f
[FIX] _force_stack_paths class attribute
renatonlima Aug 31, 2021
38f0efb
pre-commit
renatonlima Aug 31, 2021
96d17d1
spec_driven_model 12.0.1.2.0
OCA-git-bot Aug 31, 2021
c835417
[REF] cleanup spec model log message
renatonlima Sep 9, 2021
eb6f15d
[MIG] spec_driven_model: Migration to 13.0
rvalyi Oct 18, 2021
ed1f48a
[MIG] manual migration to 13.0
rvalyi Aug 3, 2021
779d78b
[UPD] Update spec_driven_model.pot
oca-travis Oct 18, 2021
ab8b4c5
[MIG] spec_driven_model: Migration to 14.0
rvalyi Oct 18, 2021
3493283
[MIG] Update spec_driven_model/tests/fake_mixin.py
rvalyi Oct 19, 2021
b0e9f6b
[UPD] Update spec_driven_model.pot
oca-travis Oct 19, 2021
1959356
[FIX] spec_driven_model: change and remove parameters unknown
marcelsavegnago Jun 2, 2022
4431d15
spec_driven_model 14.0.1.0.1
OCA-git-bot Jun 3, 2022
6c43d39
[FIX] mute spurious selection warnings
rvalyi Jul 19, 2022
6d7eb51
spec_driven_model 14.0.1.0.2
OCA-git-bot Jul 19, 2022
b8c3204
[FIX] register_hook guard fix + cleanup
rvalyi Jul 13, 2022
89f6520
[FIX] more robust spec ancestor injection
rvalyi Jul 13, 2022
525f61d
[REF] much cleaner/fix _visit_stack meth
rvalyi Aug 8, 2022
abf52e3
[ADD] add minimal readme
rvalyi Aug 8, 2022
688fc96
[UPD] README.rst
OCA-git-bot Aug 30, 2022
81f77ef
spec_driven_model 14.0.2.0.0
OCA-git-bot Aug 30, 2022
f48100c
Translated using Weblate (Portuguese (Brazil))
douglascstd Sep 16, 2022
a81d116
[REF] build -> build_from_binding (avoid collision)
rvalyi Aug 7, 2022
7fce42e
[REF] default_get working for dry run
rvalyi Aug 7, 2022
04474d7
[FIX] XML import: defaults on proper models
rvalyi Aug 28, 2022
19bd6d8
spec_driven_model 14.0.3.0.0
OCA-git-bot Oct 9, 2022
f6ea15c
[REF] missing-return spec_driven_model
mileo Oct 22, 2022
b5d214d
spec_driven_model 14.0.3.0.1
OCA-git-bot Oct 22, 2022
bd1453b
Implement dynamic dispatch _export_fields_CLASS_NAME
renatonlima Nov 29, 2022
d5a50d3
spec_driven_model 14.0.3.1.0
OCA-git-bot Dec 12, 2022
30cce42
[ADD] test-requirements.txt
rvalyi Nov 30, 2022
0e30865
do not export fields monetary xsd_required=False and value 0.00
renatonlima Dec 13, 2022
f7ed460
spec_driven_model 14.0.3.1.1
OCA-git-bot Dec 26, 2022
c5de6fc
spec_driven_model 14.0.3.1.2
OCA-git-bot Dec 26, 2022
3fb9877
[FIX] fix warning with xsd_implicit attr
rvalyi Nov 27, 2022
d839cf0
[REF] xsd_choice_required support
rvalyi Dec 25, 2022
5e621a5
spec_driven_model 14.0.4.0.0
OCA-git-bot May 11, 2023
8ae7390
[REF] test: binding generateDS -> xsdata
rvalyi Jun 11, 2022
b05a4b9
[REF] test: spec_poxsd generateds-odoo -> xsdata-odoo
rvalyi Jun 11, 2022
abd17b3
[REF] adapted spec_driven_model tests for xsdata
rvalyi Jun 11, 2022
3dca66e
[REF] adapted for xsdata export
rvalyi Jun 11, 2022
d26f5b6
[REF] adapted for xsdata import
rvalyi Jun 11, 2022
89a242d
[FIX] import Enum and CPX/Simple test
rvalyi Nov 27, 2022
67ea613
[FIX] set inverse field vals in dry run imports
rvalyi Dec 8, 2022
e616a4c
[IMP] imperative style docstrings
rvalyi Nov 27, 2022
be8b656
spec_driven_model 14.0.5.0.0
OCA-git-bot Jul 3, 2023
b35ef44
[UPD] README.rst
OCA-git-bot Sep 3, 2023
5e820cb
Update translation files
weblate Oct 9, 2023
429d1f0
[FIX] don't import readonly related m2o
rvalyi Oct 12, 2023
b1ad171
[FIX] robust Simple/Complex Type detection
rvalyi Oct 22, 2023
a5b4991
[BOT] post-merge updates
OCA-git-bot Oct 24, 2023
6dd1bea
[FIX] nfelib type validation on spec import attribute building
felipezago Aug 7, 2023
839939a
[BOT] post-merge updates
OCA-git-bot Oct 24, 2023
f39bfa1
[REF] spec_driven_model: Method Super without parameters, necessary f…
mbcosta Oct 25, 2023
5167eeb
[REF] spec_driven_model: Avoid error Flake8 E721 do not compare types…
mbcosta Oct 25, 2023
d799733
[BOT] post-merge updates
OCA-git-bot Oct 27, 2023
0c03303
[BOT] post-merge updates
OCA-git-bot Oct 27, 2023
edafb92
Translated using Weblate (Portuguese (Brazil))
marcelsavegnago Jan 2, 2024
25a1ed0
[REF] spec_driven_model: clean inherit+import
rvalyi Jul 22, 2024
f7431a9
[IMP] spec_driven_model: black, isort, prettier
rvalyi Jan 17, 2024
b09d435
[MIG] spec_driven_model: Migration to 15.0
rvalyi Jan 17, 2024
6551e56
[IMP] spec_driven_model: pre-commit stuff
rvalyi Jan 17, 2024
c8c5793
[MIG] spec_driven_model: Migration to 16.0
rvalyi Jan 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ exclude: |
# NOT INSTALLABLE ADDONS
# END NOT INSTALLABLE ADDONS
^l10n_br_nfe_spec/models/v4_0/| # (don't reformat generated code)
^spec_driven_model/tests/| # (tests include generated code)
# Files and folders generated by bots, to avoid loops
^setup/|/static/description/index\.html$|
# We don't want to mess with tool-generated files
Expand Down
1 change: 1 addition & 0 deletions oca_dependencies.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
web
account-payment
account-reconcile
odoo-test-helper
1 change: 1 addition & 0 deletions setup/spec_driven_model/odoo/addons/spec_driven_model
6 changes: 6 additions & 0 deletions setup/spec_driven_model/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
160 changes: 160 additions & 0 deletions spec_driven_model/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
=================
Spec Driven Model
=================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:7a60762120de2d0aa75c133393ab92467fdfd07bc140b199f292a250b0ffe461
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fl10n--brazil-lightgray.png?logo=github
:target: https://github.com/OCA/l10n-brazil/tree/16.0/spec_driven_model
:alt: OCA/l10n-brazil
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/l10n-brazil-16-0/l10n-brazil-16-0-spec_driven_model
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/l10n-brazil&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

Intro
~~~~~

This module is a databinding framework for Odoo and XML data: it allows to go from XML to Odoo objects back and forth. This module started with the `GenerateDS <https://www.davekuhlman.org/generateDS.html>`_ pure Python databinding framework and is now being migrated to xsdata. So a good starting point is to read `the xsdata documentation here <https://xsdata.readthedocs.io/>`_

But what if instead of only generating Python structures from XML files you could actually generate full blown Odoo objects or serialize Odoo objects back to XML? This is what this module is for!

First you should generate xsdata Python binding libraries you would generate for your specific XSD grammar, the Brazilian Electronic Invoicing for instance, or UBL.

Second you should generate Odoo abstract mixins for all these pure Python bindings. This can be achieved using `xsdata-odoo <https://github.com/akretion/xsdata-odoo>`_. An example is OCA/l10n-brazil/l10n_br_nfe_spec for the Brazilian Electronic Invoicing.

SpecModel
~~~~~~~~~

Now that you have generated these Odoo abstract bindings you should tell Odoo how to use them. For instance you may want that your electronic invoice abstract model matches the Odoo `res.partner` object. This is fairly easy, you mostly need to define an override like::


from odoo.addons.spec_driven_model.models import spec_models


class ResPartner(spec_models.SpecModel):
_inherit = [
'res.partner',
'partner.binding.mixin',
]

Notice you should inherit from `spec_models.SpecModel` and not the usual `models.Model`.

**Field mapping**: You can then define two ways mapping between fields by overriding fields from Odoo or from the binding and using `_compute=` , `_inverse=` or simply `related=`.

**Relational fields**: simple fields are easily mapped this way. However what about relational fields? In your XSD schema, your electronic invoice is related to the `partner.binding.mixin` not to an Odoo `res.partner`. Don't worry, when `SpecModel` classes are instanciated for all relational fields, we look if their comodel have been injected into some existing Odoo model and if so we remap them to the proper Odoo model.

**Field prefixes**: to avoid field collision between the Odoo fields and the XSD fields, the XSD fields are prefixed with the name of the schema and a few digits representing the schema version (typically 2 digits). So if your schema get a minor version upgrade, the same fields and classes are used. For a major upgrade however new fields and classes may be used so data of several major versions could co-exist inside your Odoo database.


StackedModel
~~~~~~~~~~~~

Sadly real life XML is a bit more complex than that. Often XML structures are deeply nested just because it makes it easier for XSD schemas to validate them! for instance an electronic invoice line can be a nested structure with lots of tax details and product details. In a relational model like Odoo however you often want flatter data structures. This is where `StackedModel` comes to the rescue! It inherits from `SpecModel` and when you inherit from `StackedModel` you can inherit from all the generated mixins corresponding to the nested XML tags below some tag (here `invoice.line.binding.mixin`). All the fields corresponding to these XML tag attributes will be collected in your model and the XML parsing and serialization will happen as expected::


from odoo.addons.spec_driven_model.models import spec_models


class InvoiceLine(spec_models.StackedModel):
_inherit = [
'account.move.line',
'invoice.line.binding.mixin',
]
_stacked = 'invoice.line.binding.mixin'

All many2one fields that are required in the XSD (xsd_required=True) will get their model stacked automatically and recursively. You can force non required many2one fields to be stacked using the `_force_stack_paths` attribute. On the contrary, you can avoid some required many2one fields to be stacked using the `stack_skip` attribute.


Hooks
~~~~~

Because XSD schemas can define lot's of different models, spec_driven_model comes with handy hooks that will automatically make all XSD mixins turn into concrete Odoo model (eg with a table) if you didn't inject them into existing Odoo models.

**Table of contents**

.. contents::
:local:

Usage
=====

See my detailed OCA Days explanations here:
https://www.youtube.com/watch?v=6gFOe7Wh8uA

You are also encouraged to look at the tests directory which features a full blown example from the famous PurchaseOrder.xsd from Microsoft tutorials.

Known issues / Roadmap
======================

Migrate from generateDS to xsdata; see the xsdata Pull Requests in the repo.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/l10n-brazil/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/l10n-brazil/issues/new?body=module:%20spec_driven_model%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Akretion

Contributors
~~~~~~~~~~~~

* `AKRETION <https://akretion.com/pt-BR/>`_:

* Raphaël Valyi <[email protected]>

* `KMEE <https://kmee.com.br>`_:

* Gabriel Cardoso de Faria <[email protected]>

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-rvalyi| image:: https://github.com/rvalyi.png?size=40px
:target: https://github.com/rvalyi
:alt: rvalyi

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-rvalyi|

This module is part of the `OCA/l10n-brazil <https://github.com/OCA/l10n-brazil/tree/16.0/spec_driven_model>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions spec_driven_model/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
17 changes: 17 additions & 0 deletions spec_driven_model/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2019 Akretion
# License LGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "Spec Driven Model",
"summary": """
Tools for specifications driven mixins (from xsd for instance)""",
"version": "16.0.1.0.0",
"maintainers": ["rvalyi"],
"license": "LGPL-3",
"author": "Akretion,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/l10n-brazil",
"depends": [],
"data": [],
"demo": [],
"development_status": "Beta",
}
192 changes: 192 additions & 0 deletions spec_driven_model/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
# Copyright (C) 2019-TODAY - Raphaël Valyi Akretion
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html).

import inspect
import logging
import sys

from odoo import SUPERUSER_ID, api, models

from .models.spec_models import SpecModel, StackedModel

_logger = logging.getLogger(__name__)


def post_init_hook(cr, registry, module_name, spec_module):
"""
Automatically generate access rules for spec models
"""
env = api.Environment(cr, SUPERUSER_ID, {})
remaining_models = get_remaining_spec_models(cr, registry, module_name, spec_module)
fields = [

Check warning on line 21 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L19-L21

Added lines #L19 - L21 were not covered by tests
"id",
"name",
"model_id/id",
"group_id/id",
"perm_read",
"perm_write",
"perm_create",
"perm_unlink",
]
access_data = []

Check warning on line 31 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L31

Added line #L31 was not covered by tests
for model in remaining_models:
underline_name = model.replace(".", "_")
model_id = "%s_spec.model_%s" % (

Check warning on line 34 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L33-L34

Added lines #L33 - L34 were not covered by tests
module_name,
underline_name,
)
access_data.append(

Check warning on line 38 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L38

Added line #L38 was not covered by tests
[
"access_%s_user" % (underline_name,),
underline_name,
model_id,
"%s.group_user" % (module_name,),
"1",
"0",
"0",
"0",
]
)
access_data.append(

Check warning on line 50 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L50

Added line #L50 was not covered by tests
[
"access_%s_manager" % (underline_name,),
underline_name,
model_id,
"%s.group_manager" % (module_name,),
"1",
"1",
"1",
"1",
]
)
env["ir.model.access"].load(fields, access_data)

Check warning on line 62 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L62

Added line #L62 was not covered by tests


def get_remaining_spec_models(cr, registry, module_name, spec_module):
"""
Figure out the list of spec models not injected into existing
Odoo models.
"""
cr.execute(
"""select ir_model.model from ir_model_data
join ir_model on res_id=ir_model.id
where ir_model_data.model='ir.model'
and module=%s;""",
(module_name,),
)
module_models = [
i[0]
for i in cr.fetchall()
if registry.get(i[0]) and not registry[i[0]]._abstract
]

injected_models = set()
for model in module_models:
base_class = registry[model]
# 1st classic Odoo classes
if hasattr(base_class, "_inherit"):
injected_models.add(base_class._name)
for cls in base_class.mro():
if hasattr(cls, "_inherit") and cls._inherit:
if isinstance(cls._inherit, list):
inherit_list = cls._inherit
else:
inherit_list = [cls._inherit]
for inherit in inherit_list:
if inherit.startswith("spec.mixin."):
injected_models.add(cls._name)

# visit_stack will now need the associated spec classes
injected_classes = set()
remaining_models = set()

for m in injected_models:
c = SpecModel._odoo_name_to_class(m, spec_module)
if c is not None:
injected_classes.add(c)

for model in module_models:
base_class = registry[model]
# 2nd StackedModel classes, that we will visit
if hasattr(base_class, "_stacked"):
node = SpecModel._odoo_name_to_class(base_class._stacked, spec_module)

env = api.Environment(cr, SUPERUSER_ID, {})
for (
_kind,
klass,
_path,
_field_path,
_child_concrete,
) in base_class._visit_stack(env, node):
injected_classes.add(klass)

all_spec_models = {
c._name
for name, c in inspect.getmembers(sys.modules[spec_module], inspect.isclass)
if c._name in registry
}

remaining_models = remaining_models.union(
{i for i in all_spec_models if i not in [c._name for c in injected_classes]}
)
return remaining_models


def register_hook(env, module_name, spec_module, force=False):
"""
Called by Model#_register_hook once all modules are loaded.
Here we take all spec models that are not injected in existing concrete
Odoo models and we make them concrete automatically with
their _auto_init method that will create their SQL DDL structure.
"""
load_key = "_%s_loaded" % (spec_module,)

Check warning on line 143 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L143

Added line #L143 was not covered by tests
if hasattr(env.registry, load_key) and not force: # already done for registry
return
setattr(env.registry, load_key, True)

Check warning on line 146 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L145-L146

Added lines #L145 - L146 were not covered by tests

remaining_models = get_remaining_spec_models(

Check warning on line 148 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L148

Added line #L148 was not covered by tests
env.cr, env.registry, module_name, spec_module
)
for name in remaining_models:
spec_class = StackedModel._odoo_name_to_class(name, spec_module)
spec_class._module = "fiscal" # TODO use python_module ?
fields = env[spec_class._name].fields_get_keys()

Check warning on line 154 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L152-L154

Added lines #L152 - L154 were not covered by tests
rec_name = next(
filter(
lambda x: (
x.startswith(env[spec_class._name]._field_prefix)
and "_choice" not in x
),
fields,
)
)
inherit = list(spec_class._inherit) + ["spec.mixin"]
c = type(

Check warning on line 165 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L164-L165

Added lines #L164 - L165 were not covered by tests
name,
(SpecModel, spec_class),
{
"_name": name,
"_inherit": inherit,
"_original_module": "fiscal",
"_odoo_module": module_name,
"_spec_module": spec_module,
"_rec_name": rec_name,
"_module": module_name,
},
)
models.MetaModel.module_to_models[module_name] += [c]

Check warning on line 178 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L178

Added line #L178 was not covered by tests

# now we init these models properly
# a bit like odoo.modules.loading#load_module_graph would do.
c._build_model(env.registry, env.cr)

Check warning on line 182 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L182

Added line #L182 was not covered by tests

env[name]._prepare_setup()
env[name]._setup_base()
env[name]._setup_fields()
env[name]._setup_complete()

Check warning on line 187 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L184-L187

Added lines #L184 - L187 were not covered by tests

hook_key = "_%s_need_hook" % (module_name,)

Check warning on line 189 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L189

Added line #L189 was not covered by tests
if hasattr(env.registry, hook_key) and getattr(env.registry, hook_key):
env.registry.init_models(env.cr, remaining_models, {"module": module_name})
setattr(env.registry, hook_key, False)

Check warning on line 192 in spec_driven_model/hooks.py

View check run for this annotation

Codecov / codecov/patch

spec_driven_model/hooks.py#L191-L192

Added lines #L191 - L192 were not covered by tests
Loading
Loading