Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • lefilament/cgscop/cgscop_timesheet
  • hsilvant/cgscop_timesheet
2 results
Select Git revision
Show changes
Commits on Source (94)
Showing with 1245 additions and 91 deletions
# Configuration for known file extensions
[*.{css,js,json,less,md,py,rst,sass,scss,xml,yaml,yml}]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.{json,yml,yaml,rst,md}]
indent_size = 2
# Do not configure editor for libs and autogenerated content
[{*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst}]
charset = unset
end_of_line = unset
indent_size = unset
indent_style = unset
insert_final_newline = false
trim_trailing_whitespace = false
env:
browser: true
es6: true
# See https://github.com/OCA/odoo-community.org/issues/37#issuecomment-470686449
parserOptions:
ecmaVersion: 2017
overrides:
- files:
- "**/*.esm.js"
parserOptions:
sourceType: module
# Globals available in Odoo that shouldn't produce errorings
globals:
_: readonly
$: readonly
fuzzy: readonly
jQuery: readonly
moment: readonly
odoo: readonly
openerp: readonly
owl: readonly
# Styling is handled by Prettier, so we only need to enable AST rules;
# see https://github.com/OCA/maintainer-quality-tools/pull/618#issuecomment-558576890
rules:
accessor-pairs: warn
array-callback-return: warn
callback-return: warn
capitalized-comments:
- warn
- always
- ignoreConsecutiveComments: true
ignoreInlineComments: true
complexity:
- warn
- 15
constructor-super: warn
dot-notation: warn
eqeqeq: warn
global-require: warn
handle-callback-err: warn
id-blacklist: warn
id-match: warn
init-declarations: error
max-depth: warn
max-nested-callbacks: warn
max-statements-per-line: warn
no-alert: warn
no-array-constructor: warn
no-caller: warn
no-case-declarations: warn
no-class-assign: warn
no-cond-assign: error
no-const-assign: error
no-constant-condition: warn
no-control-regex: warn
no-debugger: error
no-delete-var: warn
no-div-regex: warn
no-dupe-args: error
no-dupe-class-members: error
no-dupe-keys: error
no-duplicate-case: error
no-duplicate-imports: error
no-else-return: warn
no-empty-character-class: warn
no-empty-function: error
no-empty-pattern: error
no-empty: warn
no-eq-null: error
no-eval: error
no-ex-assign: error
no-extend-native: warn
no-extra-bind: warn
no-extra-boolean-cast: warn
no-extra-label: warn
no-fallthrough: warn
no-func-assign: error
no-global-assign: error
no-implicit-coercion:
- warn
- allow: ["~"]
no-implicit-globals: warn
no-implied-eval: warn
no-inline-comments: warn
no-inner-declarations: warn
no-invalid-regexp: warn
no-irregular-whitespace: warn
no-iterator: warn
no-label-var: warn
no-labels: warn
no-lone-blocks: warn
no-lonely-if: error
no-mixed-requires: error
no-multi-str: warn
no-native-reassign: error
no-negated-condition: warn
no-negated-in-lhs: error
no-new-func: warn
no-new-object: warn
no-new-require: warn
no-new-symbol: warn
no-new-wrappers: warn
no-new: warn
no-obj-calls: warn
no-octal-escape: warn
no-octal: warn
no-param-reassign: warn
no-path-concat: warn
no-process-env: warn
no-process-exit: warn
no-proto: warn
no-prototype-builtins: warn
no-redeclare: warn
no-regex-spaces: warn
no-restricted-globals: warn
no-restricted-imports: warn
no-restricted-modules: warn
no-restricted-syntax: warn
no-return-assign: error
no-script-url: warn
no-self-assign: warn
no-self-compare: warn
no-sequences: warn
no-shadow-restricted-names: warn
no-shadow: warn
no-sparse-arrays: warn
no-sync: warn
no-this-before-super: warn
no-throw-literal: warn
no-undef-init: warn
no-undef: error
no-unmodified-loop-condition: warn
no-unneeded-ternary: error
no-unreachable: error
no-unsafe-finally: error
no-unused-expressions: error
no-unused-labels: error
no-unused-vars: error
no-use-before-define: error
no-useless-call: warn
no-useless-computed-key: warn
no-useless-concat: warn
no-useless-constructor: warn
no-useless-escape: warn
no-useless-rename: warn
no-void: warn
no-with: warn
operator-assignment: [error, always]
prefer-const: warn
radix: warn
require-yield: warn
sort-imports: warn
spaced-comment: [error, always]
strict: [error, function]
use-isnan: error
valid-jsdoc:
- warn
- prefer:
arg: param
argument: param
augments: extends
constructor: class
exception: throws
func: function
method: function
prop: property
return: returns
virtual: abstract
yield: yields
preferType:
array: Array
bool: Boolean
boolean: Boolean
number: Number
object: Object
str: String
string: String
requireParamDescription: false
requireReturn: false
requireReturnDescription: false
requireReturnType: false
valid-typeof: warn
yoda: warn
[flake8]
max-line-length = 88
max-complexity = 16
# B = bugbear
# B9 = bugbear opinionated (incl line length)
select = C,E,F,W,B,B9
# E203: whitespace before ':' (black behaviour)
# E501: flake8 line length (covered by bugbear B950)
# W503: line break before binary operator (black behaviour)
ignore = E203,E501,W503
per-file-ignores=
__init__.py:F401
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
/.venv
/.pytest_cache
# C extensions
*.so
# Distribution / packaging
.Python
env/
bin/
build/
develop-eggs/
dist/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
*.eggs
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml
# Translations
*.mo
# Pycharm
.idea
# Eclipse
.settings
# Visual Studio cache/options directory
.vs/
.vscode
# OSX Files
.DS_Store
# Django stuff:
*.log
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
# Rope
.ropeproject
# Sphinx documentation
docs/_build/
# Backup files
*~
*.swp
# OCA rules
!static/lib/
[settings]
; see https://github.com/psf/black
multi_line_output=3
include_trailing_comma=True
force_grid_wrap=0
combine_as_imports=True
use_parentheses=True
line_length=88
known_odoo=odoo
known_odoo_addons=odoo.addons
sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER
default_section=THIRDPARTY
ensure_newline_before_comments = True
exclude: |
(?x)
# NOT INSTALLABLE ADDONS
# END NOT INSTALLABLE ADDONS
# Files and folders generated by bots, to avoid loops
^setup/|/static/description/index\.html$|
# We don't want to mess with tool-generated files
.svg$|/tests/([^/]+/)?cassettes/|^.copier-answers.yml$|^.github/|
# Maybe reactivate this when all README files include prettier ignore tags?
^README\.md$|
# Library files can have extraneous formatting (even minimized)
/static/(src/)?lib/|
# Repos using Sphinx to generate docs don't need prettying
^docs/_templates/.*\.html$|
# You don't usually want a bot to modify your legal texts
(LICENSE.*|COPYING.*)
default_language_version:
python: python3
node: "14.13.0"
repos:
- repo: local
hooks:
# These files are most likely copier diff rejection junks; if found,
# review them manually, fix the problem (if needed) and remove them
- id: forbidden-files
name: forbidden files
entry: found forbidden files; remove them
language: fail
files: "\\.rej$"
- id: en-po-files
name: en.po files cannot exist
entry: found a en.po file
language: fail
files: '[a-zA-Z0-9_]*/i18n/en\.po$'
- repo: https://github.com/oca/maintainer-tools
rev: ab1d7f6
hooks:
# update the NOT INSTALLABLE ADDONS section above
- id: oca-update-pre-commit-excluded-addons
- id: oca-fix-manifest-website
args: ["https://le-filament.com"]
- repo: https://github.com/myint/autoflake
rev: v1.4
hooks:
- id: autoflake
args:
- --expand-star-imports
- --ignore-init-module-imports
- --in-place
- --remove-all-unused-imports
- --remove-duplicate-keys
- --remove-unused-variables
- repo: https://github.com/psf/black
rev: 22.3.0
hooks:
- id: black
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.1.2
hooks:
- id: prettier
name: prettier (with plugin-xml)
additional_dependencies:
- "prettier@2.1.2"
- "@prettier/plugin-xml@0.12.0"
args:
- --plugin=@prettier/plugin-xml
files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v7.8.1
hooks:
- id: eslint
verbose: true
args:
- --color
- --fix
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
# exclude autogenerated files
exclude: /README\.rst$|\.pot?$
- id: end-of-file-fixer
# exclude autogenerated files
exclude: /README\.rst$|\.pot?$
- id: debug-statements
- id: fix-encoding-pragma
args: ["--remove"]
- id: check-case-conflict
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-merge-conflict
# exclude files where underlines are not distinguishable from merge conflicts
exclude: /README\.rst$|^docs/.*\.rst$
- id: check-symlinks
- id: check-xml
- id: mixed-line-ending
args: ["--fix=lf"]
- repo: https://github.com/asottile/pyupgrade
rev: v2.7.2
hooks:
- id: pyupgrade
args: ["--keep-percent-format"]
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
name: isort except __init__.py
args:
- --settings=.
exclude: /__init__\.py$
- repo: https://github.com/PyCQA/flake8
rev: 3.8.3
hooks:
- id: flake8
name: flake8
additional_dependencies: ["flake8-bugbear==20.1.4"]
- repo: https://github.com/OCA/pylint-odoo
rev: 7.0.2
hooks:
- id: pylint_odoo
name: pylint with optional checks
args:
- --rcfile=.pylintrc
- --exit-zero
verbose: true
- id: pylint_odoo
args:
- --rcfile=.pylintrc-mandatory
# Defaults for all prettier-supported languages.
# Prettier will complete this with settings from .editorconfig file.
bracketSpacing: false
printWidth: 88
proseWrap: always
semi: true
trailingComma: "es5"
xmlWhitespaceSensitivity: "strict"
[MASTER]
load-plugins=pylint_odoo
score=n
[ODOOLINT]
readme_template_url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst"
manifest_required_authors=Le Filament
manifest_required_keys=license
manifest_deprecated_keys=description,active
license_allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3
valid_odoo_versions=14.0
[MESSAGES CONTROL]
disable=all
# This .pylintrc contains optional AND mandatory checks and is meant to be
# loaded in an IDE to have it check everything, in the hope this will make
# optional checks more visible to contributors who otherwise never look at a
# green travis to see optional checks that failed.
# .pylintrc-mandatory containing only mandatory checks is used the pre-commit
# config as a blocking check.
enable=anomalous-backslash-in-string,
api-one-deprecated,
api-one-multi-together,
assignment-from-none,
attribute-deprecated,
class-camelcase,
dangerous-default-value,
dangerous-view-replace-wo-priority,
development-status-allowed,
duplicate-id-csv,
duplicate-key,
duplicate-xml-fields,
duplicate-xml-record-id,
eval-referenced,
eval-used,
incoherent-interpreter-exec-perm,
license-allowed,
manifest-author-string,
manifest-deprecated-key,
manifest-required-author,
manifest-required-key,
manifest-version-format,
method-compute,
method-inverse,
method-required-super,
method-search,
openerp-exception-warning,
pointless-statement,
pointless-string-statement,
print-used,
redundant-keyword-arg,
redundant-modulename-xml,
reimported,
relative-import,
return-in-init,
rst-syntax-error,
sql-injection,
too-few-format-args,
translation-field,
translation-required,
unreachable,
use-vim-comment,
wrong-tabs-instead-of-spaces,
xml-syntax-error,
# messages that do not cause the lint step to fail
consider-merging-classes-inherited,
create-user-wo-reset-password,
dangerous-filter-wo-user,
deprecated-module,
file-not-used,
invalid-commit,
missing-manifest-dependency,
missing-newline-extrafiles,
no-utf8-coding-comment,
odoo-addons-relative-import,
old-api7-method-defined,
redefined-builtin,
too-complex,
unnecessary-utf8-coding-comment
[REPORTS]
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
output-format=colorized
reports=no
[MASTER]
load-plugins=pylint_odoo
score=n
[ODOOLINT]
readme_template_url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst"
manifest_required_authors=Le Filament
manifest_required_keys=license
manifest_deprecated_keys=description,active
license_allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3
valid_odoo_versions=14.0
[MESSAGES CONTROL]
disable=all
enable=anomalous-backslash-in-string,
api-one-deprecated,
api-one-multi-together,
assignment-from-none,
attribute-deprecated,
class-camelcase,
dangerous-default-value,
dangerous-view-replace-wo-priority,
development-status-allowed,
duplicate-id-csv,
duplicate-key,
duplicate-xml-fields,
duplicate-xml-record-id,
eval-referenced,
eval-used,
incoherent-interpreter-exec-perm,
license-allowed,
manifest-author-string,
manifest-deprecated-key,
manifest-required-author,
manifest-required-key,
manifest-version-format,
method-compute,
method-inverse,
method-required-super,
method-search,
openerp-exception-warning,
pointless-statement,
pointless-string-statement,
print-used,
redundant-keyword-arg,
redundant-modulename-xml,
reimported,
relative-import,
return-in-init,
rst-syntax-error,
sql-injection,
too-few-format-args,
translation-field,
translation-required,
unreachable,
use-vim-comment,
wrong-tabs-instead-of-spaces,
xml-syntax-error
[REPORTS]
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
output-format=colorized
reports=no
......@@ -14,7 +14,6 @@ Il ajoute les éléments suivants :
* menu pour configurer les projets (cf Codes Activité UR) et les vues associées
* table de configuration des activités CG
* table de configuration des dispositifs
*
Credits
......
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models
from . import wizard
from . import models, wizard
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "CG SCOP - Feuille de temps",
"summary": "CG SCOP - Feuille de temps",
"version": "12.0.1.0.1",
"development_status": "Beta",
"version": "14.0.1.0.0",
"author": "Le Filament",
"maintainers": ["remi-filament"],
"license": "AGPL-3",
"application": False,
"installable": True,
"depends": [
"hr_timesheet",
"analytic",
"account",
"project",
"cgscop_partner",
"cgscop_fullcalendar",
],
"data": [
"security/ir.model.access.csv",
"security/security_rules.xml",
"wizard/cgscop_timesheet_print_wizard.xml",
"views/assets.xml",
"views/cgscop_timesheet_code.xml",
"views/cgscop_timesheet_sheet.xml",
"views/hr_timesheet.xml",
"views/hr_timesheet_cgscop.xml",
"views/res_company.xml",
"views/res_partner.xml",
"views/ur_financial_system.xml",
"wizard/print_timesheet.xml",
"wizard/report_hr_timesheet.xml",
"datas/cgscop.timesheet.code.csv",
]
"views/ur_month_timesheet.xml",
"views/ur_regional_convention.xml",
"report/report_hr_timesheet.xml",
"report/report_hr_timesheet_act.xml",
"datas/cgscop_timesheet_code_data.xml",
],
"qweb": [
"static/src/xml/*.xml",
],
"installable": True,
"auto_install": False,
}
id,name
code_cg_activite_0,Développement - Prospection, prescripteur, promotion
code_cg_activite_1,Développement - Innovation, incubateurs
code_cg_activite_2,Développement - Nouveaux projets Création
code_cg_activite_3,Développement – Nouveaux projets RES
code_cg_activite_4,Accompagnement - Suivi syndical Scop en difficultés
code_cg_activite_5,Accompagnement - Suivi syndical, missions spécifiques de suivi des adhérents
code_cg_activite_6,Accompagnement - Prestations facturées
code_cg_activite_7,Accompagnement - Animation coopérative et intercoopérative (réseau)
code_cg_activite_8,Accompagnement - Assistance dossiers financiers
code_cg_activite_9,Accompagnement - Alter'Venture
code_cg_activite_10,Formation des coopératives - Ingénierie
code_cg_activite_11,Formation des coopératives - Préparation et gestion administrative
code_cg_activite_12,Formation des coopératives - Animation
code_cg_activite_13,Révision
code_cg_activite_14,Vie du mouvement - Réunions équipe technique (régional et national)
code_cg_activite_15,Vie du mouvement - (CA+ AG)
code_cg_activite_16,Vie du mouvement - Gestion interne
code_cg_activite_17,Communication
\ No newline at end of file
<?xml version="1.0" ?>
<odoo>
<data noupdate="1">
<record id="code_cg_activite_0" model="cgscop.timesheet.code">
<field name="name">Développement - Prospection</field>
</record>
<record id="code_cg_activite_1" model="cgscop.timesheet.code">
<field name="name">Développement - Innovation</field>
</record>
<record id="code_cg_activite_2" model="cgscop.timesheet.code">
<field name="name">Développement - Nouveaux projets Création</field>
</record>
<record id="code_cg_activite_3" model="cgscop.timesheet.code">
<field name="name">Développement – Nouveaux projets RES</field>
</record>
<record id="code_cg_activite_4" model="cgscop.timesheet.code">
<field
name="name"
>Accompagnement - Suivi syndical Scop en difficultés</field>
</record>
<record id="code_cg_activite_5" model="cgscop.timesheet.code">
<field name="name">Accompagnement - Suivi syndical</field>
</record>
<record id="code_cg_activite_6" model="cgscop.timesheet.code">
<field name="name">Accompagnement - Prestations facturées</field>
</record>
<record id="code_cg_activite_7" model="cgscop.timesheet.code">
<field
name="name"
>Accompagnement - Animation coopérative et intercoopérative (réseau)</field>
</record>
<record id="code_cg_activite_8" model="cgscop.timesheet.code">
<field name="name">Accompagnement - Assistance dossiers financiers</field>
</record>
<record id="code_cg_activite_9" model="cgscop.timesheet.code">
<field name="name">Accompagnement - Alter'Venture</field>
</record>
<record id="code_cg_activite_10" model="cgscop.timesheet.code">
<field name="name">Formation des coopératives - Ingénierie</field>
</record>
<record id="code_cg_activite_11" model="cgscop.timesheet.code">
<field
name="name"
>Formation des coopératives - Préparation et gestion administrative</field>
</record>
<record id="code_cg_activite_12" model="cgscop.timesheet.code">
<field name="name">Formation des coopératives - Animation</field>
</record>
<record id="code_cg_activite_13" model="cgscop.timesheet.code">
<field name="name">Révision</field>
</record>
<record id="code_cg_activite_14" model="cgscop.timesheet.code">
<field
name="name"
>Vie du mouvement - Réunions équipe technique (régional et national)</field>
</record>
<record id="code_cg_activite_15" model="cgscop.timesheet.code">
<field name="name">Vie du mouvement - (CA+ AG)</field>
</record>
<record id="code_cg_activite_16" model="cgscop.timesheet.code">
<field name="name">Vie du mouvement - Gestion interne</field>
</record>
<record id="code_cg_activite_17" model="cgscop.timesheet.code">
<field name="name">Communication</field>
</record>
</data>
</odoo>
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * cgscop_timesheet
# * hr_timesheet
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-12-09 16:01+0000\n"
"PO-Revision-Date: 2019-12-09 16:01+0000\n"
"POT-Creation-Date: 2022-02-28 18:07+0000\n"
"PO-Revision-Date: 2022-02-28 18:07+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
......@@ -15,30 +15,6 @@ msgstr ""
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: hr_timesheet
#: model:ir.actions.act_window,name:hr_timesheet.timesheet_action_all
#: model:ir.ui.menu,name:hr_timesheet.timesheet_menu_activity_all
msgid "All Timesheets"
msgstr "Toutes les lignes de temps"
#. module: hr_timesheet
#: model:ir.actions.act_window,name:hr_timesheet.act_hr_timesheet_line
#: model:ir.ui.menu,name:hr_timesheet.timesheet_menu_activity_mine
#: model_terms:ir.ui.view,arch_db:hr_timesheet.hr_timesheet_line_search
msgid "My Timesheets"
msgstr "Mes lignes de temps"
#. module: hr_timesheet
#: model:ir.actions.act_window,name:hr_timesheet.project_task_action_view_timesheet
#: model:ir.actions.report,name:hr_timesheet.timesheet_report
msgid "Timesheet Entries"
msgstr "Lignes de temps"
#. module: hr_timesheet
#: model_terms:ir.ui.view,arch_db:hr_timesheet.hr_timesheet_line_search
msgid "Timesheet by Date"
msgstr "Lignes de temps par date"
#. module: hr_timesheet
#: model:ir.actions.act_window,name:hr_timesheet.timesheet_action_from_employee
#: model:ir.model.fields,field_description:hr_timesheet.field_project_task__timesheet_ids
......@@ -51,16 +27,29 @@ msgstr "Lignes de temps par date"
msgid "Timesheets"
msgstr "Lignes de temps"
#. module: hr_timesheet
#: model:ir.model,name:hr_timesheet.model_project_project
#: model:ir.model.fields,field_description:hr_timesheet.field_account_analytic_line__project_id
#: model_terms:ir.ui.view,arch_db:hr_timesheet.hr_timesheet_line_search
msgid "Project"
msgstr "Code activité UR"
#. module: hr_timesheet
#: model:ir.actions.act_window,name:hr_timesheet.timesheet_action_report_by_project
#: model:ir.ui.menu,name:hr_timesheet.timesheet_menu_report_timesheet_by_project
msgid "By Project"
msgstr "Par Code activité UR"
#. module: hr_timesheet
#: model:ir.ui.menu,name:hr_timesheet.menu_hr_time_tracking
#: model_terms:ir.ui.view,arch_db:hr_timesheet.hr_timesheet_line_search
#: model_terms:ir.ui.view,arch_db:hr_timesheet.view_hr_timesheet_line_graph
#: model_terms:ir.ui.view,arch_db:hr_timesheet.view_hr_timesheet_line_pivot
msgid "Timesheet"
msgstr "Lignes de Temps"
#. module: hr_timesheet
#: model:ir.actions.act_window,name:hr_timesheet.act_hr_timesheet_line
#: model:ir.ui.menu,name:hr_timesheet.timesheet_menu_activity_mine
#: model_terms:ir.ui.view,arch_db:hr_timesheet.hr_timesheet_line_search
msgid "My Timesheets"
msgstr "Mes lignes de temps"
#. module: hr_timesheet
#: model:ir.actions.act_window,name:hr_timesheet.timesheet_action_all
#: model:ir.ui.menu,name:hr_timesheet.timesheet_menu_activity_all
msgid "All Timesheets"
msgstr "Toutes les lignes de temps"
......@@ -2,7 +2,11 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import cgscop_timesheet_code
from . import cgscop_timesheet_sheet
from . import hr_timesheet
from . import project
from . import res_company
from . import res_partner
from . import ur_financial_system
from . import ur_month_timesheet
from . import ur_regional_convention
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields
from odoo import fields, models
class ScopTimesheetCode(models.Model):
_name = "cgscop.timesheet.code"
_description = "Code activité National"
_order = 'name'
_order = "name"
name = fields.Char('Nom')
name = fields.Char("Nom")
domain = fields.Selection(
[
("A", "Accompagnement"),
("D", "Développement"),
("F", "Formation"),
("R", "Révision"),
("Z", "Autre"),
],
string="Domaine",
)
# © 2020 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, api, fields, models
from odoo.exceptions import UserError, ValidationError
class ScopHrTimesheetSheet(models.Model):
_name = "cgscop.timesheet.sheet"
_inherit = ["mail.thread", "mail.activity.mixin"]
_description = "Timesheet Report"
_order = "create_date desc, validation_date desc, id desc"
def _default_ur(self):
return self.env["res.company"]._ur_default_get()
name = fields.Char("Nom", required=True)
timesheet_line_ids = fields.One2many(
comodel_name="account.analytic.line",
inverse_name="sheet_id",
string="Lignes de temps",
states={"valid": [("readonly", True)]},
copy=False,
)
state = fields.Selection(
[("draft", "Brouillon"), ("submit", "Soumis"), ("valid", "Validé")],
string="Statut",
index=True,
tracking=True,
copy=False,
default="draft",
required=True,
)
employee_id = fields.Many2one(
comodel_name="hr.employee",
string="Employé",
required=True,
readonly=True,
states={"draft": [("readonly", False)]},
default=lambda self: self.env["hr.employee"].search(
[("user_id", "=", self.env.uid)], limit=1
),
)
total_hour = fields.Float(string="Total", compute="_compute_hour", store=True)
company_id = fields.Many2one(
comodel_name="res.company",
string="Company",
readonly=True,
states={"draft": [("readonly", False)]},
default=lambda self: self.env.company,
)
validation_date = fields.Date("Date de validation")
submit_date = fields.Date("Soumis le")
ur_id = fields.Many2one(
"union.regionale",
string="Union Régionale",
index=True,
ondelete="restrict",
default=_default_ur,
)
can_edit = fields.Boolean("Can Reset", compute="_compute_can_reset")
# ------------------------------------------------------
# Compute Functions
# ------------------------------------------------------
@api.depends("timesheet_line_ids", "timesheet_line_ids.unit_amount")
def _compute_hour(self):
for sheet in self:
sheet.total_hour = sum(sheet.timesheet_line_ids.mapped("unit_amount"))
def _compute_can_reset(self):
is_timesheet_user = self.user_has_groups("hr_timesheet.group_timesheet_manager")
for sheet in self:
if sheet.state == "draft" or is_timesheet_user:
sheet.can_edit = True
else:
sheet.can_edit = False
# ------------------------------------------------------
# Constain Functions
# ------------------------------------------------------
@api.constrains("timesheet_line_ids", "employee_id")
def _check_employee(self):
for sheet in self:
employee_ids = sheet.timesheet_line_ids.mapped("employee_id")
if len(employee_ids) > 1 or (
len(employee_ids) == 1 and employee_ids != sheet.employee_id
):
raise ValidationError(
_(
"Vous ne pouvez pas ajouter les lignes"
" de temps de plusieurs employés."
)
)
# ------------------------------------------------------
# Override ORM
# ------------------------------------------------------
def unlink(self):
for timesheet in self:
if timesheet.state in ["submit", "valid"]:
raise UserError(
_(
"Vous ne pouvez pas supprimer une "
"feuille de temps soumise ou validée"
)
)
super(ScopHrTimesheetSheet, self).unlink()
# ------------------------------------------------------
# Action button
# ------------------------------------------------------
def action_submit_timesheet(self):
self.write({"state": "submit", "submit_date": fields.Date.today()})
def approve_timesheet_sheets(self):
self.write({"state": "valid", "validation_date": fields.Date.today()})
def reset_timesheet_sheets(self):
self.write({"state": "draft", "submit_date": False, "validation_date": False})
def print_timesheet(self):
return self.env.ref(
"cgscop_timesheet.cgscop_timesheet_sheet_report"
).report_action(self)
# ------------------------------------------------------
# Retourne les lignes de la Fdt avec les totaux par projet
# ------------------------------------------------------
def _to_duration(self, infloat):
return "{:02.0f}:{:02.0f}".format(*divmod(infloat * 60, 60))
def _get_timesheet_line_act(self):
for sheet in self:
lines = sheet.timesheet_line_ids.sorted(
key=lambda b: (b.project_id.name, b.date)
)
rows = []
last_project = False
tot_project = 0
for line in lines:
# On insère un total intermédiaire
if last_project != line.project_id.name and tot_project != 0:
rows.append(
{
"total": 1,
"name": False,
"partner": False,
"project": False,
"date": False,
"ur_financial_system": "Total "
+ last_project
+ " : "
+ self._to_duration(tot_project),
"unit_amount": False,
}
)
tot_project = 0
# On insère la ligne lue
rows.append(
{
"total": 0,
"name": line.name,
"partner": line.partner_id.name,
"project": line.project_id.name,
"date": line.date,
"ur_financial_system": line.ur_financial_system_id.name,
"unit_amount": self._to_duration(line.unit_amount),
}
)
last_project = line.project_id.name
tot_project = tot_project + line.unit_amount
# On insère le dernier total
rows.append(
{
"total": 1,
"name": False,
"partner": False,
"project": False,
"date": False,
"ur_financial_system": "Total "
+ last_project
+ " : "
+ self._to_duration(tot_project),
"unit_amount": False,
}
)
return rows
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api
from datetime import datetime, time
from odoo import _, api, fields, models
from odoo.exceptions import UserError, ValidationError
class ScopHrTimesheet(models.Model):
_inherit = "account.analytic.line"
def _default_ur(self):
return self.env['res.company']._ur_default_get()
return self.env["res.company"]._ur_default_get()
# Inherited fields
name = fields.Char(required=False)
partner_id = fields.Many2one(required=True)
# New fields
cgscop_timesheet_code_id = fields.Many2one(
related='project_id.cgscop_timesheet_code_id',
string='Code Activité National',
store=True)
related="project_id.cgscop_timesheet_code_id",
string="Code Activité National",
store=True,
)
ur_financial_system_id = fields.Many2one(
comodel_name='ur.financial.system',
string='Dispositif Financier')
comodel_name="ur.financial.system", string="Dispositif Financier"
)
ur_regional_convention_id = fields.Many2one(
comodel_name="ur.regional.convention", string="Convention Régionale"
)
ur_id = fields.Many2one(
'union.regionale',
string='Union Régionale',
"union.regionale",
string="Union Régionale",
index=True,
ondelete="restrict",
default=_default_ur,
)
sheet_id = fields.Many2one(
comodel_name="cgscop.timesheet.sheet",
string="Feuille de temps",
readonly=True,
copy=False,
)
state = fields.Selection(
[
("to_report", "A rapporter"),
("draft", "Brouillon"),
("submit", "Soumis"),
("valid", "Validé"),
],
compute="_compute_state",
string="Statut",
copy=False,
index=True,
on_delete='restrict',
default=_default_ur)
readonly=True,
store=True,
)
ur_financial_system_nb = fields.Integer(
string="Nb Dispositifs Financiers", compute="_compute_ur_system_nb"
)
ur_regional_convention_nb = fields.Integer(
string="Nb conventions régionales", compute="_compute_ur_system_nb"
)
is_present = fields.Boolean("Présentiel")
location = fields.Selection(
[
("R", "Rendez-vous"),
("D", "Déplacement"),
("B", "Bureau"),
],
string="Lieu",
)
justificatifs = fields.Char(string="Justificatifs", required=False)
is_overtime = fields.Boolean(
string="Heures supplémentaires",
default=False,
)
is_overtime_allowed = fields.Boolean(
string="Heures supplémentaires autorisées",
compute="_compute_overtime_allowed",
)
travel_time = fields.Float(
string="Temps déplacement",
)
is_travel_time_allowed = fields.Boolean(
string="Temps de déplacement autorisé",
compute="_compute_travel_time_allowed",
)
calendar_l1 = fields.Char(
string="Ligne 1 calendrier",
compute="_compute_calendar_l1",
)
calendar_l2 = fields.Char(
string="Ligne 2 calendrier",
compute="_compute_calendar_l2",
)
# ------------------------------------------------------
# Compute Functions
# ------------------------------------------------------
@api.depends("ur_id")
def _compute_overtime_allowed(self):
for rec in self:
rec.is_overtime_allowed = self.env.company.overtime_working
@api.depends("ur_id")
def _compute_travel_time_allowed(self):
for rec in self:
rec.is_travel_time_allowed = self.env.company.use_travel_time
@api.depends("ur_id")
def _compute_ur_system_nb(self):
for timesheet in self:
# Calcul nombre de dispositifs financiers
financial_system = timesheet.env["ur.financial.system"].search(
[("ur_id", "=", timesheet.ur_id.id)]
)
timesheet.ur_financial_system_nb = len(financial_system)
# Calcul nombre de conventions
regional_convention = timesheet.env["ur.regional.convention"].search(
[("ur_id", "=", timesheet.ur_id.id)]
)
timesheet.ur_regional_convention_nb = len(regional_convention)
@api.depends("sheet_id", "sheet_id.state")
def _compute_state(self):
for timesheet in self:
if not timesheet.sheet_id:
timesheet.state = "to_report"
else:
timesheet.state = timesheet.sheet_id.state
@api.depends("project_id", "partner_id")
def _compute_calendar_l1(self):
for ts in self:
ts.calendar_l1 = ""
if ts.project_id:
ts.calendar_l1 += ts.project_id.name + ", "
if ts.partner_id:
ts.calendar_l1 += ts.partner_id.name
@api.depends("unit_amount")
def _compute_calendar_l2(self):
for ts in self:
ts.calendar_l2 = "Durée : " + str(ts.unit_amount) + " heure(s)"
# ------------------------------------------------------
# Override le _rec_name
# ------------------------------------------------------
@api.depends("project_id", "partner_id")
def name_get(self):
result = []
for ts in self:
name = ts.calendar_l1
result.append((ts.id, name))
return result
# ------------------------------------------------------
# OnChange Functions
# ------------------------------------------------------
@api.onchange('project_id')
@api.onchange("project_id")
def onchange_project_id(self):
self.partner_id = self.project_id.partner_id
@api.onchange("partner_id")
def onchange_partner_id(self):
# affiche le Dispositif Financier par défaut sur la LdT
# si il n'y a pas de date limite du dispositif
# ou si la date de la Ldt est inférieure à la date limite du dispositif
if (
not self.partner_id.ur_financial_system_date
or self.date <= self.partner_id.ur_financial_system_date
):
self.ur_financial_system_id = self.partner_id.ur_financial_system_id
# affiche la Convention par défaut sur la LdT
# si il n'y a pas de date limite de la convention
# ou si la date de la LdT est inférieure à la date limite de la convention
if (
not self.partner_id.ur_regional_convention_date
or self.date <= self.partner_id.ur_regional_convention_date
):
self.ur_regional_convention_id = self.partner_id.ur_regional_convention_id
# ------------------------------------------------------
# Contrains
# ------------------------------------------------------
@api.constrains("unit_amount", "date")
def _check_hours(self):
for record in self:
if record.project_id:
lines = self.search(
[
("date", "=", record.date),
("employee_id", "=", record.employee_id.id),
]
)
total = sum(lines.mapped("unit_amount"))
if (
not self.env.company.day_working
and total > self.env.company.day_duration
):
raise ValidationError(
_(
"Vous ne pouvez imputer plus de %sh sur la même journée.\n"
"Journée du %s"
)
% (
self.env.company.day_duration,
record.date.strftime("%d/%m/%Y"),
)
)
@api.constrains("date")
def _check_weekday(self):
if self.env.company.weekend_working:
return
for line in self:
dt = datetime.combine(line.date, time(12, 00))
holiday = self.env["resource.calendar.leaves"].search(
[
"|",
("company_id", "=", False),
("company_id", "=", self.env.company.id),
("date_from", "<=", dt),
("date_to", ">=", dt),
("resource_id", "=", False),
]
)
if not line.holiday_id and (line.date.weekday() in (5, 6) or holiday):
raise ValidationError(
_(
"Vous ne pouvez imputer du temps sur un weekend "
"ou un jour férié."
)
)
# ------------------------------------------------------
# Override ORM
# ------------------------------------------------------
def unlink(self):
for timesheet in self:
if timesheet.state in ["submit", "valid"]:
raise UserError(
_(
"Vous ne pouvez pas supprimer une "
"ligne de temps soumise ou validée"
)
)
super(ScopHrTimesheet, self).unlink()
# ------------------------------------------------------
# Actions
# ------------------------------------------------------
def action_submit_timesheet_lines(self):
"""
Crée une feuille de temps avec les lignes sélectionnées
"""
if any(time.state != "to_report" or time.sheet_id for time in self):
raise UserError(_("Vous ne pouvez pas insérer 2 fois la même ligne !"))
if len(self.mapped("employee_id")) != 1:
raise UserError(
_(
"Il ne peut y avoir plusieurs employés dans une "
"même feuille de temps."
)
)
return {
"name": "New Expense Report",
"type": "ir.actions.act_window",
"view_mode": "form",
"res_model": "cgscop.timesheet.sheet",
"target": "current",
"context": {
"default_timesheet_line_ids": self.ids,
"default_employee_id": self[0].employee_id.id,
"default_name": self[0].name if len(self) == 1 else "",
},
}
# ------------------------------------------------------
# Modification du context pour cacher les colonnes
# ------------------------------------------------------
@api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
custom_context = self.env.context.copy()
current_ur_id = self.env.context['current_ur_id']
nbfs = self.env["ur.financial.system"].search([("ur_id", "=", current_ur_id)])
if len(nbfs) == 0:
custom_context['hide_financial_system'] = True
nbrc = self.env["ur.regional.convention"].search([("ur_id", "=", current_ur_id)])
if len(nbrc) == 0:
custom_context['hide_regional_convention'] = True
overtime_allowed = self.env.company.overtime_working
if not overtime_allowed:
custom_context['hide_overtime'] = True
travel_time_allowed = self.env.company.use_travel_time
if not travel_time_allowed:
custom_context['hide_travel_time'] = True
res = super(ScopHrTimesheet, self.with_context(custom_context)).fields_view_get(
view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)
return res
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields
from odoo import api, fields, models
class ScopProjectTimesheet(models.Model):
_inherit = "project.project"
def _default_ur(self):
return self.env['res.company']._ur_default_get()
return self.env["res.company"]._ur_default_get()
cgscop_timesheet_code_id = fields.Many2one(
comodel_name='cgscop.timesheet.code',
string='Code Activité National')
comodel_name="cgscop.timesheet.code", string="Code Activité National"
)
privacy_visibility = fields.Selection(default="employees")
ur_id = fields.Many2one(
'union.regionale',
string='Union Régionale',
"union.regionale",
string="Union Régionale",
index=True,
on_delete='restrict',
default=_default_ur)
ondelete="restrict",
default=_default_ur,
)
creation_invoiced = fields.Boolean(
string="Facturé au titre de la création",
)
@api.onchange("name")
def onchange_name(self):
analytic = self.analytic_account_id
if analytic and analytic.ensure_one():
self.analytic_account_id.sudo().write(
{
"name": self.name,
}
)