mirror of
https://gitlab.com/flectra-community/mis-builder.git
synced 2024-11-16 11:12:07 +00:00
Automatic Update form OCA2FC Migrator
This commit is contained in:
commit
e18530712c
146
.gitlab-ci.yml
Normal file
146
.gitlab-ci.yml
Normal file
@ -0,0 +1,146 @@
|
||||
image: ubuntu:jammy
|
||||
|
||||
stages:
|
||||
- testall
|
||||
- testsingle
|
||||
|
||||
variables:
|
||||
POSTGRES_DB: postgres
|
||||
POSTGRES_USER: flectra
|
||||
POSTGRES_PASSWORD: flectra
|
||||
POSTGRES_HOST: postgres
|
||||
POSTGRES_PORT: "5432"
|
||||
|
||||
services:
|
||||
- name: postgres:14-bullseye
|
||||
alias: psql
|
||||
|
||||
|
||||
test_all_modules:
|
||||
stage: testall
|
||||
image:
|
||||
name: registry.gitlab.com/jamotion/flectra/ubuntudev:2-latest
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
script:
|
||||
- apt-get install -y p7zip-full
|
||||
- su - flectra -c "mkdir ~/others"
|
||||
- sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && dpkg-reconfigure --frontend=noninteractive locales && update-locale LANG=en_US.UTF-8
|
||||
- mkdir ${CI_PROJECT_DIR}/ci_data
|
||||
- wget -O ${CI_PROJECT_DIR}/ci_data/test_base.zip https://gitlab.com/flectra-community/devops/oca2fc/raw/master/ci_data/test_base.zip
|
||||
- 7z x -o ${CI_PROJECT_DIR}/ci_data/ ${CI_PROJECT_DIR}/ci_data/test_base.zip
|
||||
- export PGPASSWORD="flectra"
|
||||
- createdb -h psql -U flectra -O flectra -T template1 test_all
|
||||
- psql -h psql -U flectra -d test_all -f ${CI_PROJECT_DIR}/ci_data/dump.sql
|
||||
- su - flectra -c "mkdir -p ~/.local/share/filestore"
|
||||
- mv ${CI_PROJECT_DIR}/ci_data/filestore /opt/flectra/.local/share/filestore/test_all
|
||||
- chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_all
|
||||
- su - flectra -c "/opt/flectra/flectra-bin
|
||||
--addons-path ${CI_PROJECT_DIR}
|
||||
--db_host psql
|
||||
--db_port 5432
|
||||
--db_user flectra
|
||||
--db_password flectra
|
||||
--database test_all
|
||||
--test-enable
|
||||
--init mis_builder_budget,mis_builder_demo,mis_builder
|
||||
--stop-after-init
|
||||
--log-level error
|
||||
--log-handler flectra.addons.mis_builder_budget:TEST
|
||||
--log-handler flectra.addons.mis_builder_demo:TEST
|
||||
--log-handler flectra.addons.mis_builder:TEST
|
||||
"
|
||||
|
||||
|
||||
test_module_mis_builder_budget:
|
||||
stage: testsingle
|
||||
when: on_failure
|
||||
image:
|
||||
name: registry.gitlab.com/jamotion/flectra/ubuntudev:2-latest
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
script:
|
||||
- apt-get install -y p7zip-full
|
||||
- su - flectra -c "mkdir ~/others"
|
||||
- sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && dpkg-reconfigure --frontend=noninteractive locales && update-locale LANG=en_US.UTF-8
|
||||
- mkdir ${CI_PROJECT_DIR}/ci_data
|
||||
- wget -O ${CI_PROJECT_DIR}/ci_data/test_base.zip https://gitlab.com/flectra-community/devops/oca2fc/raw/master/ci_data/test_base.zip
|
||||
- 7z x -o ${CI_PROJECT_DIR}/ci_data/ ${CI_PROJECT_DIR}/ci_data/test_base.zip
|
||||
- export PGPASSWORD="flectra"
|
||||
- createdb -h psql -U flectra -O flectra -T template1 test_mis_builder_budget
|
||||
- psql -h psql -U flectra -d test_mis_builder_budget -f ${CI_PROJECT_DIR}/ci_data/dump.sql
|
||||
- su - flectra -c "mkdir -p ~/.local/share/filestore"
|
||||
- mv ${CI_PROJECT_DIR}/ci_data/filestore /opt/flectra/.local/share/filestore/test_mis_builder_budget
|
||||
- chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_mis_builder_budget
|
||||
- su - flectra -c "/opt/flectra/flectra-bin
|
||||
--addons-path ${CI_PROJECT_DIR}
|
||||
--db_host psql
|
||||
--db_port 5432
|
||||
--db_user flectra
|
||||
--db_password flectra
|
||||
--database test_mis_builder_budget
|
||||
--test-enable -i mis_builder_budget
|
||||
--stop-after-init
|
||||
--log-level error
|
||||
--log-handler flectra.addons.mis_builder_budget:TEST"
|
||||
|
||||
test_module_mis_builder_demo:
|
||||
stage: testsingle
|
||||
when: on_failure
|
||||
image:
|
||||
name: registry.gitlab.com/jamotion/flectra/ubuntudev:2-latest
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
script:
|
||||
- apt-get install -y p7zip-full
|
||||
- su - flectra -c "mkdir ~/others"
|
||||
- sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && dpkg-reconfigure --frontend=noninteractive locales && update-locale LANG=en_US.UTF-8
|
||||
- mkdir ${CI_PROJECT_DIR}/ci_data
|
||||
- wget -O ${CI_PROJECT_DIR}/ci_data/test_base.zip https://gitlab.com/flectra-community/devops/oca2fc/raw/master/ci_data/test_base.zip
|
||||
- 7z x -o ${CI_PROJECT_DIR}/ci_data/ ${CI_PROJECT_DIR}/ci_data/test_base.zip
|
||||
- export PGPASSWORD="flectra"
|
||||
- createdb -h psql -U flectra -O flectra -T template1 test_mis_builder_demo
|
||||
- psql -h psql -U flectra -d test_mis_builder_demo -f ${CI_PROJECT_DIR}/ci_data/dump.sql
|
||||
- su - flectra -c "mkdir -p ~/.local/share/filestore"
|
||||
- mv ${CI_PROJECT_DIR}/ci_data/filestore /opt/flectra/.local/share/filestore/test_mis_builder_demo
|
||||
- chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_mis_builder_demo
|
||||
- su - flectra -c "/opt/flectra/flectra-bin
|
||||
--addons-path ${CI_PROJECT_DIR}
|
||||
--db_host psql
|
||||
--db_port 5432
|
||||
--db_user flectra
|
||||
--db_password flectra
|
||||
--database test_mis_builder_demo
|
||||
--test-enable -i mis_builder_demo
|
||||
--stop-after-init
|
||||
--log-level error
|
||||
--log-handler flectra.addons.mis_builder_demo:TEST"
|
||||
|
||||
test_module_mis_builder:
|
||||
stage: testsingle
|
||||
when: on_failure
|
||||
image:
|
||||
name: registry.gitlab.com/jamotion/flectra/ubuntudev:2-latest
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
script:
|
||||
- apt-get install -y p7zip-full
|
||||
- su - flectra -c "mkdir ~/others"
|
||||
- sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && dpkg-reconfigure --frontend=noninteractive locales && update-locale LANG=en_US.UTF-8
|
||||
- mkdir ${CI_PROJECT_DIR}/ci_data
|
||||
- wget -O ${CI_PROJECT_DIR}/ci_data/test_base.zip https://gitlab.com/flectra-community/devops/oca2fc/raw/master/ci_data/test_base.zip
|
||||
- 7z x -o ${CI_PROJECT_DIR}/ci_data/ ${CI_PROJECT_DIR}/ci_data/test_base.zip
|
||||
- export PGPASSWORD="flectra"
|
||||
- createdb -h psql -U flectra -O flectra -T template1 test_mis_builder
|
||||
- psql -h psql -U flectra -d test_mis_builder -f ${CI_PROJECT_DIR}/ci_data/dump.sql
|
||||
- su - flectra -c "mkdir -p ~/.local/share/filestore"
|
||||
- mv ${CI_PROJECT_DIR}/ci_data/filestore /opt/flectra/.local/share/filestore/test_mis_builder
|
||||
- chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_mis_builder
|
||||
- su - flectra -c "/opt/flectra/flectra-bin
|
||||
--addons-path ${CI_PROJECT_DIR}
|
||||
--db_host psql
|
||||
--db_port 5432
|
||||
--db_user flectra
|
||||
--db_password flectra
|
||||
--database test_mis_builder
|
||||
--test-enable -i mis_builder
|
||||
--stop-after-init
|
||||
--log-level error
|
||||
--log-handler flectra.addons.mis_builder:TEST"
|
||||
|
32
.gitlab/issue_templates/Bug.md
Normal file
32
.gitlab/issue_templates/Bug.md
Normal file
@ -0,0 +1,32 @@
|
||||
**Summary**
|
||||
|
||||
(Summarize the bug encountered concisely)
|
||||
|
||||
|
||||
**Steps to reproduce**
|
||||
|
||||
(How one can reproduce the issue - this is very important)
|
||||
|
||||
|
||||
**What is the current bug behavior?**
|
||||
|
||||
(What actually happens)
|
||||
|
||||
|
||||
**What is the expected correct behavior?**
|
||||
|
||||
(What you should see instead)
|
||||
|
||||
|
||||
**Relevant logs and/or screenshots**
|
||||
|
||||
(Paste any relevant logs - please use code blocks (```) to format console output,
|
||||
logs, and code as it's very hard to read otherwise.)
|
||||
|
||||
|
||||
**Possible fixes**
|
||||
|
||||
(If you can, link to the line of code that might be responsible for the problem)
|
||||
|
||||
/label ~bug
|
||||
|
16
README.md
Normal file
16
README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Flectra Community / mis-builder
|
||||
|
||||
None
|
||||
|
||||
|
||||
|
||||
Available addons
|
||||
----------------
|
||||
|
||||
addon | version | summary
|
||||
--- | --- | ---
|
||||
[mis_builder_budget](mis_builder_budget/) | 3.0.5.0.2| Create budgets for MIS reports
|
||||
[mis_builder_demo](mis_builder_demo/) | 3.0.1.0.2| Demo addon for MIS Builder
|
||||
[mis_builder](mis_builder/) | 3.0.5.1.5| Build 'Management Information System' Reports and Dashboards
|
||||
|
||||
|
26
mis_builder/COPYRIGHT
Normal file
26
mis_builder/COPYRIGHT
Normal file
@ -0,0 +1,26 @@
|
||||
Most of the files are
|
||||
|
||||
:Copyright: This stylesheet has been placed in the public domain.
|
||||
Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
Copyright 2014-2018 ACSONE SA/NV (<http://acsone.eu>)
|
||||
Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
|
||||
Copyright 2016 Akretion (<http://akretion.com>)
|
||||
Copyright 2016 Therp BV (<http://therp.nl>)
|
||||
Copyright 2016 Thomas Binsfeld
|
||||
Copyright 2017 ACSONE SA/NV
|
||||
Copyright 2017 ACSONE SA/NV (<http://acsone.eu>)
|
||||
Copyright 2020 ACSONE SA/NV
|
||||
Copyright 2020 ACSONE SA/NV (<http://acsone.eu>)
|
||||
Copyright 2020 CorporateHub (https://corporatehub.eu)
|
||||
Copyright 2023 ACSONE SA/NV (<http://acsone.eu>)
|
||||
Copyright 2018 Flectra Community
|
||||
|
||||
Many files also contain contributions from third
|
||||
parties. In this case the original copyright of
|
||||
the contributions can be traced through the
|
||||
history of the source version control system.
|
||||
|
||||
When that is not the case, the files contain a prominent
|
||||
notice stating the original copyright and applicable
|
||||
license, or come with their own dedicated COPYRIGHT
|
||||
and/or LICENSE file.
|
663
mis_builder/LICENSE
Normal file
663
mis_builder/LICENSE
Normal file
@ -0,0 +1,663 @@
|
||||
For copyright information, please see the COPYRIGHT file.
|
||||
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are 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.
|
||||
|
||||
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.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
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 Affero 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. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
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 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 work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero 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 Affero 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 Affero 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 Affero 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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
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 AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
699
mis_builder/README.rst
Normal file
699
mis_builder/README.rst
Normal file
@ -0,0 +1,699 @@
|
||||
===========
|
||||
MIS Builder
|
||||
===========
|
||||
|
||||
..
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:23fd54db34b43eef679da3049da56901c6bb54d081341c0d107e79b84721af47
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
|
||||
:target: https://odoo-community.org/page/development-status
|
||||
:alt: Production/Stable
|
||||
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmis--builder-lightgray.png?logo=github
|
||||
:target: https://github.com/OCA/mis-builder/tree/16.0/mis_builder
|
||||
:alt: OCA/mis-builder
|
||||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
||||
:target: https://translation.odoo-community.org/projects/mis-builder-16-0/mis-builder-16-0-mis_builder
|
||||
: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/mis-builder&target_branch=16.0
|
||||
:alt: Try me on Runboat
|
||||
|
||||
|badge1| |badge2| |badge3| |badge4| |badge5|
|
||||
|
||||
This module allows you to build Management Information Systems dashboards.
|
||||
Such style of reports presents KPI in rows and time periods in columns.
|
||||
Reports mainly fetch data from account moves, but can also combine data coming
|
||||
from arbitrary Odoo models. Reports can be exported to PDF, Excel and they
|
||||
can be added to Odoo dashboards.
|
||||
|
||||
**Table of contents**
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Your preferred way to install addons will work with MIS Builder.
|
||||
|
||||
An easy way to install it with all its dependencies is using pip:
|
||||
|
||||
* ``pip install --pre odoo12-addon-mis_builder``
|
||||
* then restart Odoo, update the addons list in your database, and install
|
||||
the MIS Builder application.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
To configure this module, you need to:
|
||||
|
||||
* Go to Accounting > Configuration > MIS Reporting > MIS Report Templates where
|
||||
you can create report templates by defining KPI's. KPI's constitute the rows of your
|
||||
reports. Such report templates are time independent.
|
||||
|
||||
.. figure:: https://raw.githubusercontent.com/OCA/mis-builder/10.0/mis_builder/static/description/ex_report_template.png
|
||||
:alt: Sample report template
|
||||
:width: 80 %
|
||||
:align: center
|
||||
|
||||
* Then in Accounting > Reports > MIS Reporting > MIS Reports you can create report instance by
|
||||
binding the templates to time periods, hence defining the columns of your reports.
|
||||
|
||||
.. figure:: https://raw.githubusercontent.com/OCA/mis-builder/10.0/mis_builder/static/description/ex_report_settings.png
|
||||
:alt: Sample report configuration
|
||||
:width: 80 %
|
||||
:align: center
|
||||
|
||||
* From the MIS Reports view, you can preview the report, add it to and Odoo dashboard,
|
||||
and export it to PDF or Excel.
|
||||
|
||||
.. figure:: https://raw.githubusercontent.com/OCA/mis-builder/10.0/mis_builder/static/description/ex_report_preview.png
|
||||
:alt: Sample preview
|
||||
:width: 80 %
|
||||
:align: center
|
||||
|
||||
Development
|
||||
===========
|
||||
|
||||
A typical extension is to provide a mechanism to filter reports on analytic dimensions
|
||||
or operational units. To implement this, you can override _get_additional_move_line_filter
|
||||
and _get_additional_filter to further filter move lines or queries based on a user
|
||||
selection. A typical use case could be to add an analytic account field on mis.report.instance,
|
||||
or even on mis.report.instance.period if you want different columns to show different
|
||||
analytic accounts.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
The mis_builder `roadmap <https://github.com/OCA/mis-builder/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement>`_
|
||||
and `known issues <https://github.com/OCA/mis-builder/issues?q=is%3Aopen+is%3Aissue+label%3Abug>`_ can
|
||||
be found on GitHub.
|
||||
|
||||
Changelog
|
||||
=========
|
||||
|
||||
16.0.5.1.0 (2023-04-04)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
- Improve UX by adding the option to edit the pivot date directly on the view.
|
||||
|
||||
16.0.5.0.0 (2023-04-01)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
- Migration to 16.0
|
||||
|
||||
- Addition of a generic filter domain on reports and columns.
|
||||
- Addition of a search bar to the widget. The corresponding search view is configurable
|
||||
per report.
|
||||
- Huge improvement of the widget style. This was long overdue.
|
||||
- Make the MIS Report menu accessible to the Billing Administrator group
|
||||
(instead of the hidden Show Full Accounting Features), to align with the access rules
|
||||
and avoid giving a false sense of security. This also makes the menu discoverable to
|
||||
new users.
|
||||
- Removal of analytic fetures because the upstream ``analytic_distribution`` mechanism
|
||||
is not compatible; support may be introduced in separate module, depending on use
|
||||
cases.
|
||||
- Abandon the ``mis_report_filters`` context key which had security implication.
|
||||
It is replaced by a ``mis_analytic_domain`` context key which is ANDed with other
|
||||
report-defined filters. (`#472 <https://github.com/OCA/mis-builder/issues/472>`_)
|
||||
- Rename the ``get_filter_descriptions_from_context`` method to
|
||||
``get_filter_descriptions``. This method may be overridden to provide additional
|
||||
subtitles on the PDF or XLS report, representing user-selected filters.
|
||||
- The ``hide_analytic_filters`` has been replaced by ``widget_show_filters``.
|
||||
- The visibility of the settings button on the widget is now controlled by a
|
||||
``show_settings_button``. Before it was visible only for the ``account_user`` group
|
||||
but this was not flexible enough.
|
||||
- The widget configuration settings are now grouped in a dedicated ``Widget`` tab in
|
||||
the report configuration form.
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Fix access error when previewing or printing report. (`#415 <https://github.com/OCA/mis-builder/issues/415>`_)
|
||||
|
||||
|
||||
15.0.4.0.5 (2022-07-19)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Support users without timezone. (`#388 <https://github.com/OCA/mis-builder/issues/388>`_)
|
||||
|
||||
|
||||
15.0.4.0.4 (2022-07-19)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Allow deleting a report that has subreports. (`#431 <https://github.com/OCA/mis-builder/issues/431>`_)
|
||||
|
||||
|
||||
15.0.4.0.2 (2022-02-16)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Fix access right issue when clicking the "Save" button on a MIS Report Instance form. (`#410 <https://github.com/OCA/mis-builder/issues/410>`_)
|
||||
|
||||
|
||||
14.0.4.0.0 (2022-01-08)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
- Remove various field size limits. (`#332 <https://github.com/OCA/mis-builder/issues/332>`_)
|
||||
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Support for the Odoo 13+ multi-company model. In multi-company mode, several allowed
|
||||
companies can be declared on MIS Report instances, and the report operates on the
|
||||
intersection of report companies and companies selected in the user context. (`#327 <https://github.com/OCA/mis-builder/issues/327>`_)
|
||||
- The ``get_additional_query_filter`` argument of ``evaluate()`` is now propagated
|
||||
correctly. (`#375 <https://github.com/OCA/mis-builder/issues/375>`_)
|
||||
- Use the ``parent_state`` field of ``account.move.line`` to filter entries in ``posted``
|
||||
and ``draft`` state only. Before, when reporting in draft mode, all entries were used
|
||||
(i.e. there was no filter), and that started including the cancelled entries/invoices in
|
||||
Odoo 13.+.
|
||||
|
||||
This change also contains a **breaking change** in the internal API. For quite a while
|
||||
the ``target_move argument`` of AEP and other methods was not used by MIS Builder itself
|
||||
and was kept for backward compatibility. To avoid rippling effects of the necessary
|
||||
change to use ``parent_state``, we now remove this argument. (`#377 <https://github.com/OCA/mis-builder/issues/377>`_)
|
||||
|
||||
|
||||
14.0.3.6.7 (2021-06-02)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- When on a MIS Report Instance, if you wanted to generate a new line of type comparison, you couldn't currently select any existing period to compare.
|
||||
This happened because the field domain was searching in a NewId context, thus not finding a correct period.
|
||||
Changing the domain and making it use a computed field with a search for the _origin record solves the problem. (`#361 <https://github.com/OCA/mis-builder/issues/361>`_)
|
||||
|
||||
|
||||
14.0.3.6.6 (2021-04-23)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Fix drilldown action name when the account model has been customized. (`#350 <https://github.com/OCA/mis-builder/issues/350>`_)
|
||||
|
||||
|
||||
14.0.3.6.5 (2021-04-23)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- While duplicating a MIS report instance, comparison columns are ignored because
|
||||
they would raise an error otherwise, as they keep the old source_cmpcol_from_id
|
||||
and source_cmpcol_to_id from the original record. (`#343 <https://github.com/OCA/mis-builder/issues/343>`_)
|
||||
|
||||
|
||||
14.0.3.6.4 (2021-04-06)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
- The drilldown action name displayed on the breadcrumb has been revised.
|
||||
The kpi description and the account ``display_name`` are shown instead
|
||||
of the kpi's technical definition. (`#304 <https://github.com/OCA/mis-builder/issues/304>`_)
|
||||
- Add analytic group filters on report instance, periods and in the interactive
|
||||
view. (`#320 <https://github.com/OCA/mis-builder/issues/320>`_)
|
||||
|
||||
|
||||
13.0.3.6.3 (2020-08-28)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Having a "Compare columns" added on a KPI with an associated style using a
|
||||
Factor/Divider did lead to the said factor being applied on the percentages
|
||||
when exporting to XLSX. (`#300 <https://github.com/OCA/mis-builder/issues/300>`_)
|
||||
|
||||
|
||||
**Misc**
|
||||
|
||||
- `#280 <https://github.com/OCA/mis-builder/issues/280>`_, `#296 <https://github.com/OCA/mis-builder/issues/296>`_
|
||||
|
||||
|
||||
13.0.3.6.2 (2020-04-22)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- The "Settings" button is now displayed for users with the "Show full accounting features" right when previewing a report. (`#281 <https://github.com/OCA/mis-builder/issues/281>`_)
|
||||
|
||||
|
||||
13.0.3.6.1 (2020-04-22)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Fix ``TypeError: 'module' object is not iterable`` when using
|
||||
budgets by account. (`#276 <https://github.com/OCA/mis-builder/issues/276>`_)
|
||||
|
||||
|
||||
13.0.3.6.0 (2020-03-28)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
- Add column-level filters on analytic account and analytic tags.
|
||||
These filters are combined with a AND with the report-level filters
|
||||
and cannot be modified in the preview. (`#138 <https://github.com/OCA/mis-builder/issues/138>`_)
|
||||
- Access to KPI from other reports in KPI expressions, aka subreports. In a
|
||||
report template, one can list named "subreports" (other report templates). When
|
||||
evaluating expressions, you can access KPI's of subreports with a dot-prefix
|
||||
notation. Example: you can define a MIS Report for a "Balance Sheet", and then
|
||||
have another MIS Report "Balance Sheet Ratios" that fetches KPI's from "Balance
|
||||
Sheet" to create new KPI's for the ratios (e.g. balance_sheet.current_assets /
|
||||
balance_sheet.total_assets). (`#155 <https://github.com/OCA/mis-builder/issues/155>`_)
|
||||
|
||||
|
||||
13.0.3.5.0 (2020-01-??)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Migration to odoo 13.0.
|
||||
|
||||
12.0.3.5.0 (2019-10-26)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
- The ``account_id`` field of the model selected in 'Move lines source'
|
||||
in the Period form can now be a Many2one
|
||||
relationship with any model that has a ``code`` field (not only with
|
||||
``account.account`` model). To this end, the model to be used for Actuals
|
||||
move lines can be configured on the report template. It can be something else
|
||||
than move lines and the only constraint is that its ``account_id`` field
|
||||
has a ``code`` field. (`#149 <https://github.com/oca/mis-builder/issues/149>`_)
|
||||
- Add ``source_aml_model_name`` field so extension modules providing
|
||||
alternative data sources can more easily customize their data source. (`#214 <https://github.com/oca/mis-builder/issues/214>`_)
|
||||
- Support analytic tag filters in the backend view and preview widget.
|
||||
Selecting several tags in the filter means filtering on move lines which
|
||||
have *all* these tags set. This is to support the most common use case of
|
||||
using tags for different dimensions. The filter also makes a AND with the
|
||||
analytic account filter. (`#228 <https://github.com/oca/mis-builder/issues/228>`_)
|
||||
- Display company in account details rows in multi-company mode. (`#242 <https://github.com/oca/mis-builder/issues/242>`_)
|
||||
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Propagate context to xlsx report, so the analytic account filter
|
||||
works when exporting to xslx too. This also requires a fix to
|
||||
``report_xlsx`` (see https://github.com/OCA/reporting-engine/pull/259). (`#178 <https://github.com/oca/mis-builder/issues/178>`_)
|
||||
- In columns of type Sum, preserve styles for KPIs that are not summable
|
||||
(eg percentage values). Before this fix, such cells were displayed without
|
||||
style. (`#219 <https://github.com/oca/mis-builder/issues/219>`_)
|
||||
- In Excel export, keep the percentage point suffix (pp) instead of replacing it with %. (`#220 <https://github.com/oca/mis-builder/issues/220>`_)
|
||||
|
||||
|
||||
12.0.3.4.0 (2019-07-09)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
- New year-to-date mode for defining periods. (`#165 <https://github.com/oca/mis-builder/issues/165>`_)
|
||||
- Add support for move lines with negative debit or credit.
|
||||
Used by some for storno accounting. Not officially supported. (`#175 <https://github.com/oca/mis-builder/issues/175>`_)
|
||||
- In Excel export, use a number format with thousands separator. The
|
||||
specific separator used depends on the Excel configuration (eg regional
|
||||
settings). (`#190 <https://github.com/oca/mis-builder/issues/190>`_)
|
||||
- Add generation date/time at the end of the XLS export. (`#191 <https://github.com/oca/mis-builder/issues/191>`_)
|
||||
- In presence of Sub KPIs, report more informative user errors when
|
||||
non-multi expressions yield tuples of incorrect lenght. (`#196 <https://github.com/oca/mis-builder/issues/196>`_)
|
||||
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Fix rendering of percentage types in Excel export. (`#192 <https://github.com/oca/mis-builder/issues/192>`_)
|
||||
|
||||
|
||||
12.0.3.3.0 (2019-01-26)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
*Dynamic analytic filters in report preview are not yet available in 11,
|
||||
this requires an update to the JS widget that proved difficult to implement
|
||||
so far. Help welcome.*
|
||||
|
||||
- Analytic account filters. On a report, an analytic
|
||||
account can be selected for filtering. The filter will
|
||||
be applied to move lines queries. A filter box is also
|
||||
available in the widget to let the user select the analytic
|
||||
account during report preview. (`#15 <https://github.com/oca/mis-builder/issues/15>`_)
|
||||
- Control visibility of analytic filter combo box in widget.
|
||||
This is useful to hide the analytic filters on reports where
|
||||
they do not make sense, such as balance sheet reports. (`#42 <https://github.com/oca/mis-builder/issues/42>`_)
|
||||
- Display analytic filters in the header of exported pdf and xls. (`#44 <https://github.com/oca/mis-builder/issues/44>`_)
|
||||
- Replace the last old gtk icons with fontawesome icons. (`#104 <https://github.com/oca/mis-builder/issues/104>`_)
|
||||
- Use active_test=False in AEP queries.
|
||||
This is important for reports involving inactive taxes.
|
||||
This should not negatively effect existing reports, because
|
||||
an accounting report must take into account all existing move lines
|
||||
even if they reference objects such as taxes, journals, accounts types
|
||||
that have been deactivated since their creation. (`#107 <https://github.com/oca/mis-builder/issues/107>`_)
|
||||
- int(), float() and round() support for AccountingNone. (`#108 <https://github.com/oca/mis-builder/issues/108>`_)
|
||||
- Allow referencing subkpis by name by writing `kpi_x.subkpi_y` in expressions. (`#114 <https://github.com/oca/mis-builder/issues/114>`_)
|
||||
- Add an option to control the display of the start/end dates in the
|
||||
column headers. It is disabled by default (this is a change compared
|
||||
to previous behaviour). (`#118 <https://github.com/oca/mis-builder/issues/118>`_)
|
||||
- Add evaluate method to mis.report. This is a simplified
|
||||
method to evaluate kpis of a report over a time period,
|
||||
without creating a mis.report.instance. (`#123 <https://github.com/oca/mis-builder/issues/123>`_)
|
||||
|
||||
**Bugs**
|
||||
|
||||
- In the style form, hide the "Hide always" checkbox when "Hide always inherit"
|
||||
is checked, as for all other syle elements. (`#121 <https://github.com/OCA/mis-builder/pull/121>_`)
|
||||
|
||||
**Upgrading from 3.2 (breaking changes)**
|
||||
|
||||
If you use ``Actuals (alternative)`` data source in combination with analytic
|
||||
filters, the underlying model must now have an ``analytic_account_id`` field.
|
||||
|
||||
|
||||
11.0.3.2.2 (2018-06-30)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* [FIX] Fix bug in company_default_get call returning
|
||||
id instead of recordset
|
||||
(`#103 <https://github.com/OCA/mis-builder/pull/103>`_)
|
||||
* [IMP] add "hide always" style property to make hidden KPI's
|
||||
(for KPI that serve as basis for other formulas, but do not
|
||||
need to be displayed).
|
||||
(`#46 <https://github.com/OCA/mis-builder/issues/46>`_)
|
||||
|
||||
11.0.3.2.1 (2018-05-29)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* [FIX] Missing comparison operator for AccountingNone
|
||||
leading to errors in pbal computations
|
||||
(`#93 <https://github.com/OCA/mis-builder/issue/93>`_)
|
||||
|
||||
10.0.3.2.0 (2018-05-02)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* [FIX] make subkpi ordering deterministic
|
||||
(`#71 <https://github.com/OCA/mis-builder/issues/71>`_)
|
||||
* [ADD] report instance level option to disable account expansion,
|
||||
enabling the creation of detailed templates while deferring the decision
|
||||
of rendering the details or not to the report instance
|
||||
(`#74 <https://github.com/OCA/mis-builder/issues/74>`_)
|
||||
* [ADD] pbal and nbal accounting expressions, to sum positive
|
||||
and negative balances respectively (ie ignoring accounts with negative,
|
||||
resp positive balances)
|
||||
(`#86 <https://github.com/OCA/mis-builder/issues/86>`_)
|
||||
|
||||
11.0.3.1.2 (2018-02-04)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Migration to Odoo 11. No new feature.
|
||||
(`#67 <https://github.com/OCA/mis-builder/pull/67>`_)
|
||||
|
||||
10.0.3.1.1 (2017-11-14)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
New features:
|
||||
|
||||
* [ADD] month and year relative periods, easier to use than
|
||||
date ranges for the most common case.
|
||||
(`#2 <https://github.com/OCA/mis-builder/issues/2>`_)
|
||||
* [ADD] multi-company consolidation support, with currency conversion
|
||||
(the conversion rate date is the end of the reporting period)
|
||||
(`#7 <https://github.com/OCA/mis-builder/issues/7>`_,
|
||||
`#3 <https://github.com/OCA/mis-builder/issues/3>`_)
|
||||
* [ADD] provide ref, datetime, dateutil, time, user in the evaluation
|
||||
context of move line domains; among other things, this allows using
|
||||
references to xml ids (such as account types or tax tags) when
|
||||
querying move lines
|
||||
(`#26 <https://github.com/OCA/mis-builder/issues/26>`_).
|
||||
* [ADD] extended account selectors: you can now select accounts using
|
||||
any domain on account.account, not only account codes
|
||||
``balp[('account_type', '=', 'asset_receivable')]``
|
||||
(`#4 <https://github.com/OCA/mis-builder/issues/4>`_).
|
||||
* [IMP] in the report instance configuration form, the filters are
|
||||
now grouped in a notebook page, this improves readability and
|
||||
extensibility
|
||||
(`#39 <https://github.com/OCA/mis-builder/issues/39>`_).
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [FIX] fix error when saving periods in comparison mode on newly
|
||||
created (not yet saved) report instances.
|
||||
`#50 <https://github.com/OCA/mis-builder/pull/50>`_
|
||||
* [FIX] improve display of Base Date report instance view.
|
||||
`#51 <https://github.com/OCA/mis-builder/pull/51>`_
|
||||
|
||||
Upgrading from 3.0 (breaking changes):
|
||||
|
||||
* Alternative move line data sources must have a company_id field.
|
||||
|
||||
10.0.3.0.4 (2017-10-14)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Bug fix:
|
||||
|
||||
* [FIX] issue with initial balance rounding.
|
||||
`#30 <https://github.com/OCA/mis-builder/issues/30>`_
|
||||
|
||||
10.0.3.0.3 (2017-10-03)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Bug fix:
|
||||
|
||||
* [FIX] fix error saving KPI on newly created reports.
|
||||
`#18 <https://github.com/OCA/mis-builder/issues/18>`_
|
||||
|
||||
10.0.3.0.2 (2017-10-01)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
New features:
|
||||
|
||||
* [ADD] Alternative move line source per report column.
|
||||
This makes mis buidler accounting expressions work on any model
|
||||
that has debit, credit, account_id and date fields. Provided you can
|
||||
expose, say, committed purchases, or your budget as a view with
|
||||
debit, credit and account_id, this opens up a lot of possibilities
|
||||
* [ADD] Comparison column source (more flexible than the previous,
|
||||
now deprecated, comparison mechanism).
|
||||
CAVEAT: there is no automated migration to the new mechanism.
|
||||
* [ADD] Sum column source, to create columns that add/subtract
|
||||
other columns.
|
||||
* [ADD] mis.kpi.data abstract model as a basis for manual KPI values
|
||||
supporting automatic ajustment to the reporting time period (the basis
|
||||
for budget item, but could also server other purposes, such as manually
|
||||
entering some KPI values, such as number of employee)
|
||||
* [ADD] mis_builder_budget module providing a new budget data source
|
||||
* [ADD] new "hide empty" style property
|
||||
* [IMP] new AEP method to get accounts involved in an expression
|
||||
(this is useful to find which KPI relate to a given P&L
|
||||
acount, to implement budget control)
|
||||
* [IMP] many UI improvements
|
||||
* [IMP] many code style improvements and some refactoring
|
||||
* [IMP] add the column date_from, date_to in expression evaluation context,
|
||||
as well as time, datetime and dateutil modules
|
||||
|
||||
Main bug fixes:
|
||||
|
||||
* [FIX] deletion of templates and reports (cascade and retricts)
|
||||
(https://github.com/OCA/account-financial-reporting/issues/281)
|
||||
* [FIX] copy of reports
|
||||
(https://github.com/OCA/account-financial-reporting/issues/282)
|
||||
* [FIX] better error message when periods have wrong/missing dates
|
||||
(https://github.com/OCA/account-financial-reporting/issues/283)
|
||||
* [FIX] xlsx export of string types KPI
|
||||
(https://github.com/OCA/account-financial-reporting/issues/285)
|
||||
* [FIX] sorting of detail by account
|
||||
* [FIX] computation bug in detail by account when multiple accounting
|
||||
expressions were used in a KPI
|
||||
* [FIX] permission issue when adding report to dashboard with non admin user
|
||||
|
||||
10.0.2.0.3 (unreleased)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* [IMP] more robust behaviour in presence of missing expressions
|
||||
* [FIX] indent style
|
||||
* [FIX] local variable 'ctx' referenced before assignment when generating
|
||||
reports with no objects
|
||||
* [IMP] use fontawesome icons
|
||||
* [MIG] migrate to 10.0
|
||||
* [FIX] unicode error when exporting to Excel
|
||||
* [IMP] provide full access to mis builder style for group Adviser.
|
||||
|
||||
9.0.2.0.2 (2016-09-27)
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* [IMP] Add refresh button in mis report preview.
|
||||
* [IMP] Widget code changes to allow to add fields in the widget more easily.
|
||||
|
||||
9.0.2.0.1 (2016-05-26)
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* [IMP] remove unused argument in declare_and_compute_period()
|
||||
for a cleaner API. This is a breaking API changing merged in
|
||||
urgency before it is used by other modules.
|
||||
|
||||
9.0.2.0.0 (2016-05-24)
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Part of the work for this release has been done at the Sorrento sprint
|
||||
April 26-29, 2016. The rest (ie a major refactoring) has been done in
|
||||
the weeks after.
|
||||
|
||||
* [IMP] hide button box in edit mode on the report instance settings form
|
||||
* [FIX] Fix sum aggregation of non-stored fields
|
||||
(https://github.com/OCA/account-financial-reporting/issues/178)
|
||||
* [IMP] There is now a default style at the report level
|
||||
* [CHG] Number display properties (rounding, prefix, suffix, factor) are
|
||||
now defined in styles
|
||||
* [CHG] Percentage difference are rounded to 1 digit instead of the kpi's
|
||||
rounding, as the KPI rounding does not make sense in this case
|
||||
* [CHG] The divider suffix (k, M, etc) is not inserted automatically anymore
|
||||
because it is inconsistent when working with prefixes; you need to add it
|
||||
manually in the suffix
|
||||
* [IMP] AccountingExpressionProcessor now supports 'balu' expressions
|
||||
to obtain the unallocated profit/loss of previous fiscal years;
|
||||
get_unallocated_pl is the corresponding convenience method
|
||||
* [IMP] AccountingExpressionProcessor now has easy methods to obtain
|
||||
balances by account: get_balances_initial, get_balances_end,
|
||||
get_balances_variation
|
||||
* [IMP] there is now an auto-expand feature to automatically display
|
||||
a detail by account for selected kpis
|
||||
* [IMP] the kpi and period lists are now manipulated through forms instead
|
||||
of directly in the tree views
|
||||
* [IMP] it is now possible to create a report through a wizard, such
|
||||
reports are deemed temporary and available through a "Last Reports Generated"
|
||||
menu, they are garbaged collected automatically, unless saved permanently,
|
||||
which can be done using a Save button
|
||||
* [IMP] there is now a beginner mode to configure simple reports with
|
||||
only one period
|
||||
* [IMP] it is now easier to configure periods with fixed start/end dates
|
||||
* [IMP] the new sub-kpi mechanism allows the creation of columns
|
||||
with multiple values, or columns with different values
|
||||
* [IMP] thanks to the new style model, the Excel export is now styled
|
||||
* [IMP] a new style model is now used to centralize style configuration
|
||||
* [FIX] use =like instead of like to search for accounts, because
|
||||
the % are added by the user in the expressions
|
||||
* [FIX] Correctly compute the initial balance of income and expense account
|
||||
based on the start of the fiscal year
|
||||
* [IMP] Support date ranges (from OCA/server-tools/date_range) as a more
|
||||
flexible alternative to fiscal periods
|
||||
* v9 migration: fiscal periods are removed, account charts are removed,
|
||||
consolidation accounts have been removed
|
||||
|
||||
8.0.1.0.0 (2016-04-27)
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* The copy of a MIS Report Instance now copies period.
|
||||
https://github.com/OCA/account-financial-reporting/pull/181
|
||||
* The copy of a MIS Report Template now copies KPIs and queries.
|
||||
https://github.com/OCA/account-financial-reporting/pull/177
|
||||
* Usability: the default view for MIS Report instances is now the rendered preview,
|
||||
and the settings are accessible through a gear icon in the list view and
|
||||
a button in the preview.
|
||||
https://github.com/OCA/account-financial-reporting/pull/170
|
||||
* Display blank cells instead of 0.0 when there is no data.
|
||||
https://github.com/OCA/account-financial-reporting/pull/169
|
||||
* Usability: better layout of the MIS Report periods settings on small screens.
|
||||
https://github.com/OCA/account-financial-reporting/pull/167
|
||||
* Include the download buttons inside the MIS Builder widget, and refactor
|
||||
the widget to open the door to analytic filtering in the previews.
|
||||
https://github.com/OCA/account-financial-reporting/pull/151
|
||||
* Add KPI rendering prefixes (so you can print $ in front of the value).
|
||||
https://github.com/OCA/account-financial-reporting/pull/158
|
||||
* Add hooks for analytic filtering.
|
||||
https://github.com/OCA/account-financial-reporting/pull/128
|
||||
https://github.com/OCA/account-financial-reporting/pull/131
|
||||
|
||||
8.0.0.2.0
|
||||
~~~~~~~~~
|
||||
|
||||
Pre-history. Or rather, you need to look at the git log.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/mis-builder/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/mis-builder/issues/new?body=module:%20mis_builder%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
|
||||
~~~~~~~
|
||||
|
||||
* ACSONE SA/NV
|
||||
|
||||
Contributors
|
||||
~~~~~~~~~~~~
|
||||
|
||||
* Stéphane Bidoul <stephane.bidoul@acsone.eu>
|
||||
* Laetitia Gangloff <laetitia.gangloff@acsone.eu>
|
||||
* Adrien Peiffer <adrien.peiffer@acsone.eu>
|
||||
* Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
* Alexandre Fayolle <alexandre.fayolle@camptocamp.com>
|
||||
* Jordi Ballester <jordi.ballester@eficent.com>
|
||||
* Thomas Binsfeld <thomas.binsfeld@gmail.com>
|
||||
* Giovanni Capalbo <giovanni@therp.nl>
|
||||
* Marco Calcagni <mcalcagni@dinamicheaziendali.it>
|
||||
* Sébastien Beau <sebastien.beau@akretion.com>
|
||||
* Laurent Mignon <laurent.mignon@acsone.eu>
|
||||
* Luc De Meyer <luc.demeyer@noviat.com>
|
||||
* Benjamin Willig <benjamin.willig@acsone.eu>
|
||||
* Martronic SA <info@martronic.ch>
|
||||
* nicomacr <nmr@adhoc.com.ar>
|
||||
* Juan Jose Scarafia <jjs@adhoc.com.ar>
|
||||
* Richard deMeester <richard@willowit.com.au>
|
||||
* Eric Caudal <eric.caudal@elico-corp.com>
|
||||
* Andrea Stirpe <a.stirpe@onestein.nl>
|
||||
* Maxence Groine <mgroine@fiefmanage.ch>
|
||||
* Arnaud Pineux <arnaud.pineux@acsone.eu>
|
||||
* Ernesto Tejeda <ernesto.tejeda@tecnativa.com>
|
||||
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
|
||||
* Alexey Pelykh <alexey.pelykh@corphub.eu>
|
||||
* Jairo Llopis (https://www.moduon.team/)
|
||||
* Dzung Tran <dungtd@trobz.com>
|
||||
* Hoang Diep <hoang@trobz.com>
|
||||
|
||||
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-sbidoul| image:: https://github.com/sbidoul.png?size=40px
|
||||
:target: https://github.com/sbidoul
|
||||
:alt: sbidoul
|
||||
|
||||
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|
||||
|
||||
|maintainer-sbidoul|
|
||||
|
||||
This module is part of the `OCA/mis-builder <https://github.com/OCA/mis-builder/tree/16.0/mis_builder>`_ project on GitHub.
|
||||
|
||||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
6
mis_builder/__init__.py
Normal file
6
mis_builder/__init__.py
Normal file
@ -0,0 +1,6 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import models
|
||||
from . import wizard
|
||||
from . import report
|
46
mis_builder/__manifest__.py
Normal file
46
mis_builder/__manifest__.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Copyright 2014-2018 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
{
|
||||
"name": "MIS Builder",
|
||||
"version": "3.0.5.1.5",
|
||||
"category": "Reporting",
|
||||
"summary": """
|
||||
Build 'Management Information System' Reports and Dashboards
|
||||
""",
|
||||
"author": "ACSONE SA/NV, " "Odoo Community Association (OCA)",
|
||||
"website": "https://gitlab.com/flectra-community/mis-builder",
|
||||
"depends": [
|
||||
"account",
|
||||
"board",
|
||||
"report_xlsx", # OCA/reporting-engine
|
||||
"date_range", # OCA/server-ux
|
||||
],
|
||||
"data": [
|
||||
"wizard/mis_builder_dashboard.xml",
|
||||
"views/mis_report.xml",
|
||||
"views/mis_report_instance.xml",
|
||||
"views/mis_report_style.xml",
|
||||
"datas/ir_cron.xml",
|
||||
"security/ir.model.access.csv",
|
||||
"security/mis_builder_security.xml",
|
||||
"report/mis_report_instance_qweb.xml",
|
||||
"report/mis_report_instance_xlsx.xml",
|
||||
],
|
||||
"assets": {
|
||||
"web.assets_backend": [
|
||||
"mis_builder/static/src/components/mis_report_widget.esm.js",
|
||||
"mis_builder/static/src/components/mis_report_widget.xml",
|
||||
"mis_builder/static/src/components/mis_report_widget.css",
|
||||
],
|
||||
"web.report_assets_common": [
|
||||
"/mis_builder/static/src/css/report.css",
|
||||
],
|
||||
},
|
||||
"qweb": ["static/src/xml/mis_report_widget.xml"],
|
||||
"installable": False,
|
||||
"application": True,
|
||||
"license": "AGPL-3",
|
||||
"development_status": "Production/Stable",
|
||||
"maintainers": ["sbidoul"],
|
||||
}
|
13
mis_builder/datas/ir_cron.xml
Normal file
13
mis_builder/datas/ir_cron.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<flectra noupdate="1">
|
||||
<record id="ir_cron_vacuum_temp_reports" model="ir.cron">
|
||||
<field name="name">Vacuum temporary reports</field>
|
||||
<field name="interval_number">4</field>
|
||||
<field name="interval_type">hours</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall" />
|
||||
<field ref="model_mis_report_instance" name="model_id" />
|
||||
<field name="code">model._vacuum_report()</field>
|
||||
<field name="active" eval="True" />
|
||||
</record>
|
||||
</flectra>
|
2413
mis_builder/i18n/ca.po
Normal file
2413
mis_builder/i18n/ca.po
Normal file
File diff suppressed because it is too large
Load Diff
1868
mis_builder/i18n/de.po
Normal file
1868
mis_builder/i18n/de.po
Normal file
File diff suppressed because it is too large
Load Diff
1786
mis_builder/i18n/el.po
Normal file
1786
mis_builder/i18n/el.po
Normal file
File diff suppressed because it is too large
Load Diff
1786
mis_builder/i18n/el_GR.po
Normal file
1786
mis_builder/i18n/el_GR.po
Normal file
File diff suppressed because it is too large
Load Diff
2243
mis_builder/i18n/es.po
Normal file
2243
mis_builder/i18n/es.po
Normal file
File diff suppressed because it is too large
Load Diff
2167
mis_builder/i18n/fr.po
Normal file
2167
mis_builder/i18n/fr.po
Normal file
File diff suppressed because it is too large
Load Diff
1881
mis_builder/i18n/fr_FR.po
Normal file
1881
mis_builder/i18n/fr_FR.po
Normal file
File diff suppressed because it is too large
Load Diff
1925
mis_builder/i18n/hr.po
Normal file
1925
mis_builder/i18n/hr.po
Normal file
File diff suppressed because it is too large
Load Diff
1880
mis_builder/i18n/it.po
Normal file
1880
mis_builder/i18n/it.po
Normal file
File diff suppressed because it is too large
Load Diff
1765
mis_builder/i18n/mis_builder.pot
Normal file
1765
mis_builder/i18n/mis_builder.pot
Normal file
File diff suppressed because it is too large
Load Diff
2063
mis_builder/i18n/nl.po
Normal file
2063
mis_builder/i18n/nl.po
Normal file
File diff suppressed because it is too large
Load Diff
2066
mis_builder/i18n/nl_NL.po
Normal file
2066
mis_builder/i18n/nl_NL.po
Normal file
File diff suppressed because it is too large
Load Diff
1793
mis_builder/i18n/pt.po
Normal file
1793
mis_builder/i18n/pt.po
Normal file
File diff suppressed because it is too large
Load Diff
2179
mis_builder/i18n/pt_BR.po
Normal file
2179
mis_builder/i18n/pt_BR.po
Normal file
File diff suppressed because it is too large
Load Diff
1798
mis_builder/i18n/sv.po
Normal file
1798
mis_builder/i18n/sv.po
Normal file
File diff suppressed because it is too large
Load Diff
1788
mis_builder/i18n/tr.po
Normal file
1788
mis_builder/i18n/tr.po
Normal file
File diff suppressed because it is too large
Load Diff
10
mis_builder/migrations/16.0.5.0.0/end-migrate.py
Normal file
10
mis_builder/migrations/16.0.5.0.0/end-migrate.py
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright 2023 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import flectra
|
||||
from flectra import api
|
||||
|
||||
|
||||
def migrate(cr, installed_version):
|
||||
env = api.Environment(cr, flectra.SUPERUSER_ID, {})
|
||||
env["mis.report.instance.period"].search([])._compute_source_aml_model_id()
|
29
mis_builder/migrations/8.0.2.0.0/post-migration.py
Normal file
29
mis_builder/migrations/8.0.2.0.0/post-migration.py
Normal file
@ -0,0 +1,29 @@
|
||||
# Copyright 2017 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
|
||||
def migrate(cr, version):
|
||||
cr.execute(
|
||||
"""
|
||||
INSERT INTO mis_report_kpi_expression
|
||||
(create_uid, create_date, write_uid, write_date,
|
||||
kpi_id, name, sequence)
|
||||
SELECT create_uid, create_date, write_uid, write_date,
|
||||
id, old_expression, sequence
|
||||
FROM mis_report_kpi
|
||||
"""
|
||||
)
|
||||
cr.execute(
|
||||
"""
|
||||
ALTER TABLE mis_report_kpi
|
||||
DROP COLUMN old_expression
|
||||
"""
|
||||
)
|
||||
# set default mode to relative for existing periods
|
||||
# as it was the only mode in previous versions
|
||||
cr.execute(
|
||||
"""
|
||||
UPDATE mis_report_instance_period
|
||||
SET mode='relative'
|
||||
"""
|
||||
)
|
20
mis_builder/migrations/8.0.2.0.0/pre-migration.py
Normal file
20
mis_builder/migrations/8.0.2.0.0/pre-migration.py
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright 2017 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
|
||||
def migrate(cr, version):
|
||||
cr.execute(
|
||||
"""
|
||||
ALTER TABLE mis_report_kpi
|
||||
RENAME COLUMN expression TO old_expression
|
||||
"""
|
||||
)
|
||||
# this migration to date_range type is partial,
|
||||
# actual date ranges needs to be created manually
|
||||
cr.execute(
|
||||
"""
|
||||
UPDATE mis_report_instance_period
|
||||
SET type='date_range'
|
||||
WHERE type='fp'
|
||||
"""
|
||||
)
|
10
mis_builder/models/__init__.py
Normal file
10
mis_builder/models/__init__.py
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import mis_report
|
||||
from . import mis_report_subreport
|
||||
from . import mis_report_instance
|
||||
from . import mis_report_style
|
||||
from . import aep
|
||||
from . import mis_kpi_data
|
||||
from . import prorata_read_group_mixin
|
215
mis_builder/models/accounting_none.py
Normal file
215
mis_builder/models/accounting_none.py
Normal file
@ -0,0 +1,215 @@
|
||||
# Copyright 2016 Thomas Binsfeld
|
||||
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
"""
|
||||
Provides the AccountingNone singleton.
|
||||
|
||||
AccountingNone is a null value that dissolves in basic arithmetic operations,
|
||||
as illustrated in the examples below. In comparisons, AccountingNone behaves
|
||||
the same as zero.
|
||||
|
||||
>>> 1 + 1
|
||||
2
|
||||
>>> 1 + AccountingNone
|
||||
1
|
||||
>>> AccountingNone + 1
|
||||
1
|
||||
>>> AccountingNone + None
|
||||
AccountingNone
|
||||
>>> None + AccountingNone
|
||||
AccountingNone
|
||||
>>> +AccountingNone
|
||||
AccountingNone
|
||||
>>> -AccountingNone
|
||||
AccountingNone
|
||||
>>> -(AccountingNone)
|
||||
AccountingNone
|
||||
>>> AccountingNone - 1
|
||||
-1
|
||||
>>> 1 - AccountingNone
|
||||
1
|
||||
>>> abs(AccountingNone)
|
||||
AccountingNone
|
||||
>>> AccountingNone - None
|
||||
AccountingNone
|
||||
>>> None - AccountingNone
|
||||
AccountingNone
|
||||
>>> AccountingNone / 2
|
||||
0.0
|
||||
>>> 2 / AccountingNone
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ZeroDivisionError
|
||||
>>> AccountingNone / AccountingNone
|
||||
AccountingNone
|
||||
>>> AccountingNone // 2
|
||||
0.0
|
||||
>>> 2 // AccountingNone
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ZeroDivisionError
|
||||
>>> AccountingNone // AccountingNone
|
||||
AccountingNone
|
||||
>>> AccountingNone * 2
|
||||
0.0
|
||||
>>> 2 * AccountingNone
|
||||
0.0
|
||||
>>> AccountingNone * AccountingNone
|
||||
AccountingNone
|
||||
>>> AccountingNone * None
|
||||
AccountingNone
|
||||
>>> None * AccountingNone
|
||||
AccountingNone
|
||||
>>> str(AccountingNone)
|
||||
''
|
||||
>>> bool(AccountingNone)
|
||||
False
|
||||
>>> AccountingNone > 0
|
||||
False
|
||||
>>> AccountingNone < 0
|
||||
False
|
||||
>>> AccountingNone < 1
|
||||
True
|
||||
>>> AccountingNone > 1
|
||||
False
|
||||
>>> 0 < AccountingNone
|
||||
False
|
||||
>>> 0 > AccountingNone
|
||||
False
|
||||
>>> 1 < AccountingNone
|
||||
False
|
||||
>>> 1 > AccountingNone
|
||||
True
|
||||
>>> AccountingNone == 0
|
||||
True
|
||||
>>> AccountingNone == 0.0
|
||||
True
|
||||
>>> AccountingNone == None
|
||||
True
|
||||
>>> AccountingNone >= AccountingNone
|
||||
True
|
||||
>>> AccountingNone <= AccountingNone
|
||||
True
|
||||
>>> round(AccountingNone, 2)
|
||||
0.0
|
||||
>>> float(AccountingNone)
|
||||
0.0
|
||||
>>> int(AccountingNone)
|
||||
0
|
||||
"""
|
||||
|
||||
__all__ = ["AccountingNone"]
|
||||
|
||||
|
||||
class AccountingNoneType:
|
||||
def __add__(self, other):
|
||||
if other is None:
|
||||
return AccountingNone
|
||||
return other
|
||||
|
||||
__radd__ = __add__
|
||||
|
||||
def __sub__(self, other):
|
||||
if other is None:
|
||||
return AccountingNone
|
||||
return -other
|
||||
|
||||
def __rsub__(self, other):
|
||||
if other is None:
|
||||
return AccountingNone
|
||||
return other
|
||||
|
||||
def __iadd__(self, other):
|
||||
if other is None:
|
||||
return AccountingNone
|
||||
return other
|
||||
|
||||
def __isub__(self, other):
|
||||
if other is None:
|
||||
return AccountingNone
|
||||
return -other
|
||||
|
||||
def __abs__(self):
|
||||
return self
|
||||
|
||||
def __pos__(self):
|
||||
return self
|
||||
|
||||
def __neg__(self):
|
||||
return self
|
||||
|
||||
def __div__(self, other):
|
||||
if other is AccountingNone:
|
||||
return AccountingNone
|
||||
return 0.0
|
||||
|
||||
def __rdiv__(self, other):
|
||||
raise ZeroDivisionError
|
||||
|
||||
def __floordiv__(self, other):
|
||||
if other is AccountingNone:
|
||||
return AccountingNone
|
||||
return 0.0
|
||||
|
||||
def __rfloordiv__(self, other):
|
||||
raise ZeroDivisionError
|
||||
|
||||
def __truediv__(self, other):
|
||||
if other is AccountingNone:
|
||||
return AccountingNone
|
||||
return 0.0
|
||||
|
||||
def __rtruediv__(self, other):
|
||||
raise ZeroDivisionError
|
||||
|
||||
def __mul__(self, other):
|
||||
if other is None or other is AccountingNone:
|
||||
return AccountingNone
|
||||
return 0.0
|
||||
|
||||
__rmul__ = __mul__
|
||||
|
||||
def __repr__(self):
|
||||
return "AccountingNone"
|
||||
|
||||
def __str__(self):
|
||||
return ""
|
||||
|
||||
def __nonzero__(self):
|
||||
return False
|
||||
|
||||
def __bool__(self):
|
||||
return False
|
||||
|
||||
def __eq__(self, other):
|
||||
return other == 0 or other is None or other is AccountingNone
|
||||
|
||||
def __lt__(self, other):
|
||||
return other > 0
|
||||
|
||||
def __gt__(self, other):
|
||||
return other < 0
|
||||
|
||||
def __le__(self, other):
|
||||
return other >= 0
|
||||
|
||||
def __ge__(self, other):
|
||||
return other <= 0
|
||||
|
||||
def __float__(self):
|
||||
return 0.0
|
||||
|
||||
def __int__(self):
|
||||
return 0
|
||||
|
||||
def __round__(self, ndigits):
|
||||
return 0.0
|
||||
|
||||
|
||||
AccountingNone = AccountingNoneType()
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
546
mis_builder/models/aep.py
Normal file
546
mis_builder/models/aep.py
Normal file
@ -0,0 +1,546 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import logging
|
||||
import re
|
||||
from collections import defaultdict
|
||||
|
||||
from flectra import _, fields
|
||||
from flectra.exceptions import UserError
|
||||
from flectra.models import expression
|
||||
from flectra.tools.float_utils import float_is_zero
|
||||
from flectra.tools.safe_eval import datetime, dateutil, safe_eval, time
|
||||
|
||||
from .accounting_none import AccountingNone
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
_DOMAIN_START_RE = re.compile(r"\(|(['\"])[!&|]\1")
|
||||
|
||||
|
||||
def _is_domain(s):
|
||||
"""Test if a string looks like an Flectra domain"""
|
||||
return _DOMAIN_START_RE.match(s)
|
||||
|
||||
|
||||
class AccountingExpressionProcessor:
|
||||
"""Processor for accounting expressions.
|
||||
|
||||
Expressions of the form <field><mode>[accounts][optional move line domain]
|
||||
are supported, where:
|
||||
* field is bal, crd, deb, pbal (positive balances only),
|
||||
nbal (negative balance only)
|
||||
* mode is i (initial balance), e (ending balance),
|
||||
p (moves over period)
|
||||
* there is also a special u mode (unallocated P&L) which computes
|
||||
the sum from the beginning until the beginning of the fiscal year
|
||||
of the period; it is only meaningful for P&L accounts
|
||||
* accounts is a list of accounts, possibly containing % wildcards,
|
||||
or a domain expression on account.account
|
||||
* an optional domain on move lines allowing filters on eg analytic
|
||||
accounts or journal
|
||||
|
||||
Examples:
|
||||
* bal[70]: variation of the balance of moves on account 70
|
||||
over the period (it is the same as balp[70]);
|
||||
* bali[70,60]: balance of accounts 70 and 60 at the start of period;
|
||||
* bale[1%]: balance of accounts starting with 1 at end of period.
|
||||
|
||||
How to use:
|
||||
* repeatedly invoke parse_expr() for each expression containing
|
||||
accounting variables as described above; this lets the processor
|
||||
group domains and modes and accounts;
|
||||
* when all expressions have been parsed, invoke done_parsing()
|
||||
to notify the processor that it can prepare to query (mainly
|
||||
search all accounts - children, consolidation - that will need to
|
||||
be queried;
|
||||
* for each period, call do_queries(), then call replace_expr() for each
|
||||
expression to replace accounting variables with their resulting value
|
||||
for the given period.
|
||||
|
||||
How it works:
|
||||
* by accumulating the expressions before hand, it ensures to do the
|
||||
strict minimum number of queries to the database (for each period,
|
||||
one query per domain and mode);
|
||||
* it queries using the orm read_group which reduces to a query with
|
||||
sum on debit and credit and group by on account_id and company_id,
|
||||
(note: it seems the orm then does one query per account to fetch
|
||||
the account name...);
|
||||
* additionally, one query per view/consolidation account is done to
|
||||
discover the children accounts.
|
||||
"""
|
||||
|
||||
MODE_VARIATION = "p"
|
||||
MODE_INITIAL = "i"
|
||||
MODE_END = "e"
|
||||
MODE_UNALLOCATED = "u"
|
||||
|
||||
_ACC_RE = re.compile(
|
||||
r"(?P<field>\bbal|\bpbal|\bnbal|\bcrd|\bdeb)"
|
||||
r"(?P<mode>[piseu])?"
|
||||
r"\s*"
|
||||
r"(?P<account_sel>_[a-zA-Z0-9]+|\[.*?\])"
|
||||
r"\s*"
|
||||
r"(?P<ml_domain>\[.*?\])?"
|
||||
)
|
||||
|
||||
def __init__(self, companies, currency=None, account_model="account.account"):
|
||||
self.env = companies.env
|
||||
self.companies = companies
|
||||
if not currency:
|
||||
self.currency = companies.mapped("currency_id")
|
||||
if len(self.currency) > 1:
|
||||
raise UserError(
|
||||
_(
|
||||
"If currency_id is not provided, "
|
||||
"all companies must have the same currency."
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.currency = currency
|
||||
self.dp = self.currency.decimal_places
|
||||
# before done_parsing: {(ml_domain, mode): set(acc_domain)}
|
||||
# after done_parsing: {(ml_domain, mode): list(account_ids)}
|
||||
self._map_account_ids = defaultdict(set)
|
||||
# {account_domain: set(account_ids)}
|
||||
self._account_ids_by_acc_domain = defaultdict(set)
|
||||
# smart ending balance (returns AccountingNone if there
|
||||
# are no moves in period and 0 initial balance), implies
|
||||
# a first query to get the initial balance and another
|
||||
# to get the variation, so it's a bit slower
|
||||
self.smart_end = True
|
||||
# Account model
|
||||
self._account_model = self.env[account_model].with_context(active_test=False)
|
||||
|
||||
def _account_codes_to_domain(self, account_codes):
|
||||
"""Convert a comma separated list of account codes
|
||||
(possibly with wildcards) to a domain on account.account.
|
||||
"""
|
||||
elems = []
|
||||
for account_code in account_codes.split(","):
|
||||
account_code = account_code.strip()
|
||||
if "%" in account_code:
|
||||
elems.append([("code", "=like", account_code)])
|
||||
else:
|
||||
elems.append([("code", "=", account_code)])
|
||||
return tuple(expression.OR(elems))
|
||||
|
||||
def _parse_match_object(self, mo):
|
||||
"""Split a match object corresponding to an accounting variable
|
||||
|
||||
Returns field, mode, account domain, move line domain.
|
||||
"""
|
||||
domain_eval_context = {
|
||||
"ref": self.env.ref,
|
||||
"user": self.env.user,
|
||||
"time": time,
|
||||
"datetime": datetime,
|
||||
"dateutil": dateutil,
|
||||
}
|
||||
field, mode, account_sel, ml_domain = mo.groups()
|
||||
# handle some legacy modes
|
||||
if not mode:
|
||||
mode = self.MODE_VARIATION
|
||||
elif mode == "s":
|
||||
mode = self.MODE_END
|
||||
# convert account selector to account domain
|
||||
if account_sel.startswith("_"):
|
||||
# legacy bal_NNN%
|
||||
acc_domain = self._account_codes_to_domain(account_sel[1:])
|
||||
else:
|
||||
assert account_sel[0] == "[" and account_sel[-1] == "]"
|
||||
inner_account_sel = account_sel[1:-1].strip()
|
||||
if not inner_account_sel:
|
||||
# empty selector: select all accounts
|
||||
acc_domain = tuple()
|
||||
elif _is_domain(inner_account_sel):
|
||||
# account selector is a domain
|
||||
acc_domain = tuple(safe_eval(account_sel, domain_eval_context))
|
||||
else:
|
||||
# account selector is a list of account codes
|
||||
acc_domain = self._account_codes_to_domain(inner_account_sel)
|
||||
# move line domain
|
||||
if ml_domain:
|
||||
assert ml_domain[0] == "[" and ml_domain[-1] == "]"
|
||||
ml_domain = tuple(safe_eval(ml_domain, domain_eval_context))
|
||||
else:
|
||||
ml_domain = tuple()
|
||||
return field, mode, acc_domain, ml_domain
|
||||
|
||||
def parse_expr(self, expr):
|
||||
"""Parse an expression, extracting accounting variables.
|
||||
|
||||
Move line domains and account selectors are extracted and
|
||||
stored in the map so when all expressions have been parsed,
|
||||
we know which account domains to query for each move line domain
|
||||
and mode.
|
||||
"""
|
||||
for mo in self._ACC_RE.finditer(expr):
|
||||
_, mode, acc_domain, ml_domain = self._parse_match_object(mo)
|
||||
if mode == self.MODE_END and self.smart_end:
|
||||
modes = (self.MODE_INITIAL, self.MODE_VARIATION, self.MODE_END)
|
||||
else:
|
||||
modes = (mode,)
|
||||
for mode in modes:
|
||||
key = (ml_domain, mode)
|
||||
self._map_account_ids[key].add(acc_domain)
|
||||
|
||||
def done_parsing(self):
|
||||
"""Replace account domains by account ids in map"""
|
||||
for key, acc_domains in self._map_account_ids.items():
|
||||
all_account_ids = set()
|
||||
for acc_domain in acc_domains:
|
||||
acc_domain_with_company = expression.AND(
|
||||
[acc_domain, [("company_id", "in", self.companies.ids)]]
|
||||
)
|
||||
account_ids = self._account_model.search(acc_domain_with_company).ids
|
||||
self._account_ids_by_acc_domain[acc_domain].update(account_ids)
|
||||
all_account_ids.update(account_ids)
|
||||
self._map_account_ids[key] = list(all_account_ids)
|
||||
|
||||
@classmethod
|
||||
def has_account_var(cls, expr):
|
||||
"""Test if an string contains an accounting variable."""
|
||||
return bool(cls._ACC_RE.search(expr))
|
||||
|
||||
def get_account_ids_for_expr(self, expr):
|
||||
"""Get a set of account ids that are involved in an expression.
|
||||
|
||||
Prerequisite: done_parsing() must have been invoked.
|
||||
"""
|
||||
account_ids = set()
|
||||
for mo in self._ACC_RE.finditer(expr):
|
||||
field, mode, acc_domain, ml_domain = self._parse_match_object(mo)
|
||||
account_ids.update(self._account_ids_by_acc_domain[acc_domain])
|
||||
return account_ids
|
||||
|
||||
def get_aml_domain_for_expr(self, expr, date_from, date_to, account_id=None):
|
||||
"""Get a domain on account.move.line for an expression.
|
||||
|
||||
Prerequisite: done_parsing() must have been invoked.
|
||||
|
||||
Returns a domain that can be used to search on account.move.line.
|
||||
"""
|
||||
aml_domains = []
|
||||
date_domain_by_mode = {}
|
||||
for mo in self._ACC_RE.finditer(expr):
|
||||
field, mode, acc_domain, ml_domain = self._parse_match_object(mo)
|
||||
aml_domain = list(ml_domain)
|
||||
account_ids = set()
|
||||
account_ids.update(self._account_ids_by_acc_domain[acc_domain])
|
||||
if not account_id:
|
||||
aml_domain.append(("account_id", "in", tuple(account_ids)))
|
||||
else:
|
||||
# filter on account_id
|
||||
if account_id in account_ids:
|
||||
aml_domain.append(("account_id", "=", account_id))
|
||||
else:
|
||||
continue
|
||||
if field == "crd":
|
||||
aml_domain.append(("credit", "<>", 0.0))
|
||||
elif field == "deb":
|
||||
aml_domain.append(("debit", "<>", 0.0))
|
||||
aml_domains.append(expression.normalize_domain(aml_domain))
|
||||
if mode not in date_domain_by_mode:
|
||||
date_domain_by_mode[mode] = self.get_aml_domain_for_dates(
|
||||
date_from, date_to, mode
|
||||
)
|
||||
assert aml_domains
|
||||
# TODO we could do this for more precision:
|
||||
# AND(OR(aml_domains[mode]), date_domain[mode]) for each mode
|
||||
return expression.OR(aml_domains) + expression.OR(date_domain_by_mode.values())
|
||||
|
||||
def get_aml_domain_for_dates(self, date_from, date_to, mode):
|
||||
if mode == self.MODE_VARIATION:
|
||||
domain = [("date", ">=", date_from), ("date", "<=", date_to)]
|
||||
elif mode in (self.MODE_INITIAL, self.MODE_END):
|
||||
# for income and expense account, sum from the beginning
|
||||
# of the current fiscal year only, for balance sheet accounts
|
||||
# sum from the beginning of time
|
||||
date_from_date = fields.Date.from_string(date_from)
|
||||
# TODO this takes the fy from the first company
|
||||
# make that user controllable (nice to have)?
|
||||
fy_date_from = self.companies[0].compute_fiscalyear_dates(date_from_date)[
|
||||
"date_from"
|
||||
]
|
||||
domain = [
|
||||
"|",
|
||||
("date", ">=", fields.Date.to_string(fy_date_from)),
|
||||
("account_id.include_initial_balance", "=", True),
|
||||
]
|
||||
if mode == self.MODE_INITIAL:
|
||||
domain.append(("date", "<", date_from))
|
||||
elif mode == self.MODE_END:
|
||||
domain.append(("date", "<=", date_to))
|
||||
elif mode == self.MODE_UNALLOCATED:
|
||||
date_from_date = fields.Date.from_string(date_from)
|
||||
# TODO this takes the fy from the first company
|
||||
# make that user controllable (nice to have)?
|
||||
fy_date_from = self.companies[0].compute_fiscalyear_dates(date_from_date)[
|
||||
"date_from"
|
||||
]
|
||||
domain = [
|
||||
("date", "<", fields.Date.to_string(fy_date_from)),
|
||||
("account_id.include_initial_balance", "=", False),
|
||||
]
|
||||
return expression.normalize_domain(domain)
|
||||
|
||||
def _get_company_rates(self, date):
|
||||
# get exchange rates for each company with its rouding
|
||||
company_rates = {}
|
||||
target_rate = self.currency.with_context(date=date).rate
|
||||
for company in self.companies:
|
||||
if company.currency_id != self.currency:
|
||||
rate = target_rate / company.currency_id.with_context(date=date).rate
|
||||
else:
|
||||
rate = 1.0
|
||||
company_rates[company.id] = (rate, company.currency_id.decimal_places)
|
||||
return company_rates
|
||||
|
||||
def do_queries(
|
||||
self,
|
||||
date_from,
|
||||
date_to,
|
||||
additional_move_line_filter=None,
|
||||
aml_model=None,
|
||||
):
|
||||
"""Query sums of debit and credit for all accounts and domains
|
||||
used in expressions.
|
||||
|
||||
This method must be executed after done_parsing().
|
||||
"""
|
||||
if not aml_model:
|
||||
aml_model = self.env["account.move.line"]
|
||||
else:
|
||||
aml_model = self.env[aml_model]
|
||||
aml_model = aml_model.with_context(active_test=False)
|
||||
company_rates = self._get_company_rates(date_to)
|
||||
# {(domain, mode): {account_id: (debit, credit)}}
|
||||
self._data = defaultdict(dict)
|
||||
domain_by_mode = {}
|
||||
ends = []
|
||||
for key in self._map_account_ids:
|
||||
domain, mode = key
|
||||
if mode == self.MODE_END and self.smart_end:
|
||||
# postpone computation of ending balance
|
||||
ends.append((domain, mode))
|
||||
continue
|
||||
if mode not in domain_by_mode:
|
||||
domain_by_mode[mode] = self.get_aml_domain_for_dates(
|
||||
date_from, date_to, mode
|
||||
)
|
||||
domain = list(domain) + domain_by_mode[mode]
|
||||
domain.append(("account_id", "in", self._map_account_ids[key]))
|
||||
if additional_move_line_filter:
|
||||
domain.extend(additional_move_line_filter)
|
||||
# fetch sum of debit/credit, grouped by account_id
|
||||
_logger.debug("read_group domain: %s", domain)
|
||||
try:
|
||||
accs = aml_model.read_group(
|
||||
domain,
|
||||
["debit", "credit", "account_id", "company_id"],
|
||||
["account_id", "company_id"],
|
||||
lazy=False,
|
||||
)
|
||||
except ValueError as e:
|
||||
raise UserError(
|
||||
_(
|
||||
'Error while querying move line source "%(model_name)s". '
|
||||
"This is likely due to a filter or expression referencing "
|
||||
"a field that does not exist in the model.\n\n"
|
||||
"The technical error message is: %(exception)s. "
|
||||
)
|
||||
% dict(
|
||||
model_name=aml_model._description,
|
||||
exception=e,
|
||||
)
|
||||
) from e
|
||||
for acc in accs:
|
||||
rate, dp = company_rates[acc["company_id"][0]]
|
||||
debit = acc["debit"] or 0.0
|
||||
credit = acc["credit"] or 0.0
|
||||
if mode in (self.MODE_INITIAL, self.MODE_UNALLOCATED) and float_is_zero(
|
||||
debit - credit, precision_digits=self.dp
|
||||
):
|
||||
# in initial mode, ignore accounts with 0 balance
|
||||
continue
|
||||
self._data[key][acc["account_id"][0]] = (debit * rate, credit * rate)
|
||||
# compute ending balances by summing initial and variation
|
||||
for key in ends:
|
||||
domain, mode = key
|
||||
initial_data = self._data[(domain, self.MODE_INITIAL)]
|
||||
variation_data = self._data[(domain, self.MODE_VARIATION)]
|
||||
account_ids = set(initial_data.keys()) | set(variation_data.keys())
|
||||
for account_id in account_ids:
|
||||
di, ci = initial_data.get(account_id, (AccountingNone, AccountingNone))
|
||||
dv, cv = variation_data.get(
|
||||
account_id, (AccountingNone, AccountingNone)
|
||||
)
|
||||
self._data[key][account_id] = (di + dv, ci + cv)
|
||||
|
||||
def replace_expr(self, expr):
|
||||
"""Replace accounting variables in an expression by their amount.
|
||||
|
||||
Returns a new expression string.
|
||||
|
||||
This method must be executed after do_queries().
|
||||
"""
|
||||
|
||||
def f(mo):
|
||||
field, mode, acc_domain, ml_domain = self._parse_match_object(mo)
|
||||
key = (ml_domain, mode)
|
||||
account_ids_data = self._data[key]
|
||||
v = AccountingNone
|
||||
account_ids = self._account_ids_by_acc_domain[acc_domain]
|
||||
for account_id in account_ids:
|
||||
debit, credit = account_ids_data.get(
|
||||
account_id, (AccountingNone, AccountingNone)
|
||||
)
|
||||
if field == "bal":
|
||||
v += debit - credit
|
||||
elif field == "pbal" and debit >= credit:
|
||||
v += debit - credit
|
||||
elif field == "nbal" and debit < credit:
|
||||
v += debit - credit
|
||||
elif field == "deb":
|
||||
v += debit
|
||||
elif field == "crd":
|
||||
v += credit
|
||||
# in initial balance mode, assume 0 is None
|
||||
# as it does not make sense to distinguish 0 from "no data"
|
||||
if (
|
||||
v is not AccountingNone
|
||||
and mode in (self.MODE_INITIAL, self.MODE_UNALLOCATED)
|
||||
and float_is_zero(v, precision_digits=self.dp)
|
||||
):
|
||||
v = AccountingNone
|
||||
return "(" + repr(v) + ")"
|
||||
|
||||
return self._ACC_RE.sub(f, expr)
|
||||
|
||||
def replace_exprs_by_account_id(self, exprs):
|
||||
"""Replace accounting variables in a list of expression
|
||||
by their amount, iterating by accounts involved in the expression.
|
||||
|
||||
yields account_id, replaced_expr
|
||||
|
||||
This method must be executed after do_queries().
|
||||
"""
|
||||
|
||||
def f(mo):
|
||||
field, mode, acc_domain, ml_domain = self._parse_match_object(mo)
|
||||
key = (ml_domain, mode)
|
||||
# first check if account_id is involved in
|
||||
# the current expression part
|
||||
if account_id not in self._account_ids_by_acc_domain[acc_domain]:
|
||||
return "(AccountingNone)"
|
||||
# here we know account_id is involved in acc_domain
|
||||
account_ids_data = self._data[key]
|
||||
debit, credit = account_ids_data.get(
|
||||
account_id, (AccountingNone, AccountingNone)
|
||||
)
|
||||
if field == "bal":
|
||||
v = debit - credit
|
||||
elif field == "pbal":
|
||||
if debit >= credit:
|
||||
v = debit - credit
|
||||
else:
|
||||
v = AccountingNone
|
||||
elif field == "nbal":
|
||||
if debit < credit:
|
||||
v = debit - credit
|
||||
else:
|
||||
v = AccountingNone
|
||||
elif field == "deb":
|
||||
v = debit
|
||||
elif field == "crd":
|
||||
v = credit
|
||||
# in initial balance mode, assume 0 is None
|
||||
# as it does not make sense to distinguish 0 from "no data"
|
||||
if (
|
||||
v is not AccountingNone
|
||||
and mode in (self.MODE_INITIAL, self.MODE_UNALLOCATED)
|
||||
and float_is_zero(v, precision_digits=self.dp)
|
||||
):
|
||||
v = AccountingNone
|
||||
return "(" + repr(v) + ")"
|
||||
|
||||
account_ids = set()
|
||||
for expr in exprs:
|
||||
for mo in self._ACC_RE.finditer(expr):
|
||||
field, mode, acc_domain, ml_domain = self._parse_match_object(mo)
|
||||
key = (ml_domain, mode)
|
||||
account_ids_data = self._data[key]
|
||||
for account_id in self._account_ids_by_acc_domain[acc_domain]:
|
||||
if account_id in account_ids_data:
|
||||
account_ids.add(account_id)
|
||||
|
||||
for account_id in account_ids:
|
||||
yield account_id, [self._ACC_RE.sub(f, expr) for expr in exprs]
|
||||
|
||||
@classmethod
|
||||
def _get_balances(cls, mode, companies, date_from, date_to):
|
||||
expr = f"deb{mode}[], crd{mode}[]"
|
||||
aep = AccountingExpressionProcessor(companies)
|
||||
# disable smart_end to have the data at once, instead
|
||||
# of initial + variation
|
||||
aep.smart_end = False
|
||||
aep.parse_expr(expr)
|
||||
aep.done_parsing()
|
||||
aep.do_queries(date_from, date_to)
|
||||
return aep._data[((), mode)]
|
||||
|
||||
@classmethod
|
||||
def get_balances_initial(cls, companies, date):
|
||||
"""A convenience method to obtain the initial balances of all accounts
|
||||
at a given date.
|
||||
|
||||
It is the same as get_balances_end(date-1).
|
||||
|
||||
:param companies:
|
||||
:param date:
|
||||
|
||||
Returns a dictionary: {account_id, (debit, credit)}
|
||||
"""
|
||||
return cls._get_balances(cls.MODE_INITIAL, companies, date, date)
|
||||
|
||||
@classmethod
|
||||
def get_balances_end(cls, companies, date):
|
||||
"""A convenience method to obtain the ending balances of all accounts
|
||||
at a given date.
|
||||
|
||||
It is the same as get_balances_initial(date+1).
|
||||
|
||||
:param companies:
|
||||
:param date:
|
||||
|
||||
Returns a dictionary: {account_id, (debit, credit)}
|
||||
"""
|
||||
return cls._get_balances(cls.MODE_END, companies, date, date)
|
||||
|
||||
@classmethod
|
||||
def get_balances_variation(cls, companies, date_from, date_to):
|
||||
"""A convenience method to obtain the variation of the
|
||||
balances of all accounts over a period.
|
||||
|
||||
:param companies:
|
||||
:param date:
|
||||
|
||||
Returns a dictionary: {account_id, (debit, credit)}
|
||||
"""
|
||||
return cls._get_balances(cls.MODE_VARIATION, companies, date_from, date_to)
|
||||
|
||||
@classmethod
|
||||
def get_unallocated_pl(cls, companies, date):
|
||||
"""A convenience method to obtain the unallocated profit/loss
|
||||
of the previous fiscal years at a given date.
|
||||
|
||||
:param companies:
|
||||
:param date:
|
||||
|
||||
Returns a tuple (debit, credit)
|
||||
"""
|
||||
# TODO shoud we include here the accounts of type "unaffected"
|
||||
# or leave that to the caller?
|
||||
bals = cls._get_balances(cls.MODE_UNALLOCATED, companies, date, date)
|
||||
return tuple(map(sum, zip(*bals.values(), strict=True)))
|
129
mis_builder/models/aggregate.py
Normal file
129
mis_builder/models/aggregate.py
Normal file
@ -0,0 +1,129 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
|
||||
def _sum(lst):
|
||||
"""Same as stdlib sum but returns None instead of 0
|
||||
in case of empty sequence.
|
||||
|
||||
>>> sum([1])
|
||||
1
|
||||
>>> _sum([1])
|
||||
1
|
||||
>>> sum([1, 2])
|
||||
3
|
||||
>>> _sum([1, 2])
|
||||
3
|
||||
>>> sum([])
|
||||
0
|
||||
>>> _sum([])
|
||||
"""
|
||||
if not lst:
|
||||
return None
|
||||
return sum(lst)
|
||||
|
||||
|
||||
def _avg(lst):
|
||||
"""Arithmetic mean of a sequence. Returns None in case of empty sequence.
|
||||
|
||||
>>> _avg([1])
|
||||
1.0
|
||||
>>> _avg([1, 2])
|
||||
1.5
|
||||
>>> _avg([])
|
||||
"""
|
||||
if not lst:
|
||||
return None
|
||||
return sum(lst) / float(len(lst))
|
||||
|
||||
|
||||
def _min(*args):
|
||||
"""Same as stdlib min but returns None instead of exception
|
||||
in case of empty sequence.
|
||||
|
||||
>>> min(1, 2)
|
||||
1
|
||||
>>> _min(1, 2)
|
||||
1
|
||||
>>> min([1, 2])
|
||||
1
|
||||
>>> _min([1, 2])
|
||||
1
|
||||
>>> min(1)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: 'int' object is not iterable
|
||||
>>> _min(1)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: 'int' object is not iterable
|
||||
>>> min([1])
|
||||
1
|
||||
>>> _min([1])
|
||||
1
|
||||
>>> min()
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: min expected 1 arguments, got 0
|
||||
>>> _min()
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: min expected 1 arguments, got 0
|
||||
>>> min([])
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
ValueError: min() arg is an empty sequence
|
||||
>>> _min([])
|
||||
"""
|
||||
if len(args) == 1 and not args[0]:
|
||||
return None
|
||||
return min(*args)
|
||||
|
||||
|
||||
def _max(*args):
|
||||
"""Same as stdlib max but returns None instead of exception
|
||||
in case of empty sequence.
|
||||
|
||||
>>> max(1, 2)
|
||||
2
|
||||
>>> _max(1, 2)
|
||||
2
|
||||
>>> max([1, 2])
|
||||
2
|
||||
>>> _max([1, 2])
|
||||
2
|
||||
>>> max(1)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: 'int' object is not iterable
|
||||
>>> _max(1)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: 'int' object is not iterable
|
||||
>>> max([1])
|
||||
1
|
||||
>>> _max([1])
|
||||
1
|
||||
>>> max()
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: max expected 1 arguments, got 0
|
||||
>>> _max()
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: max expected 1 arguments, got 0
|
||||
>>> max([])
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
ValueError: max() arg is an empty sequence
|
||||
>>> _max([])
|
||||
"""
|
||||
if len(args) == 1 and not args[0]:
|
||||
return None
|
||||
return max(*args)
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
17
mis_builder/models/data_error.py
Normal file
17
mis_builder/models/data_error.py
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# Copyright 2016 Akretion (<http://akretion.com>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
|
||||
class DataError(Exception):
|
||||
def __init__(self, name, msg):
|
||||
super().__init__()
|
||||
self.name = name
|
||||
self.msg = msg
|
||||
|
||||
def __repr__(self):
|
||||
return f"{self.__class__.__name__}({repr(self.name)})"
|
||||
|
||||
|
||||
class NameDataError(DataError):
|
||||
pass
|
68
mis_builder/models/expression_evaluator.py
Normal file
68
mis_builder/models/expression_evaluator.py
Normal file
@ -0,0 +1,68 @@
|
||||
# Copyright 2020 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from .mis_safe_eval import NameDataError, mis_safe_eval
|
||||
|
||||
|
||||
class ExpressionEvaluator:
|
||||
def __init__(
|
||||
self,
|
||||
aep,
|
||||
date_from,
|
||||
date_to,
|
||||
additional_move_line_filter=None,
|
||||
aml_model=None,
|
||||
):
|
||||
self.aep = aep
|
||||
self.date_from = date_from
|
||||
self.date_to = date_to
|
||||
self.additional_move_line_filter = additional_move_line_filter
|
||||
self.aml_model = aml_model
|
||||
self._aep_queries_done = False
|
||||
|
||||
def aep_do_queries(self):
|
||||
if self.aep and not self._aep_queries_done:
|
||||
self.aep.do_queries(
|
||||
self.date_from,
|
||||
self.date_to,
|
||||
self.additional_move_line_filter,
|
||||
self.aml_model,
|
||||
)
|
||||
self._aep_queries_done = True
|
||||
|
||||
def eval_expressions(self, expressions, locals_dict):
|
||||
vals = []
|
||||
drilldown_args = []
|
||||
name_error = False
|
||||
for expression in expressions:
|
||||
expr = expression and expression.name or "AccountingNone"
|
||||
if self.aep:
|
||||
replaced_expr = self.aep.replace_expr(expr)
|
||||
else:
|
||||
replaced_expr = expr
|
||||
val = mis_safe_eval(replaced_expr, locals_dict)
|
||||
vals.append(val)
|
||||
if isinstance(val, NameDataError):
|
||||
name_error = True
|
||||
if replaced_expr != expr:
|
||||
drilldown_args.append({"expr": expr})
|
||||
else:
|
||||
drilldown_args.append(None)
|
||||
return vals, drilldown_args, name_error
|
||||
|
||||
def eval_expressions_by_account(self, expressions, locals_dict):
|
||||
if not self.aep:
|
||||
return
|
||||
exprs = [e and e.name or "AccountingNone" for e in expressions]
|
||||
for account_id, replaced_exprs in self.aep.replace_exprs_by_account_id(exprs):
|
||||
vals = []
|
||||
drilldown_args = []
|
||||
name_error = False
|
||||
for expr, replaced_expr in zip(exprs, replaced_exprs, strict=True):
|
||||
val = mis_safe_eval(replaced_expr, locals_dict)
|
||||
vals.append(val)
|
||||
if replaced_expr != expr:
|
||||
drilldown_args.append({"expr": expr, "account_id": account_id})
|
||||
else:
|
||||
drilldown_args.append(None)
|
||||
yield account_id, vals, drilldown_args, name_error
|
542
mis_builder/models/kpimatrix.py
Normal file
542
mis_builder/models/kpimatrix.py
Normal file
@ -0,0 +1,542 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import logging
|
||||
from collections import OrderedDict, defaultdict
|
||||
|
||||
from flectra import _
|
||||
from flectra.exceptions import UserError
|
||||
|
||||
from .accounting_none import AccountingNone
|
||||
from .mis_kpi_data import ACC_SUM
|
||||
from .mis_safe_eval import DataError, mis_safe_eval
|
||||
from .simple_array import SimpleArray
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class KpiMatrixRow:
|
||||
# TODO: ultimately, the kpi matrix will become ignorant of KPI's and
|
||||
# accounts and know about rows, columns, sub columns and styles only.
|
||||
# It is already ignorant of period and only knowns about columns.
|
||||
# This will require a correct abstraction for expanding row details.
|
||||
|
||||
def __init__(self, matrix, kpi, account_id=None, parent_row=None):
|
||||
self._matrix = matrix
|
||||
self.kpi = kpi
|
||||
self.account_id = account_id
|
||||
self.description = ""
|
||||
self.parent_row = parent_row
|
||||
if not self.account_id:
|
||||
self.style_props = self._matrix._style_model.merge(
|
||||
[self.kpi.report_id.style_id, self.kpi.style_id]
|
||||
)
|
||||
else:
|
||||
self.style_props = self._matrix._style_model.merge(
|
||||
[self.kpi.report_id.style_id, self.kpi.auto_expand_accounts_style_id]
|
||||
)
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
if not self.account_id:
|
||||
return self.kpi.description
|
||||
else:
|
||||
return self._matrix.get_account_name(self.account_id)
|
||||
|
||||
@property
|
||||
def row_id(self):
|
||||
if not self.account_id:
|
||||
return self.kpi.name
|
||||
else:
|
||||
return f"{self.kpi.name}:{self.account_id}"
|
||||
|
||||
def iter_cell_tuples(self, cols=None):
|
||||
if cols is None:
|
||||
cols = self._matrix.iter_cols()
|
||||
for col in cols:
|
||||
yield col.get_cell_tuple_for_row(self)
|
||||
|
||||
def iter_cells(self, subcols=None):
|
||||
if subcols is None:
|
||||
subcols = self._matrix.iter_subcols()
|
||||
for subcol in subcols:
|
||||
yield subcol.get_cell_for_row(self)
|
||||
|
||||
def is_empty(self):
|
||||
for cell in self.iter_cells():
|
||||
if cell and cell.val not in (AccountingNone, None):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class KpiMatrixCol:
|
||||
def __init__(self, key, label, description, locals_dict, subkpis):
|
||||
self.key = key
|
||||
self.label = label
|
||||
self.description = description
|
||||
self.locals_dict = locals_dict
|
||||
self.colspan = subkpis and len(subkpis) or 1
|
||||
self._subcols = []
|
||||
self.subkpis = subkpis
|
||||
if not subkpis:
|
||||
subcol = KpiMatrixSubCol(self, "", "", 0)
|
||||
self._subcols.append(subcol)
|
||||
else:
|
||||
for i, subkpi in enumerate(subkpis):
|
||||
subcol = KpiMatrixSubCol(self, subkpi.description, "", i)
|
||||
self._subcols.append(subcol)
|
||||
self._cell_tuples_by_row = {} # {row: (cells tuple)}
|
||||
|
||||
def _set_cell_tuple(self, row, cell_tuple):
|
||||
self._cell_tuples_by_row[row] = cell_tuple
|
||||
|
||||
def iter_subcols(self):
|
||||
return self._subcols
|
||||
|
||||
def iter_cell_tuples(self):
|
||||
return self._cell_tuples_by_row.values()
|
||||
|
||||
def get_cell_tuple_for_row(self, row):
|
||||
return self._cell_tuples_by_row.get(row)
|
||||
|
||||
|
||||
class KpiMatrixSubCol:
|
||||
def __init__(self, col, label, description, index=0):
|
||||
self.col = col
|
||||
self.label = label
|
||||
self.description = description
|
||||
self.index = index
|
||||
|
||||
@property
|
||||
def subkpi(self):
|
||||
if self.col.subkpis:
|
||||
return self.col.subkpis[self.index]
|
||||
|
||||
def iter_cells(self):
|
||||
for cell_tuple in self.col.iter_cell_tuples():
|
||||
yield cell_tuple[self.index]
|
||||
|
||||
def get_cell_for_row(self, row):
|
||||
cell_tuple = self.col.get_cell_tuple_for_row(row)
|
||||
if cell_tuple is None:
|
||||
return None
|
||||
return cell_tuple[self.index]
|
||||
|
||||
|
||||
class KpiMatrixCell: # noqa: B903 (immutable data class)
|
||||
def __init__(
|
||||
self,
|
||||
row,
|
||||
subcol,
|
||||
val,
|
||||
val_rendered,
|
||||
val_comment,
|
||||
style_props,
|
||||
drilldown_arg,
|
||||
val_type,
|
||||
):
|
||||
self.row = row
|
||||
self.subcol = subcol
|
||||
self.val = val
|
||||
self.val_rendered = val_rendered
|
||||
self.val_comment = val_comment
|
||||
self.style_props = style_props
|
||||
self.drilldown_arg = drilldown_arg
|
||||
self.val_type = val_type
|
||||
|
||||
|
||||
class KpiMatrix:
|
||||
def __init__(self, env, multi_company=False, account_model="account.account"):
|
||||
# cache language id for faster rendering
|
||||
lang_model = env["res.lang"]
|
||||
self.lang = lang_model._lang_get(env.user.lang)
|
||||
self._style_model = env["mis.report.style"]
|
||||
self._account_model = env[account_model]
|
||||
# data structures
|
||||
# { kpi: KpiMatrixRow }
|
||||
self._kpi_rows = OrderedDict()
|
||||
# { kpi: {account_id: KpiMatrixRow} }
|
||||
self._detail_rows = {}
|
||||
# { col_key: KpiMatrixCol }
|
||||
self._cols = OrderedDict()
|
||||
# { col_key (left of comparison): [(col_key, base_col_key)] }
|
||||
self._comparison_todo = defaultdict(list)
|
||||
# { col_key (left of sum): (col_key, [(sign, sum_col_key)])
|
||||
self._sum_todo = {}
|
||||
# { account_id: account_name }
|
||||
self._account_names = {}
|
||||
self._multi_company = multi_company
|
||||
|
||||
def declare_kpi(self, kpi):
|
||||
"""Declare a new kpi (row) in the matrix.
|
||||
|
||||
Invoke this first for all kpi, in display order.
|
||||
"""
|
||||
self._kpi_rows[kpi] = KpiMatrixRow(self, kpi)
|
||||
self._detail_rows[kpi] = {}
|
||||
|
||||
def declare_col(self, col_key, label, description, locals_dict, subkpis):
|
||||
"""Declare a new column, giving it an identifier (key).
|
||||
|
||||
Invoke the declare_* methods in display order.
|
||||
"""
|
||||
col = KpiMatrixCol(col_key, label, description, locals_dict, subkpis)
|
||||
self._cols[col_key] = col
|
||||
return col
|
||||
|
||||
def declare_comparison(
|
||||
self, cmpcol_key, col_key, base_col_key, label, description=None
|
||||
):
|
||||
"""Declare a new comparison column.
|
||||
|
||||
Invoke the declare_* methods in display order.
|
||||
"""
|
||||
self._comparison_todo[cmpcol_key] = (col_key, base_col_key, label, description)
|
||||
self._cols[cmpcol_key] = None # reserve slot in insertion order
|
||||
|
||||
def declare_sum(
|
||||
self, sumcol_key, col_to_sum_keys, label, description=None, sum_accdet=False
|
||||
):
|
||||
"""Declare a new summation column.
|
||||
|
||||
Invoke the declare_* methods in display order.
|
||||
:param col_to_sum_keys: [(sign, col_key)]
|
||||
"""
|
||||
self._sum_todo[sumcol_key] = (col_to_sum_keys, label, description, sum_accdet)
|
||||
self._cols[sumcol_key] = None # reserve slot in insertion order
|
||||
|
||||
def set_values(self, kpi, col_key, vals, drilldown_args, tooltips=True):
|
||||
"""Set values for a kpi and a colum.
|
||||
|
||||
Invoke this after declaring the kpi and the column.
|
||||
"""
|
||||
self.set_values_detail_account(
|
||||
kpi, col_key, None, vals, drilldown_args, tooltips
|
||||
)
|
||||
|
||||
def set_values_detail_account(
|
||||
self, kpi, col_key, account_id, vals, drilldown_args, tooltips=True
|
||||
):
|
||||
"""Set values for a kpi and a column and a detail account.
|
||||
|
||||
Invoke this after declaring the kpi and the column.
|
||||
"""
|
||||
if not account_id:
|
||||
row = self._kpi_rows[kpi]
|
||||
else:
|
||||
kpi_row = self._kpi_rows[kpi]
|
||||
if account_id in self._detail_rows[kpi]:
|
||||
row = self._detail_rows[kpi][account_id]
|
||||
else:
|
||||
row = KpiMatrixRow(self, kpi, account_id, parent_row=kpi_row)
|
||||
self._detail_rows[kpi][account_id] = row
|
||||
col = self._cols[col_key]
|
||||
cell_tuple = []
|
||||
assert len(vals) == col.colspan
|
||||
assert len(drilldown_args) == col.colspan
|
||||
for val, drilldown_arg, subcol in zip(
|
||||
vals, drilldown_args, col.iter_subcols(), strict=True
|
||||
):
|
||||
if isinstance(val, DataError):
|
||||
val_rendered = val.name
|
||||
val_comment = val.msg
|
||||
else:
|
||||
val_rendered = self._style_model.render(
|
||||
self.lang, row.style_props, kpi.type, val
|
||||
)
|
||||
if row.kpi.multi and subcol.subkpi:
|
||||
val_comment = "{}.{} = {}".format(
|
||||
row.kpi.name,
|
||||
subcol.subkpi.name,
|
||||
row.kpi._get_expression_str_for_subkpi(subcol.subkpi),
|
||||
)
|
||||
else:
|
||||
val_comment = f"{row.kpi.name} = {row.kpi.expression}"
|
||||
cell_style_props = row.style_props
|
||||
if row.kpi.style_expression:
|
||||
# evaluate style expression
|
||||
try:
|
||||
style_name = mis_safe_eval(
|
||||
row.kpi.style_expression, col.locals_dict
|
||||
)
|
||||
except Exception:
|
||||
_logger.error(
|
||||
"Error evaluating style expression <%s>",
|
||||
row.kpi.style_expression,
|
||||
exc_info=True,
|
||||
)
|
||||
if style_name:
|
||||
style = self._style_model.search([("name", "=", style_name)])
|
||||
if style:
|
||||
cell_style_props = self._style_model.merge(
|
||||
[row.style_props, style[0]]
|
||||
)
|
||||
else:
|
||||
_logger.error("Style '%s' not found.", style_name)
|
||||
cell = KpiMatrixCell(
|
||||
row,
|
||||
subcol,
|
||||
val,
|
||||
val_rendered,
|
||||
tooltips and val_comment or None,
|
||||
cell_style_props,
|
||||
drilldown_arg,
|
||||
kpi.type,
|
||||
)
|
||||
cell_tuple.append(cell)
|
||||
assert len(cell_tuple) == col.colspan
|
||||
col._set_cell_tuple(row, cell_tuple)
|
||||
|
||||
def _common_subkpis(self, cols):
|
||||
if not cols:
|
||||
return set()
|
||||
common_subkpis = set(cols[0].subkpis)
|
||||
for col in cols[1:]:
|
||||
common_subkpis = common_subkpis & set(col.subkpis)
|
||||
return common_subkpis
|
||||
|
||||
def compute_comparisons(self):
|
||||
"""Compute comparisons.
|
||||
|
||||
Invoke this after setting all values.
|
||||
"""
|
||||
for (
|
||||
cmpcol_key,
|
||||
(col_key, base_col_key, label, description),
|
||||
) in self._comparison_todo.items():
|
||||
col = self._cols[col_key]
|
||||
base_col = self._cols[base_col_key]
|
||||
common_subkpis = self._common_subkpis([col, base_col])
|
||||
if (col.subkpis or base_col.subkpis) and not common_subkpis:
|
||||
raise UserError(
|
||||
_(
|
||||
"Columns %(descr)s and %(base_descr)s are not comparable",
|
||||
descr=col.description,
|
||||
base_descr=base_col.description,
|
||||
)
|
||||
)
|
||||
if not label:
|
||||
label = f"{col.label} vs {base_col.label}"
|
||||
comparison_col = KpiMatrixCol(
|
||||
cmpcol_key,
|
||||
label,
|
||||
description,
|
||||
{},
|
||||
sorted(common_subkpis, key=lambda s: s.sequence),
|
||||
)
|
||||
self._cols[cmpcol_key] = comparison_col
|
||||
for row in self.iter_rows():
|
||||
cell_tuple = col.get_cell_tuple_for_row(row)
|
||||
base_cell_tuple = base_col.get_cell_tuple_for_row(row)
|
||||
if cell_tuple is None and base_cell_tuple is None:
|
||||
continue
|
||||
if cell_tuple is None:
|
||||
vals = [AccountingNone] * (len(common_subkpis) or 1)
|
||||
else:
|
||||
vals = [
|
||||
cell.val
|
||||
for cell in cell_tuple
|
||||
if not common_subkpis or cell.subcol.subkpi in common_subkpis
|
||||
]
|
||||
if base_cell_tuple is None:
|
||||
base_vals = [AccountingNone] * (len(common_subkpis) or 1)
|
||||
else:
|
||||
base_vals = [
|
||||
cell.val
|
||||
for cell in base_cell_tuple
|
||||
if not common_subkpis or cell.subcol.subkpi in common_subkpis
|
||||
]
|
||||
comparison_cell_tuple = []
|
||||
for val, base_val, comparison_subcol in zip(
|
||||
vals,
|
||||
base_vals,
|
||||
comparison_col.iter_subcols(),
|
||||
strict=True,
|
||||
):
|
||||
# TODO FIXME average factors
|
||||
comparison = self._style_model.compare_and_render(
|
||||
self.lang,
|
||||
row.style_props,
|
||||
row.kpi.type,
|
||||
row.kpi.compare_method,
|
||||
val,
|
||||
base_val,
|
||||
1,
|
||||
1,
|
||||
)
|
||||
delta, delta_r, delta_style, delta_type = comparison
|
||||
comparison_cell_tuple.append(
|
||||
KpiMatrixCell(
|
||||
row,
|
||||
comparison_subcol,
|
||||
delta,
|
||||
delta_r,
|
||||
None,
|
||||
delta_style,
|
||||
None,
|
||||
delta_type,
|
||||
)
|
||||
)
|
||||
comparison_col._set_cell_tuple(row, comparison_cell_tuple)
|
||||
|
||||
def compute_sums(self):
|
||||
"""Compute comparisons.
|
||||
|
||||
Invoke this after setting all values.
|
||||
"""
|
||||
for (
|
||||
sumcol_key,
|
||||
(col_to_sum_keys, label, description, sum_accdet),
|
||||
) in self._sum_todo.items():
|
||||
sumcols = [self._cols[k] for (sign, k) in col_to_sum_keys]
|
||||
# TODO check all sumcols are resolved; we need a kind of
|
||||
# recompute queue here so we don't depend on insertion
|
||||
# order
|
||||
common_subkpis = self._common_subkpis(sumcols)
|
||||
if any(c.subkpis for c in sumcols) and not common_subkpis:
|
||||
raise UserError(
|
||||
_(
|
||||
"Sum cannot be computed in column {} "
|
||||
"because the columns to sum have no "
|
||||
"common subkpis"
|
||||
).format(label)
|
||||
)
|
||||
sum_col = KpiMatrixCol(
|
||||
sumcol_key,
|
||||
label,
|
||||
description,
|
||||
{},
|
||||
sorted(common_subkpis, key=lambda s: s.sequence),
|
||||
)
|
||||
self._cols[sumcol_key] = sum_col
|
||||
for row in self.iter_rows():
|
||||
acc = SimpleArray([AccountingNone] * (len(common_subkpis) or 1))
|
||||
if row.kpi.accumulation_method == ACC_SUM and not (
|
||||
row.account_id and not sum_accdet
|
||||
):
|
||||
for sign, col_to_sum in col_to_sum_keys:
|
||||
cell_tuple = self._cols[col_to_sum].get_cell_tuple_for_row(row)
|
||||
if cell_tuple is None:
|
||||
vals = [AccountingNone] * (len(common_subkpis) or 1)
|
||||
else:
|
||||
vals = [
|
||||
cell.val
|
||||
for cell in cell_tuple
|
||||
if not common_subkpis
|
||||
or cell.subcol.subkpi in common_subkpis
|
||||
]
|
||||
if sign == "+":
|
||||
acc += SimpleArray(vals)
|
||||
else:
|
||||
acc -= SimpleArray(vals)
|
||||
self.set_values_detail_account(
|
||||
row.kpi,
|
||||
sumcol_key,
|
||||
row.account_id,
|
||||
acc,
|
||||
[None] * (len(common_subkpis) or 1),
|
||||
tooltips=False,
|
||||
)
|
||||
|
||||
def iter_rows(self):
|
||||
"""Iterate rows in display order.
|
||||
|
||||
yields KpiMatrixRow.
|
||||
"""
|
||||
for kpi_row in self._kpi_rows.values():
|
||||
yield kpi_row
|
||||
detail_rows = self._detail_rows[kpi_row.kpi].values()
|
||||
detail_rows = sorted(detail_rows, key=lambda r: r.label)
|
||||
yield from detail_rows
|
||||
|
||||
def iter_cols(self):
|
||||
"""Iterate columns in display order.
|
||||
|
||||
yields KpiMatrixCol: one for each column or comparison.
|
||||
"""
|
||||
for _col_key, col in self._cols.items():
|
||||
yield col
|
||||
|
||||
def iter_subcols(self):
|
||||
"""Iterate sub columns in display order.
|
||||
|
||||
yields KpiMatrixSubCol: one for each subkpi in each column
|
||||
and comparison.
|
||||
"""
|
||||
for col in self.iter_cols():
|
||||
yield from col.iter_subcols()
|
||||
|
||||
def _load_account_names(self):
|
||||
account_ids = set()
|
||||
for detail_rows in self._detail_rows.values():
|
||||
account_ids.update(detail_rows.keys())
|
||||
accounts = self._account_model.search([("id", "in", list(account_ids))])
|
||||
self._account_names = {a.id: self._get_account_name(a) for a in accounts}
|
||||
|
||||
def _get_account_name(self, account):
|
||||
result = f"{account.code} {account.name}"
|
||||
if self._multi_company:
|
||||
result = f"{result} [{account.company_id.name}]"
|
||||
return result
|
||||
|
||||
def get_account_name(self, account_id):
|
||||
if account_id not in self._account_names:
|
||||
self._load_account_names()
|
||||
return self._account_names[account_id]
|
||||
|
||||
def as_dict(self):
|
||||
header = [{"cols": []}, {"cols": []}]
|
||||
for col in self.iter_cols():
|
||||
header[0]["cols"].append(
|
||||
{
|
||||
"label": col.label,
|
||||
"description": col.description,
|
||||
"colspan": col.colspan,
|
||||
}
|
||||
)
|
||||
for subcol in col.iter_subcols():
|
||||
header[1]["cols"].append(
|
||||
{
|
||||
"label": subcol.label,
|
||||
"description": subcol.description,
|
||||
"colspan": 1,
|
||||
}
|
||||
)
|
||||
|
||||
body = []
|
||||
for row in self.iter_rows():
|
||||
if (
|
||||
row.style_props.hide_empty and row.is_empty()
|
||||
) or row.style_props.hide_always:
|
||||
continue
|
||||
row_data = {
|
||||
"row_id": row.row_id,
|
||||
"parent_row_id": (row.parent_row and row.parent_row.row_id or None),
|
||||
"label": row.label,
|
||||
"description": row.description,
|
||||
"style": self._style_model.to_css_style(row.style_props),
|
||||
"cells": [],
|
||||
}
|
||||
for cell in row.iter_cells():
|
||||
if cell is None:
|
||||
# TODO use subcol style here
|
||||
row_data["cells"].append({})
|
||||
else:
|
||||
if cell.val is AccountingNone or isinstance(cell.val, DataError):
|
||||
val = None
|
||||
else:
|
||||
val = cell.val
|
||||
col_data = {
|
||||
"val": val,
|
||||
"val_r": cell.val_rendered,
|
||||
"val_c": cell.val_comment,
|
||||
"style": self._style_model.to_css_style(
|
||||
cell.style_props, no_indent=True
|
||||
),
|
||||
}
|
||||
if cell.drilldown_arg:
|
||||
col_data["drilldown_arg"] = cell.drilldown_arg
|
||||
row_data["cells"].append(col_data)
|
||||
body.append(row_data)
|
||||
|
||||
return {"header": header, "body": body}
|
115
mis_builder/models/mis_kpi_data.py
Normal file
115
mis_builder/models/mis_kpi_data.py
Normal file
@ -0,0 +1,115 @@
|
||||
# Copyright 2017 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
from flectra import _, api, fields, models
|
||||
from flectra.exceptions import UserError
|
||||
from flectra.osv import expression
|
||||
|
||||
ACC_SUM = "sum"
|
||||
ACC_AVG = "avg"
|
||||
ACC_NONE = "none"
|
||||
|
||||
|
||||
def intersect_days(item_dt_from, item_dt_to, dt_from, dt_to):
|
||||
item_days = (item_dt_to - item_dt_from).days + 1.0
|
||||
i_dt_from = max(dt_from, item_dt_from)
|
||||
i_dt_to = min(dt_to, item_dt_to)
|
||||
i_days = (i_dt_to - i_dt_from).days + 1.0
|
||||
return i_days, item_days
|
||||
|
||||
|
||||
class MisKpiData(models.AbstractModel):
|
||||
"""Abstract class for manually entered KPI values."""
|
||||
|
||||
_name = "mis.kpi.data"
|
||||
_description = "MIS Kpi Data Abtract class"
|
||||
|
||||
name = fields.Char(compute="_compute_name", required=False, readonly=True)
|
||||
kpi_expression_id = fields.Many2one(
|
||||
comodel_name="mis.report.kpi.expression",
|
||||
required=True,
|
||||
ondelete="restrict",
|
||||
string="KPI",
|
||||
)
|
||||
date_from = fields.Date(required=True, string="From")
|
||||
date_to = fields.Date(required=True, string="To")
|
||||
amount = fields.Float()
|
||||
seq1 = fields.Integer(
|
||||
related="kpi_expression_id.kpi_id.sequence",
|
||||
store=True,
|
||||
readonly=True,
|
||||
string="KPI Sequence",
|
||||
)
|
||||
seq2 = fields.Integer(
|
||||
related="kpi_expression_id.subkpi_id.sequence",
|
||||
store=True,
|
||||
readonly=True,
|
||||
string="Sub-KPI Sequence",
|
||||
)
|
||||
|
||||
@api.depends(
|
||||
"kpi_expression_id.subkpi_id.name",
|
||||
"kpi_expression_id.kpi_id.name",
|
||||
"date_from",
|
||||
"date_to",
|
||||
)
|
||||
def _compute_name(self):
|
||||
for rec in self:
|
||||
subkpi_name = rec.kpi_expression_id.subkpi_id.name
|
||||
if subkpi_name:
|
||||
subkpi_name = "." + subkpi_name
|
||||
else:
|
||||
subkpi_name = ""
|
||||
rec.name = "{}{}: {} - {}".format(
|
||||
rec.kpi_expression_id.kpi_id.name,
|
||||
subkpi_name,
|
||||
rec.date_from,
|
||||
rec.date_to,
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _intersect_days(self, item_dt_from, item_dt_to, dt_from, dt_to):
|
||||
return intersect_days(item_dt_from, item_dt_to, dt_from, dt_to)
|
||||
|
||||
@api.model
|
||||
def _query_kpi_data(self, date_from, date_to, base_domain):
|
||||
"""Query mis.kpi.data over a time period.
|
||||
|
||||
Returns {mis.report.kpi.expression: amount}
|
||||
"""
|
||||
dt_from = fields.Date.from_string(date_from)
|
||||
dt_to = fields.Date.from_string(date_to)
|
||||
# all data items within or overlapping [date_from, date_to]
|
||||
date_domain = [("date_from", "<=", date_to), ("date_to", ">=", date_from)]
|
||||
domain = expression.AND([date_domain, base_domain])
|
||||
res = defaultdict(float)
|
||||
res_avg = defaultdict(list)
|
||||
for item in self.search(domain):
|
||||
item_dt_from = fields.Date.from_string(item.date_from)
|
||||
item_dt_to = fields.Date.from_string(item.date_to)
|
||||
i_days, item_days = self._intersect_days(
|
||||
item_dt_from, item_dt_to, dt_from, dt_to
|
||||
)
|
||||
if item.kpi_expression_id.kpi_id.accumulation_method == ACC_SUM:
|
||||
# accumulate pro-rata overlap between item and reporting period
|
||||
res[item.kpi_expression_id] += item.amount * i_days / item_days
|
||||
elif item.kpi_expression_id.kpi_id.accumulation_method == ACC_AVG:
|
||||
# memorize the amount and number of days overlapping
|
||||
# the reporting period (used as weight in average)
|
||||
res_avg[item.kpi_expression_id].append((i_days, item.amount))
|
||||
else:
|
||||
raise UserError(
|
||||
_(
|
||||
"Unexpected accumulation method %(method)s for %(name)s.",
|
||||
method=item.kpi_expression_id.kpi_id.accumulation_method,
|
||||
name=item.name,
|
||||
)
|
||||
)
|
||||
# compute weighted average for ACC_AVG
|
||||
for kpi_expression, amounts in res_avg.items():
|
||||
res[kpi_expression] = sum(d * a for d, a in amounts) / sum(
|
||||
d for d, a in amounts
|
||||
)
|
||||
return res
|
1015
mis_builder/models/mis_report.py
Normal file
1015
mis_builder/models/mis_report.py
Normal file
File diff suppressed because it is too large
Load Diff
922
mis_builder/models/mis_report_instance.py
Normal file
922
mis_builder/models/mis_report_instance.py
Normal file
@ -0,0 +1,922 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# Copyright 2020 CorporateHub (https://corporatehub.eu)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import ast
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from flectra import _, api, fields, models
|
||||
from flectra.exceptions import UserError, ValidationError
|
||||
|
||||
from .aep import AccountingExpressionProcessor as AEP
|
||||
from .expression_evaluator import ExpressionEvaluator
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
SRC_ACTUALS = "actuals"
|
||||
SRC_ACTUALS_ALT = "actuals_alt"
|
||||
SRC_CMPCOL = "cmpcol"
|
||||
SRC_SUMCOL = "sumcol"
|
||||
|
||||
MODE_NONE = "none"
|
||||
MODE_FIX = "fix"
|
||||
MODE_REL = "relative"
|
||||
|
||||
|
||||
class DateFilterRequired(ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class DateFilterForbidden(ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class MisReportInstancePeriodSum(models.Model):
|
||||
_name = "mis.report.instance.period.sum"
|
||||
_description = "MIS Report Instance Period Sum"
|
||||
|
||||
period_id = fields.Many2one(
|
||||
comodel_name="mis.report.instance.period",
|
||||
string="Parent column",
|
||||
ondelete="cascade",
|
||||
required=True,
|
||||
)
|
||||
period_to_sum_id = fields.Many2one(
|
||||
comodel_name="mis.report.instance.period",
|
||||
string="Column",
|
||||
ondelete="restrict",
|
||||
required=True,
|
||||
)
|
||||
sign = fields.Selection([("+", "+"), ("-", "-")], required=True, default="+")
|
||||
|
||||
@api.constrains("period_id", "period_to_sum_id")
|
||||
def _check_period_to_sum(self):
|
||||
for rec in self:
|
||||
if rec.period_id == rec.period_to_sum_id:
|
||||
raise ValidationError(
|
||||
_("You cannot sum period %s with itself.") % rec.period_id.name
|
||||
)
|
||||
|
||||
|
||||
class MisReportInstancePeriod(models.Model):
|
||||
"""A MIS report instance has the logic to compute
|
||||
a report template for a given date period.
|
||||
|
||||
Periods have a duration (day, week, fiscal period) and
|
||||
are defined as an offset relative to a pivot date.
|
||||
"""
|
||||
|
||||
@api.depends(
|
||||
"report_instance_id.pivot_date",
|
||||
"report_instance_id.comparison_mode",
|
||||
"date_range_type_id",
|
||||
"type",
|
||||
"offset",
|
||||
"duration",
|
||||
"mode",
|
||||
"manual_date_from",
|
||||
"manual_date_to",
|
||||
"is_ytd",
|
||||
)
|
||||
def _compute_dates(self):
|
||||
for record in self:
|
||||
record.date_from = False
|
||||
record.date_to = False
|
||||
record.valid = False
|
||||
report = record.report_instance_id
|
||||
d = fields.Date.from_string(report.pivot_date)
|
||||
if not report.comparison_mode:
|
||||
record.date_from = report.date_from
|
||||
record.date_to = report.date_to
|
||||
record.valid = record.date_from and record.date_to
|
||||
elif record.mode == MODE_NONE:
|
||||
record.date_from = False
|
||||
record.date_to = False
|
||||
record.valid = True
|
||||
elif record.mode == MODE_FIX:
|
||||
record.date_from = record.manual_date_from
|
||||
record.date_to = record.manual_date_to
|
||||
record.valid = record.date_from and record.date_to
|
||||
elif record.mode == MODE_REL and record.type == "d":
|
||||
date_from = d + datetime.timedelta(days=record.offset)
|
||||
date_to = date_from + datetime.timedelta(days=record.duration - 1)
|
||||
record.date_from = fields.Date.to_string(date_from)
|
||||
record.date_to = fields.Date.to_string(date_to)
|
||||
record.valid = True
|
||||
elif record.mode == MODE_REL and record.type == "w":
|
||||
date_from = d - datetime.timedelta(d.weekday())
|
||||
date_from = date_from + datetime.timedelta(days=record.offset * 7)
|
||||
date_to = date_from + datetime.timedelta(days=(7 * record.duration) - 1)
|
||||
record.date_from = fields.Date.to_string(date_from)
|
||||
record.date_to = fields.Date.to_string(date_to)
|
||||
record.valid = True
|
||||
elif record.mode == MODE_REL and record.type == "m":
|
||||
date_from = d.replace(day=1)
|
||||
date_from = date_from + relativedelta(months=record.offset)
|
||||
date_to = (
|
||||
date_from
|
||||
+ relativedelta(months=record.duration - 1)
|
||||
+ relativedelta(day=31)
|
||||
)
|
||||
record.date_from = fields.Date.to_string(date_from)
|
||||
record.date_to = fields.Date.to_string(date_to)
|
||||
record.valid = True
|
||||
elif record.mode == MODE_REL and record.type == "y":
|
||||
date_from = d.replace(month=1, day=1)
|
||||
date_from = date_from + relativedelta(years=record.offset)
|
||||
date_to = date_from + relativedelta(years=record.duration - 1)
|
||||
date_to = date_to.replace(month=12, day=31)
|
||||
record.date_from = fields.Date.to_string(date_from)
|
||||
record.date_to = fields.Date.to_string(date_to)
|
||||
record.valid = True
|
||||
elif record.mode == MODE_REL and record.type == "date_range":
|
||||
date_range_obj = record.env["date.range"]
|
||||
current_periods = date_range_obj.search(
|
||||
[
|
||||
("type_id", "=", record.date_range_type_id.id),
|
||||
("date_start", "<=", d),
|
||||
("date_end", ">=", d),
|
||||
"|",
|
||||
("company_id", "=", False),
|
||||
(
|
||||
"company_id",
|
||||
"in",
|
||||
record.report_instance_id.query_company_ids.ids,
|
||||
),
|
||||
]
|
||||
)
|
||||
if current_periods:
|
||||
# TODO we take the first date range we found as current
|
||||
# this may be surprising if several companies
|
||||
# have overlapping date ranges with different dates
|
||||
current_period = current_periods[0]
|
||||
all_periods = date_range_obj.search(
|
||||
[
|
||||
("type_id", "=", current_period.type_id.id),
|
||||
("company_id", "=", current_period.company_id.id),
|
||||
],
|
||||
order="date_start",
|
||||
)
|
||||
p = all_periods.ids.index(current_period.id) + record.offset
|
||||
if p >= 0 and p + record.duration <= len(all_periods):
|
||||
periods = all_periods[p : p + record.duration]
|
||||
record.date_from = periods[0].date_start
|
||||
record.date_to = periods[-1].date_end
|
||||
record.valid = True
|
||||
if record.mode == MODE_REL and record.valid and record.is_ytd:
|
||||
record.date_from = fields.Date.from_string(record.date_to).replace(
|
||||
day=1, month=1
|
||||
)
|
||||
|
||||
_name = "mis.report.instance.period"
|
||||
_description = "MIS Report Instance Period"
|
||||
|
||||
name = fields.Char(required=True, string="Label", translate=True)
|
||||
mode = fields.Selection(
|
||||
[
|
||||
(MODE_FIX, "Fixed dates"),
|
||||
(MODE_REL, "Relative to report base date"),
|
||||
(MODE_NONE, "No date filter"),
|
||||
],
|
||||
required=True,
|
||||
default=MODE_FIX,
|
||||
)
|
||||
type = fields.Selection(
|
||||
[
|
||||
("d", _("Day")),
|
||||
("w", _("Week")),
|
||||
("m", _("Month")),
|
||||
("y", _("Year")),
|
||||
("date_range", _("Date Range")),
|
||||
],
|
||||
string="Period type",
|
||||
)
|
||||
is_ytd = fields.Boolean(
|
||||
default=False,
|
||||
string="Year to date",
|
||||
help="Forces the start date to Jan 1st of the relevant year",
|
||||
)
|
||||
date_range_type_id = fields.Many2one(
|
||||
comodel_name="date.range.type",
|
||||
string="Date Range Type",
|
||||
domain=[("allow_overlap", "=", False)],
|
||||
)
|
||||
offset = fields.Integer(help="Offset from current period", default=-1)
|
||||
duration = fields.Integer(help="Number of periods", default=1)
|
||||
date_from = fields.Date(compute="_compute_dates", string="From (computed)")
|
||||
date_to = fields.Date(compute="_compute_dates", string="To (computed)")
|
||||
manual_date_from = fields.Date(string="From")
|
||||
manual_date_to = fields.Date(string="To")
|
||||
date_range_id = fields.Many2one(comodel_name="date.range", string="Date Range")
|
||||
valid = fields.Boolean(compute="_compute_dates", type="boolean")
|
||||
sequence = fields.Integer(default=100)
|
||||
report_instance_id = fields.Many2one(
|
||||
comodel_name="mis.report.instance",
|
||||
string="Report Instance",
|
||||
required=True,
|
||||
ondelete="cascade",
|
||||
)
|
||||
report_id = fields.Many2one(related="report_instance_id.report_id")
|
||||
normalize_factor = fields.Integer(
|
||||
string="Factor",
|
||||
help="Factor to use to normalize the period (used in comparison",
|
||||
default=1,
|
||||
)
|
||||
subkpi_ids = fields.Many2many("mis.report.subkpi", string="Sub KPI Filter")
|
||||
|
||||
source = fields.Selection(
|
||||
[
|
||||
(SRC_ACTUALS, "Actuals"),
|
||||
(SRC_ACTUALS_ALT, "Actuals (alternative)"),
|
||||
(SRC_SUMCOL, "Sum columns"),
|
||||
(SRC_CMPCOL, "Compare columns"),
|
||||
],
|
||||
default=SRC_ACTUALS,
|
||||
required=True,
|
||||
help="Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an "
|
||||
"alternative source (eg a database view providing look-alike "
|
||||
"account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n",
|
||||
)
|
||||
source_aml_model_id = fields.Many2one(
|
||||
comodel_name="ir.model",
|
||||
string="Move lines source",
|
||||
domain=[
|
||||
("field_id.name", "=", "debit"),
|
||||
("field_id.name", "=", "credit"),
|
||||
("field_id.name", "=", "account_id"),
|
||||
("field_id.name", "=", "date"),
|
||||
("field_id.name", "=", "company_id"),
|
||||
("field_id.model_id.model", "!=", "account.move.line"),
|
||||
],
|
||||
compute="_compute_source_aml_model_id",
|
||||
store=True,
|
||||
readonly=False,
|
||||
help="A 'move line like' model, ie having at least debit, credit, "
|
||||
"date, account_id and company_id fields.",
|
||||
)
|
||||
source_aml_model_name = fields.Char(
|
||||
string="Move lines source model name", related="source_aml_model_id.model"
|
||||
)
|
||||
source_sumcol_ids = fields.One2many(
|
||||
comodel_name="mis.report.instance.period.sum",
|
||||
inverse_name="period_id",
|
||||
string="Columns to sum",
|
||||
)
|
||||
source_sumcol_accdet = fields.Boolean(string="Sum account details")
|
||||
source_cmpcol_from_id = fields.Many2one(
|
||||
comodel_name="mis.report.instance.period", string="versus"
|
||||
)
|
||||
source_cmpcol_to_id = fields.Many2one(
|
||||
comodel_name="mis.report.instance.period", string="Compare"
|
||||
)
|
||||
allowed_cmpcol_ids = fields.Many2many(
|
||||
comodel_name="mis.report.instance.period", compute="_compute_allowed_cmpcol_ids"
|
||||
)
|
||||
analytic_domain = fields.Text(
|
||||
default="[]",
|
||||
help="A domain to additionally filter move lines considered in this column.",
|
||||
)
|
||||
|
||||
_order = "sequence, id"
|
||||
|
||||
_sql_constraints = [
|
||||
("duration", "CHECK (duration>0)", "Wrong duration, it must be positive!"),
|
||||
(
|
||||
"normalize_factor",
|
||||
"CHECK (normalize_factor>0)",
|
||||
"Wrong normalize factor, it must be positive!",
|
||||
),
|
||||
(
|
||||
"name_unique",
|
||||
"unique(name, report_instance_id)",
|
||||
"Period name should be unique by report",
|
||||
),
|
||||
]
|
||||
|
||||
@api.depends("source", "report_instance_id.report_id.move_lines_source")
|
||||
def _compute_source_aml_model_id(self):
|
||||
for record in self:
|
||||
if record.source == SRC_ACTUALS:
|
||||
if not record.report_instance_id.report_id:
|
||||
raise UserError(
|
||||
_(
|
||||
"Please select a report template and/or "
|
||||
"save the report before adding columns."
|
||||
)
|
||||
)
|
||||
# use the default model defined on the report template
|
||||
record.source_aml_model_id = (
|
||||
record.report_instance_id.report_id.move_lines_source
|
||||
)
|
||||
elif record.source in (SRC_SUMCOL, SRC_CMPCOL):
|
||||
record.source_aml_model_id = False
|
||||
elif record.source == SRC_ACTUALS_ALT:
|
||||
pass # let the user choose
|
||||
|
||||
@api.depends("report_instance_id")
|
||||
def _compute_allowed_cmpcol_ids(self):
|
||||
"""Compute actual records while in NewId context"""
|
||||
for record in self:
|
||||
record.allowed_cmpcol_ids = record.report_instance_id.period_ids - record
|
||||
|
||||
@api.constrains("source_aml_model_id")
|
||||
def _check_source_aml_model_id(self):
|
||||
for record in self:
|
||||
if record.source_aml_model_id:
|
||||
record_model = record.source_aml_model_id.field_id.filtered(
|
||||
lambda r: r.name == "account_id"
|
||||
).relation
|
||||
report_account_model = record.report_id.account_model
|
||||
if record_model != report_account_model:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"Actual (alternative) models used in columns must "
|
||||
"have the same account model in the Account field and must "
|
||||
"be the same defined in the "
|
||||
"report template: %s"
|
||||
)
|
||||
% report_account_model
|
||||
)
|
||||
|
||||
@api.onchange("date_range_id")
|
||||
def _onchange_date_range(self):
|
||||
if self.date_range_id:
|
||||
self.manual_date_from = self.date_range_id.date_start
|
||||
self.manual_date_to = self.date_range_id.date_end
|
||||
|
||||
@api.onchange("manual_date_from", "manual_date_to")
|
||||
def _onchange_dates(self):
|
||||
if self.date_range_id:
|
||||
if (
|
||||
self.manual_date_from != self.date_range_id.date_start
|
||||
or self.manual_date_to != self.date_range_id.date_end
|
||||
):
|
||||
self.date_range_id = False
|
||||
|
||||
@api.onchange("source")
|
||||
def _onchange_source(self):
|
||||
if self.source in (SRC_SUMCOL, SRC_CMPCOL):
|
||||
self.mode = MODE_NONE
|
||||
# Dirty hack to solve bug https://github.com/OCA/mis-builder/issues/393
|
||||
if self.source and not self.report_instance_id.id:
|
||||
self.report_instance_id = self.report_instance_id._origin.id
|
||||
|
||||
def _get_additional_move_line_filter(self):
|
||||
"""Prepare a filter to apply on all move lines
|
||||
|
||||
This filter will be applied with a AND operator on all accounting expression
|
||||
domains. This hook is intended to be inherited, and is useful to implement
|
||||
filtering on analytic dimensions or operational units.
|
||||
|
||||
The default filter is obtained from the report-instance-level
|
||||
``_get_filter_domain`` method, extended with a per column analytic domain.
|
||||
|
||||
Returns an Flectra domain expression (a python list) compatible with
|
||||
account.move.line.
|
||||
"""
|
||||
self.ensure_one()
|
||||
if not self.source_aml_model_name:
|
||||
# This column does not have a move line source, so this additional move line
|
||||
# filter does not apply
|
||||
return []
|
||||
# First get the report-level filter domain.
|
||||
domain = self.report_instance_id._get_filter_domain(self.source_aml_model_name)
|
||||
if self.analytic_domain:
|
||||
# Then extend it with the column-level analytic domain.
|
||||
domain.extend(ast.literal_eval(self.analytic_domain))
|
||||
return domain
|
||||
|
||||
def _get_additional_query_filter(self, query):
|
||||
"""Prepare an additional filter to apply on the query
|
||||
|
||||
This filter is combined to the query domain with a AND
|
||||
operator. This hook is intended
|
||||
to be inherited, and is useful to implement filtering
|
||||
on analytic dimensions or operational units.
|
||||
|
||||
Returns an Flectra domain expression (a python list)
|
||||
compatible with the model of the query."""
|
||||
self.ensure_one()
|
||||
return []
|
||||
|
||||
@api.constrains("mode", "source")
|
||||
def _check_mode_source(self):
|
||||
for rec in self:
|
||||
if rec.source in (SRC_ACTUALS, SRC_ACTUALS_ALT):
|
||||
if rec.mode == MODE_NONE:
|
||||
raise DateFilterRequired(
|
||||
_("A date filter is mandatory for this source " "in column %s.")
|
||||
% rec.name
|
||||
)
|
||||
elif rec.source in (SRC_SUMCOL, SRC_CMPCOL):
|
||||
if rec.mode != MODE_NONE:
|
||||
raise DateFilterForbidden(
|
||||
_("No date filter is allowed for this source " "in column %s.")
|
||||
% rec.name
|
||||
)
|
||||
|
||||
@api.constrains("source", "source_cmpcol_from_id", "source_cmpcol_to_id")
|
||||
def _check_source_cmpcol(self):
|
||||
for rec in self:
|
||||
if rec.source == SRC_CMPCOL:
|
||||
if not rec.source_cmpcol_from_id or not rec.source_cmpcol_to_id:
|
||||
raise ValidationError(
|
||||
_("Please provide both columns to compare in %s.") % rec.name
|
||||
)
|
||||
if rec.source_cmpcol_from_id == rec or rec.source_cmpcol_to_id == rec:
|
||||
raise ValidationError(
|
||||
_("Column %s cannot be compared to itrec.") % rec.name
|
||||
)
|
||||
if (
|
||||
rec.source_cmpcol_from_id.report_instance_id
|
||||
!= rec.report_instance_id
|
||||
or rec.source_cmpcol_to_id.report_instance_id
|
||||
!= rec.report_instance_id
|
||||
):
|
||||
raise ValidationError(
|
||||
_("Columns to compare must belong to the same report " "in %s")
|
||||
% rec.name
|
||||
)
|
||||
|
||||
def copy_data(self, default=None):
|
||||
if self.source == SRC_CMPCOL:
|
||||
# While duplicating a MIS report instance, comparison columns are
|
||||
# ignored because they would raise an error, as they keep the old
|
||||
# `source_cmpcol_from_id` and `source_cmpcol_to_id` from the
|
||||
# original record.
|
||||
return [
|
||||
False,
|
||||
]
|
||||
return super().copy_data(default=default)
|
||||
|
||||
|
||||
class MisReportInstance(models.Model):
|
||||
"""The MIS report instance combines everything to compute
|
||||
a MIS report template for a set of periods."""
|
||||
|
||||
@api.depends("date")
|
||||
def _compute_pivot_date(self):
|
||||
for record in self:
|
||||
if self.env.context.get("mis_pivot_date"):
|
||||
record.pivot_date = self.env.context.get("mis_pivot_date")
|
||||
elif record.date:
|
||||
record.pivot_date = record.date
|
||||
else:
|
||||
record.pivot_date = fields.Date.context_today(record)
|
||||
|
||||
_name = "mis.report.instance"
|
||||
_description = "MIS Report Instance"
|
||||
|
||||
name = fields.Char(required=True, translate=True)
|
||||
description = fields.Char(related="report_id.description", readonly=True)
|
||||
date = fields.Date(
|
||||
string="Base date", help="Report base date " "(leave empty to use current date)"
|
||||
)
|
||||
pivot_date = fields.Date(compute="_compute_pivot_date")
|
||||
report_id = fields.Many2one("mis.report", required=True, string="Report")
|
||||
period_ids = fields.One2many(
|
||||
comodel_name="mis.report.instance.period",
|
||||
inverse_name="report_instance_id",
|
||||
required=True,
|
||||
string="Periods",
|
||||
copy=True,
|
||||
)
|
||||
target_move = fields.Selection(
|
||||
[("posted", "All Posted Entries"), ("all", "All Entries")],
|
||||
string="Target Moves",
|
||||
required=True,
|
||||
default="posted",
|
||||
)
|
||||
company_id = fields.Many2one(
|
||||
comodel_name="res.company",
|
||||
string="Allowed company",
|
||||
default=lambda self: self.env.company,
|
||||
required=False,
|
||||
)
|
||||
multi_company = fields.Boolean(
|
||||
string="Multiple companies",
|
||||
help="Check if you wish to specify several companies to be searched for data.",
|
||||
default=False,
|
||||
)
|
||||
company_ids = fields.Many2many(
|
||||
comodel_name="res.company",
|
||||
string="Allowed companies",
|
||||
help="Select companies for which data will be searched.",
|
||||
)
|
||||
query_company_ids = fields.Many2many(
|
||||
string="Effective companies",
|
||||
comodel_name="res.company",
|
||||
compute="_compute_query_company_ids",
|
||||
help="Companies for which data will be searched.",
|
||||
)
|
||||
currency_id = fields.Many2one(
|
||||
comodel_name="res.currency",
|
||||
string="Currency",
|
||||
help="Select target currency for the report. "
|
||||
"Required if companies have different currencies.",
|
||||
required=False,
|
||||
)
|
||||
landscape_pdf = fields.Boolean(string="Landscape PDF")
|
||||
no_auto_expand_accounts = fields.Boolean(string="Disable account details expansion")
|
||||
display_columns_description = fields.Boolean(
|
||||
help="Display the date range details in the column headers."
|
||||
)
|
||||
comparison_mode = fields.Boolean(
|
||||
compute="_compute_comparison_mode", inverse="_inverse_comparison_mode"
|
||||
)
|
||||
date_range_id = fields.Many2one(comodel_name="date.range", string="Date Range")
|
||||
date_from = fields.Date(string="From")
|
||||
date_to = fields.Date(string="To")
|
||||
temporary = fields.Boolean(default=False)
|
||||
source_aml_model_id = fields.Many2one(
|
||||
related="report_id.move_lines_source",
|
||||
readonly=True,
|
||||
)
|
||||
source_aml_model_name = fields.Char(
|
||||
related="source_aml_model_id.model",
|
||||
related_sudo=True,
|
||||
readonly=True,
|
||||
)
|
||||
analytic_domain = fields.Text(
|
||||
default="[]",
|
||||
help=(
|
||||
"A domain to additionally filter move lines considered in this report. "
|
||||
"Caution: when using different move line sources in different columns, "
|
||||
"such as budgets by account, "
|
||||
"make sure to use only fields that are available in "
|
||||
"all move line sources."
|
||||
),
|
||||
)
|
||||
widget_show_filters = fields.Boolean(
|
||||
default=True,
|
||||
string="Show filters box",
|
||||
help="Show the filter bar in the report widget.",
|
||||
)
|
||||
widget_show_settings_button = fields.Boolean(
|
||||
default=False,
|
||||
string="Show settings button",
|
||||
help="Show the settings button in the report widget.",
|
||||
)
|
||||
widget_show_pivot_date = fields.Boolean(
|
||||
default=False,
|
||||
string="Show Pivot Date",
|
||||
help="Show the Pivot Date in the report widget filter bar.",
|
||||
)
|
||||
widget_search_view_id = fields.Many2one(
|
||||
comodel_name="ir.ui.view",
|
||||
domain='[("type", "=", "search"), ("model", "=", source_aml_model_name)]',
|
||||
compute="_compute_widget_search_view_id",
|
||||
store=True,
|
||||
readonly=False,
|
||||
string="Filter box search view",
|
||||
help="Search view to customize the filter box in the report widget.",
|
||||
)
|
||||
|
||||
@api.depends("report_id.move_lines_source")
|
||||
def _compute_widget_search_view_id(self):
|
||||
for rec in self:
|
||||
rec.widget_search_view_id = (
|
||||
self.env["ir.ui.view"]
|
||||
.sudo()
|
||||
.search(
|
||||
[
|
||||
("type", "=", "search"),
|
||||
("model", "=", rec.report_id.move_lines_source.model),
|
||||
],
|
||||
limit=1,
|
||||
)
|
||||
)
|
||||
|
||||
@api.onchange("multi_company")
|
||||
def _onchange_company(self):
|
||||
if self.multi_company:
|
||||
self.company_ids |= self.company_id
|
||||
self.company_id = False
|
||||
else:
|
||||
prev = self.company_ids.ids
|
||||
company = False
|
||||
if self.env.company.id in prev or not prev:
|
||||
company = self.env.company
|
||||
else:
|
||||
for c_id in prev:
|
||||
if c_id in self.env.companies.ids:
|
||||
company = self.env["res.company"].browse(c_id)
|
||||
break
|
||||
|
||||
self.company_id = company
|
||||
self.company_ids = False
|
||||
|
||||
@api.depends("multi_company", "company_id", "company_ids")
|
||||
@api.depends_context("allowed_company_ids")
|
||||
def _compute_query_company_ids(self):
|
||||
for rec in self:
|
||||
if rec.multi_company:
|
||||
if not rec.company_ids:
|
||||
rec.query_company_ids = self.env.companies
|
||||
else:
|
||||
rec.query_company_ids = rec.company_ids & self.env.companies
|
||||
else:
|
||||
rec.query_company_ids = rec.company_id or self.env.company
|
||||
|
||||
@api.model
|
||||
def get_filter_descriptions(self):
|
||||
return []
|
||||
|
||||
def save_report(self):
|
||||
self.ensure_one()
|
||||
self.write({"temporary": False})
|
||||
xmlid = "mis_builder.mis_report_instance_view_action"
|
||||
action = self.env["ir.actions.act_window"]._for_xml_id(xmlid)
|
||||
view = self.env.ref("mis_builder.mis_report_instance_view_form")
|
||||
action.update({"views": [(view.id, "form")], "res_id": self.id})
|
||||
return action
|
||||
|
||||
@api.model
|
||||
def _vacuum_report(self, hours=24):
|
||||
clear_date = fields.Datetime.to_string(
|
||||
datetime.datetime.now() - datetime.timedelta(hours=hours)
|
||||
)
|
||||
reports = self.search(
|
||||
[("write_date", "<", clear_date), ("temporary", "=", True)]
|
||||
)
|
||||
_logger.debug("Vacuum %s Temporary MIS Builder Report", len(reports))
|
||||
return reports.unlink()
|
||||
|
||||
def copy(self, default=None):
|
||||
self.ensure_one()
|
||||
default = dict(default or {})
|
||||
default["name"] = _("%s (copy)") % self.name
|
||||
return super().copy(default)
|
||||
|
||||
def _format_date(self, date):
|
||||
# format date following user language
|
||||
lang_model = self.env["res.lang"]
|
||||
lang = lang_model._lang_get(self.env.user.lang)
|
||||
date_format = lang.date_format
|
||||
return datetime.datetime.strftime(fields.Date.from_string(date), date_format)
|
||||
|
||||
@api.depends("date_from")
|
||||
def _compute_comparison_mode(self):
|
||||
for instance in self:
|
||||
instance.comparison_mode = bool(instance.period_ids) and not bool(
|
||||
instance.date_from
|
||||
)
|
||||
|
||||
def _inverse_comparison_mode(self):
|
||||
for record in self:
|
||||
if not record.comparison_mode:
|
||||
if not record.date_from:
|
||||
record.date_from = fields.Date.context_today(self)
|
||||
if not record.date_to:
|
||||
record.date_to = fields.Date.context_today(self)
|
||||
record.period_ids.unlink()
|
||||
record.write({"period_ids": [(0, 0, {"name": "Default"})]})
|
||||
else:
|
||||
record.date_from = None
|
||||
record.date_to = None
|
||||
|
||||
@api.onchange("date_range_id")
|
||||
def _onchange_date_range(self):
|
||||
if self.date_range_id:
|
||||
self.date_from = self.date_range_id.date_start
|
||||
self.date_to = self.date_range_id.date_end
|
||||
|
||||
@api.onchange("date_from", "date_to")
|
||||
def _onchange_dates(self):
|
||||
if self.date_range_id:
|
||||
if (
|
||||
self.date_from != self.date_range_id.date_start
|
||||
or self.date_to != self.date_range_id.date_end
|
||||
):
|
||||
self.date_range_id = False
|
||||
|
||||
def _add_analytic_filters_to_context(self, context):
|
||||
self.ensure_one()
|
||||
context["mis_analytic_domain"] = ast.literal_eval(self.analytic_domain)
|
||||
|
||||
def _get_filter_domain(self, source_aml_model_name):
|
||||
"""Return the domain to filter the source move lines.
|
||||
|
||||
It combines
|
||||
- the draft/posted filter (if the move line source has a parent_state
|
||||
field).
|
||||
- the analytic domain field configured on this report instance
|
||||
- a mis_analytic_domain obtained from the context (typically populated
|
||||
by the mis builder widget)
|
||||
"""
|
||||
domain = []
|
||||
# draft/posted filter
|
||||
domain.extend(
|
||||
self.report_id._get_target_move_domain(
|
||||
self.target_move, source_aml_model_name
|
||||
)
|
||||
)
|
||||
# report-level analytic domain filter
|
||||
domain.extend(ast.literal_eval(self.analytic_domain))
|
||||
# contextual analytic domain filter
|
||||
domain.extend(self.env.context.get("mis_analytic_domain", []))
|
||||
return domain
|
||||
|
||||
@api.model
|
||||
def get_views(self, views, options=None):
|
||||
"""
|
||||
Override to get correct form view on dashboard
|
||||
"""
|
||||
context = self.env.context
|
||||
if (
|
||||
context.get("from_dashboard")
|
||||
and context.get("active_model") == "mis.report.instance"
|
||||
):
|
||||
view_id = self.env.ref(
|
||||
"mis_builder." "mis_report_instance_result_view_form"
|
||||
)
|
||||
mis_report_form_view = view_id and [view_id.id, "form"]
|
||||
for view in views:
|
||||
if view and view[1] == "form":
|
||||
views.remove(view)
|
||||
views.append(mis_report_form_view)
|
||||
result = super().get_views(views, options)
|
||||
return result
|
||||
|
||||
def preview(self):
|
||||
self.ensure_one()
|
||||
view_id = self.env.ref("mis_builder." "mis_report_instance_result_view_form")
|
||||
return {
|
||||
"type": "ir.actions.act_window",
|
||||
"res_model": "mis.report.instance",
|
||||
"res_id": self.id,
|
||||
"view_mode": "form",
|
||||
"view_id": view_id.id,
|
||||
"target": "current",
|
||||
"context": self.env.context,
|
||||
}
|
||||
|
||||
def print_pdf(self):
|
||||
self.ensure_one()
|
||||
return (
|
||||
self.env.ref("mis_builder.qweb_pdf_export")
|
||||
.with_context(landscape=self.landscape_pdf)
|
||||
.report_action(self, data=dict(dummy=True)) # required to propagate context
|
||||
)
|
||||
|
||||
def export_xls(self):
|
||||
self.ensure_one()
|
||||
return self.env.ref("mis_builder.xls_export").report_action(
|
||||
self, data=dict(dummy=True)
|
||||
) # required to propagate context
|
||||
|
||||
def display_settings(self):
|
||||
assert len(self.ids) <= 1
|
||||
view_id = self.env.ref("mis_builder.mis_report_instance_view_form")
|
||||
return {
|
||||
"type": "ir.actions.act_window",
|
||||
"res_model": "mis.report.instance",
|
||||
"res_id": self.id if self.id else False,
|
||||
"view_mode": "form",
|
||||
"views": [(view_id.id, "form")],
|
||||
"view_id": view_id.id,
|
||||
"target": "current",
|
||||
}
|
||||
|
||||
def _add_column_move_lines(self, aep, kpi_matrix, period, label, description):
|
||||
if not period.date_from or not period.date_to:
|
||||
raise UserError(
|
||||
_("Column %s with move lines source must have from/to dates.")
|
||||
% (period.name,)
|
||||
)
|
||||
expression_evaluator = ExpressionEvaluator(
|
||||
aep,
|
||||
period.date_from,
|
||||
period.date_to,
|
||||
period._get_additional_move_line_filter(),
|
||||
period.source_aml_model_name,
|
||||
)
|
||||
self.report_id._declare_and_compute_period(
|
||||
expression_evaluator,
|
||||
kpi_matrix,
|
||||
period.id,
|
||||
label,
|
||||
description,
|
||||
period.subkpi_ids,
|
||||
period._get_additional_query_filter,
|
||||
no_auto_expand_accounts=self.no_auto_expand_accounts,
|
||||
)
|
||||
|
||||
def _add_column_sumcol(self, aep, kpi_matrix, period, label, description):
|
||||
kpi_matrix.declare_sum(
|
||||
period.id,
|
||||
[(c.sign, c.period_to_sum_id.id) for c in period.source_sumcol_ids],
|
||||
label,
|
||||
description,
|
||||
period.source_sumcol_accdet,
|
||||
)
|
||||
|
||||
def _add_column_cmpcol(self, aep, kpi_matrix, period, label, description):
|
||||
kpi_matrix.declare_comparison(
|
||||
period.id,
|
||||
period.source_cmpcol_to_id.id,
|
||||
period.source_cmpcol_from_id.id,
|
||||
label,
|
||||
description,
|
||||
)
|
||||
|
||||
def _add_column(self, aep, kpi_matrix, period, label, description):
|
||||
if period.source == SRC_ACTUALS:
|
||||
return self._add_column_move_lines(
|
||||
aep, kpi_matrix, period, label, description
|
||||
)
|
||||
elif period.source == SRC_ACTUALS_ALT:
|
||||
return self._add_column_move_lines(
|
||||
aep, kpi_matrix, period, label, description
|
||||
)
|
||||
elif period.source == SRC_SUMCOL:
|
||||
return self._add_column_sumcol(aep, kpi_matrix, period, label, description)
|
||||
elif period.source == SRC_CMPCOL:
|
||||
return self._add_column_cmpcol(aep, kpi_matrix, period, label, description)
|
||||
|
||||
def _compute_matrix(self):
|
||||
"""Compute a report and return a KpiMatrix.
|
||||
|
||||
The key attribute of the matrix columns (KpiMatrixCol)
|
||||
is guaranteed to be the id of the mis.report.instance.period.
|
||||
"""
|
||||
self.ensure_one()
|
||||
aep = self.report_id._prepare_aep(self.query_company_ids, self.currency_id)
|
||||
kpi_matrix = self.report_id.prepare_kpi_matrix(self.multi_company)
|
||||
for period in self.period_ids:
|
||||
description = None
|
||||
if period.mode == MODE_NONE:
|
||||
pass
|
||||
elif not self.display_columns_description:
|
||||
pass
|
||||
elif period.date_from == period.date_to and period.date_from:
|
||||
description = self._format_date(period.date_from)
|
||||
elif period.date_from and period.date_to:
|
||||
date_from = self._format_date(period.date_from)
|
||||
date_to = self._format_date(period.date_to)
|
||||
description = _(
|
||||
"from %(date_from)s to %(date_to)s",
|
||||
date_from=date_from,
|
||||
date_to=date_to,
|
||||
)
|
||||
self._add_column(aep, kpi_matrix, period, period.name, description)
|
||||
kpi_matrix.compute_comparisons()
|
||||
kpi_matrix.compute_sums()
|
||||
return kpi_matrix
|
||||
|
||||
def compute(self):
|
||||
self.ensure_one()
|
||||
kpi_matrix = self._compute_matrix()
|
||||
return kpi_matrix.as_dict()
|
||||
|
||||
def drilldown(self, arg):
|
||||
self.ensure_one()
|
||||
period_id = arg.get("period_id")
|
||||
expr = arg.get("expr")
|
||||
account_id = arg.get("account_id")
|
||||
if period_id and expr and AEP.has_account_var(expr):
|
||||
period = self.env["mis.report.instance.period"].browse(period_id)
|
||||
aep = AEP(
|
||||
self.query_company_ids, self.currency_id, self.report_id.account_model
|
||||
)
|
||||
aep.parse_expr(expr)
|
||||
aep.done_parsing()
|
||||
domain = aep.get_aml_domain_for_expr(
|
||||
expr,
|
||||
period.date_from,
|
||||
period.date_to,
|
||||
account_id,
|
||||
)
|
||||
domain.extend(period._get_additional_move_line_filter())
|
||||
return {
|
||||
"name": self._get_drilldown_action_name(arg),
|
||||
"domain": domain,
|
||||
"type": "ir.actions.act_window",
|
||||
"res_model": period.source_aml_model_name,
|
||||
"views": [[False, "list"], [False, "form"]],
|
||||
"view_mode": "list",
|
||||
"target": "current",
|
||||
"context": {"active_test": False},
|
||||
}
|
||||
else:
|
||||
return False
|
||||
|
||||
def _get_drilldown_action_name(self, arg):
|
||||
kpi_id = arg.get("kpi_id")
|
||||
kpi = self.env["mis.report.kpi"].browse(kpi_id)
|
||||
period_id = arg.get("period_id")
|
||||
period = self.env["mis.report.instance.period"].browse(period_id)
|
||||
account_id = arg.get("account_id")
|
||||
|
||||
if account_id:
|
||||
account = self.env[self.report_id.account_model].browse(account_id)
|
||||
return f"{kpi.description} - {account.display_name} - {period.display_name}"
|
||||
else:
|
||||
return f"{kpi.description} - {period.display_name}"
|
311
mis_builder/models/mis_report_style.py
Normal file
311
mis_builder/models/mis_report_style.py
Normal file
@ -0,0 +1,311 @@
|
||||
# Copyright 2016 Therp BV (<http://therp.nl>)
|
||||
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# Copyright 2020 CorporateHub (https://corporatehub.eu)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import sys
|
||||
|
||||
from flectra import _, api, fields, models
|
||||
from flectra.exceptions import ValidationError
|
||||
|
||||
from .accounting_none import AccountingNone
|
||||
from .data_error import DataError
|
||||
|
||||
if sys.version_info.major >= 3:
|
||||
unicode = str
|
||||
|
||||
|
||||
class PropertyDict(dict):
|
||||
def __getattr__(self, name):
|
||||
return self.get(name)
|
||||
|
||||
def copy(self): # pylint: disable=copy-wo-api-one,method-required-super
|
||||
return PropertyDict(self)
|
||||
|
||||
|
||||
PROPS = [
|
||||
"color",
|
||||
"background_color",
|
||||
"font_style",
|
||||
"font_weight",
|
||||
"font_size",
|
||||
"indent_level",
|
||||
"prefix",
|
||||
"suffix",
|
||||
"dp",
|
||||
"divider",
|
||||
"hide_empty",
|
||||
"hide_always",
|
||||
]
|
||||
|
||||
TYPE_NUM = "num"
|
||||
TYPE_PCT = "pct"
|
||||
TYPE_STR = "str"
|
||||
|
||||
CMP_DIFF = "diff"
|
||||
CMP_PCT = "pct"
|
||||
CMP_NONE = "none"
|
||||
|
||||
|
||||
class MisReportKpiStyle(models.Model):
|
||||
_name = "mis.report.style"
|
||||
_description = "MIS Report Style"
|
||||
|
||||
@api.constrains("indent_level")
|
||||
def check_positive_val(self):
|
||||
for record in self:
|
||||
if record.indent_level < 0:
|
||||
raise ValidationError(
|
||||
_("Indent level must be greater than " "or equal to 0")
|
||||
)
|
||||
|
||||
_font_style_selection = [("normal", "Normal"), ("italic", "Italic")]
|
||||
|
||||
_font_weight_selection = [("nornal", "Normal"), ("bold", "Bold")]
|
||||
|
||||
_font_size_selection = [
|
||||
("medium", "medium"),
|
||||
("xx-small", "xx-small"),
|
||||
("x-small", "x-small"),
|
||||
("small", "small"),
|
||||
("large", "large"),
|
||||
("x-large", "x-large"),
|
||||
("xx-large", "xx-large"),
|
||||
]
|
||||
|
||||
_font_size_to_xlsx_size = {
|
||||
"medium": 11,
|
||||
"xx-small": 5,
|
||||
"x-small": 7,
|
||||
"small": 9,
|
||||
"large": 13,
|
||||
"x-large": 15,
|
||||
"xx-large": 17,
|
||||
}
|
||||
|
||||
# style name
|
||||
# TODO enforce uniqueness
|
||||
name = fields.Char(string="Style name", required=True)
|
||||
|
||||
# color
|
||||
color_inherit = fields.Boolean(default=True)
|
||||
color = fields.Char(
|
||||
string="Text color",
|
||||
help="Text color in valid RGB code (from #000000 to #FFFFFF)",
|
||||
default="#000000",
|
||||
)
|
||||
background_color_inherit = fields.Boolean(default=True)
|
||||
background_color = fields.Char(
|
||||
help="Background color in valid RGB code (from #000000 to #FFFFFF)",
|
||||
default="#FFFFFF",
|
||||
)
|
||||
# font
|
||||
font_style_inherit = fields.Boolean(default=True)
|
||||
font_style = fields.Selection(selection=_font_style_selection)
|
||||
font_weight_inherit = fields.Boolean(default=True)
|
||||
font_weight = fields.Selection(selection=_font_weight_selection)
|
||||
font_size_inherit = fields.Boolean(default=True)
|
||||
font_size = fields.Selection(selection=_font_size_selection)
|
||||
# indent
|
||||
indent_level_inherit = fields.Boolean(default=True)
|
||||
indent_level = fields.Integer()
|
||||
# number format
|
||||
prefix_inherit = fields.Boolean(default=True)
|
||||
prefix = fields.Char()
|
||||
suffix_inherit = fields.Boolean(default=True)
|
||||
suffix = fields.Char()
|
||||
dp_inherit = fields.Boolean(default=True)
|
||||
dp = fields.Integer(string="Rounding", default=0)
|
||||
divider_inherit = fields.Boolean(default=True)
|
||||
divider = fields.Selection(
|
||||
[
|
||||
("1e-6", _("µ")),
|
||||
("1e-3", _("m")),
|
||||
("1", _("1")),
|
||||
("1e3", _("k")),
|
||||
("1e6", _("M")),
|
||||
],
|
||||
string="Factor",
|
||||
default="1",
|
||||
)
|
||||
hide_empty_inherit = fields.Boolean(default=True)
|
||||
hide_empty = fields.Boolean(default=False)
|
||||
hide_always_inherit = fields.Boolean(default=True)
|
||||
hide_always = fields.Boolean(default=False)
|
||||
|
||||
@api.model
|
||||
def merge(self, styles):
|
||||
"""Merge several styles, giving priority to the last.
|
||||
|
||||
Returns a PropertyDict of style properties.
|
||||
"""
|
||||
r = PropertyDict()
|
||||
for style in styles:
|
||||
if not style:
|
||||
continue
|
||||
if isinstance(style, dict):
|
||||
r.update(style)
|
||||
else:
|
||||
for prop in PROPS:
|
||||
inherit = getattr(style, prop + "_inherit", None)
|
||||
if not inherit:
|
||||
value = getattr(style, prop)
|
||||
r[prop] = value
|
||||
return r
|
||||
|
||||
@api.model
|
||||
def render(self, lang, style_props, var_type, value, sign="-"):
|
||||
if var_type == TYPE_NUM:
|
||||
return self.render_num(
|
||||
lang,
|
||||
value,
|
||||
style_props.divider,
|
||||
style_props.dp,
|
||||
style_props.prefix,
|
||||
style_props.suffix,
|
||||
sign=sign,
|
||||
)
|
||||
elif var_type == TYPE_PCT:
|
||||
return self.render_pct(lang, value, style_props.dp, sign=sign)
|
||||
else:
|
||||
return self.render_str(lang, value)
|
||||
|
||||
@api.model
|
||||
def render_num(
|
||||
self, lang, value, divider=1.0, dp=0, prefix=None, suffix=None, sign="-"
|
||||
):
|
||||
# format number following user language
|
||||
if value is None or value is AccountingNone:
|
||||
return ""
|
||||
value = round(value / float(divider or 1), dp or 0) or 0
|
||||
r = lang.format("%%%s.%df" % (sign, dp or 0), value, grouping=True)
|
||||
r = r.replace("-", "\N{NON-BREAKING HYPHEN}")
|
||||
if prefix:
|
||||
r = prefix + "\N{NO-BREAK SPACE}" + r
|
||||
if suffix:
|
||||
r = r + "\N{NO-BREAK SPACE}" + suffix
|
||||
return r
|
||||
|
||||
@api.model
|
||||
def render_pct(self, lang, value, dp=1, sign="-"):
|
||||
return self.render_num(lang, value, divider=0.01, dp=dp, suffix="%", sign=sign)
|
||||
|
||||
@api.model
|
||||
def render_str(self, lang, value):
|
||||
if value is None or value is AccountingNone:
|
||||
return ""
|
||||
return unicode(value)
|
||||
|
||||
@api.model
|
||||
def compare_and_render(
|
||||
self,
|
||||
lang,
|
||||
style_props,
|
||||
var_type,
|
||||
compare_method,
|
||||
value,
|
||||
base_value,
|
||||
average_value=1,
|
||||
average_base_value=1,
|
||||
):
|
||||
"""
|
||||
:param lang: res.lang record
|
||||
:param style_props: PropertyDict with style properties
|
||||
:param var_type: num, pct or str
|
||||
:param compare_method: diff, pct, none
|
||||
:param value: value to compare (value - base_value)
|
||||
:param base_value: value compared with (value - base_value)
|
||||
:param average_value: value = value / average_value
|
||||
:param average_base_value: base_value = base_value / average_base_value
|
||||
:return: tuple with 4 elements
|
||||
- delta = comparison result (Float or AccountingNone)
|
||||
- delta_r = delta rendered in formatted string (String)
|
||||
- delta_style = PropertyDict with style properties
|
||||
- delta_type = Type of the comparison result (num or pct)
|
||||
"""
|
||||
delta = AccountingNone
|
||||
delta_r = ""
|
||||
delta_style = style_props.copy()
|
||||
delta_type = TYPE_NUM
|
||||
if isinstance(value, DataError) or isinstance(base_value, DataError):
|
||||
return AccountingNone, "", delta_style, delta_type
|
||||
if value is None:
|
||||
value = AccountingNone
|
||||
if base_value is None:
|
||||
base_value = AccountingNone
|
||||
if var_type == TYPE_PCT:
|
||||
delta = value - base_value
|
||||
if delta and round(delta, (style_props.dp or 0) + 2) != 0:
|
||||
delta_style.update(divider=0.01, prefix="", suffix=_("pp"))
|
||||
else:
|
||||
delta = AccountingNone
|
||||
elif var_type == TYPE_NUM:
|
||||
if value and average_value:
|
||||
# pylint: disable=redefined-variable-type
|
||||
value = value / float(average_value)
|
||||
if base_value and average_base_value:
|
||||
# pylint: disable=redefined-variable-type
|
||||
base_value = base_value / float(average_base_value)
|
||||
if compare_method == CMP_DIFF:
|
||||
delta = value - base_value
|
||||
if delta and round(delta, style_props.dp or 0) != 0:
|
||||
pass
|
||||
else:
|
||||
delta = AccountingNone
|
||||
elif compare_method == CMP_PCT:
|
||||
if base_value and round(base_value, style_props.dp or 0) != 0:
|
||||
delta = (value - base_value) / abs(base_value)
|
||||
if delta and round(delta, 3) != 0:
|
||||
delta_style.update(dp=1)
|
||||
delta_type = TYPE_PCT
|
||||
else:
|
||||
delta = AccountingNone
|
||||
if delta is not AccountingNone:
|
||||
delta_r = self.render(lang, delta_style, delta_type, delta, sign="+")
|
||||
return delta, delta_r, delta_style, delta_type
|
||||
|
||||
@api.model
|
||||
def to_xlsx_style(self, var_type, props, no_indent=False):
|
||||
xlsx_attributes = [
|
||||
("italic", props.font_style == "italic"),
|
||||
("bold", props.font_weight == "bold"),
|
||||
("size", self._font_size_to_xlsx_size.get(props.font_size, 11)),
|
||||
("font_color", props.color),
|
||||
("bg_color", props.background_color),
|
||||
]
|
||||
if var_type == TYPE_NUM:
|
||||
num_format = "#,##0"
|
||||
if props.dp:
|
||||
num_format += "."
|
||||
num_format += "0" * props.dp
|
||||
if props.prefix:
|
||||
num_format = f'"{props.prefix} "{num_format}'
|
||||
if props.suffix:
|
||||
num_format = f'{num_format}" {props.suffix}"'
|
||||
xlsx_attributes.append(("num_format", num_format))
|
||||
elif var_type == TYPE_PCT:
|
||||
num_format = "0"
|
||||
if props.dp:
|
||||
num_format += "."
|
||||
num_format += "0" * props.dp
|
||||
num_format += "%"
|
||||
xlsx_attributes.append(("num_format", num_format))
|
||||
if props.indent_level is not None and not no_indent:
|
||||
xlsx_attributes.append(("indent", props.indent_level))
|
||||
return dict([a for a in xlsx_attributes if a[1] is not None])
|
||||
|
||||
@api.model
|
||||
def to_css_style(self, props, no_indent=False):
|
||||
css_attributes = [
|
||||
("font-style", props.font_style),
|
||||
("font-weight", props.font_weight),
|
||||
("font-size", props.font_size),
|
||||
("color", props.color),
|
||||
("background-color", props.background_color),
|
||||
]
|
||||
if props.indent_level is not None and not no_indent:
|
||||
css_attributes.append(("text-indent", f"{props.indent_level}em"))
|
||||
return (
|
||||
"; ".join(["{}: {}".format(*a) for a in css_attributes if a[1] is not None])
|
||||
or None
|
||||
)
|
74
mis_builder/models/mis_report_subreport.py
Normal file
74
mis_builder/models/mis_report_subreport.py
Normal file
@ -0,0 +1,74 @@
|
||||
# Copyright 2020 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from flectra import _, api, fields, models
|
||||
from flectra.exceptions import ValidationError
|
||||
|
||||
from .mis_report import _is_valid_python_var
|
||||
|
||||
|
||||
class ParentLoopError(ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidNameError(ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class MisReportSubReport(models.Model):
|
||||
_name = "mis.report.subreport"
|
||||
_description = "MIS Report - Sub Reports Relation"
|
||||
|
||||
name = fields.Char(required=True)
|
||||
report_id = fields.Many2one(
|
||||
comodel_name="mis.report",
|
||||
required=True,
|
||||
ondelete="cascade",
|
||||
)
|
||||
subreport_id = fields.Many2one(
|
||||
comodel_name="mis.report",
|
||||
required=True,
|
||||
ondelete="restrict",
|
||||
)
|
||||
|
||||
_sql_constraints = [
|
||||
(
|
||||
"name_unique",
|
||||
"unique(name, report_id)",
|
||||
"Subreport name should be unique by report",
|
||||
),
|
||||
(
|
||||
"subreport_unique",
|
||||
"unique(subreport_id, report_id)",
|
||||
"Should not include the same report more than once as sub report "
|
||||
"of a given report",
|
||||
),
|
||||
]
|
||||
|
||||
@api.constrains("name")
|
||||
def _check_name(self):
|
||||
for rec in self:
|
||||
if not _is_valid_python_var(rec.name):
|
||||
raise InvalidNameError(
|
||||
_("Subreport name ({}) must be a valid python identifier").format(
|
||||
rec.name
|
||||
)
|
||||
)
|
||||
|
||||
@api.constrains("report_id", "subreport_id")
|
||||
def _check_loop(self):
|
||||
def _has_subreport(reports, report):
|
||||
if not reports:
|
||||
return False
|
||||
if report in reports:
|
||||
return True
|
||||
return any(
|
||||
_has_subreport(r.subreport_ids.mapped("subreport_id"), report)
|
||||
for r in reports
|
||||
)
|
||||
|
||||
for rec in self:
|
||||
if _has_subreport(rec.subreport_id, rec.report_id):
|
||||
raise ParentLoopError(_("Subreport loop detected"))
|
||||
|
||||
# TODO check subkpi compatibility in subreports
|
33
mis_builder/models/mis_safe_eval.py
Normal file
33
mis_builder/models/mis_safe_eval.py
Normal file
@ -0,0 +1,33 @@
|
||||
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import traceback
|
||||
|
||||
from flectra.tools.safe_eval import _BUILTINS, _SAFE_OPCODES, test_expr
|
||||
|
||||
from .data_error import DataError, NameDataError
|
||||
|
||||
__all__ = ["mis_safe_eval"]
|
||||
|
||||
|
||||
def mis_safe_eval(expr, locals_dict):
|
||||
"""Evaluate an expression using safe_eval
|
||||
|
||||
Returns the evaluated value or DataError.
|
||||
|
||||
Raises NameError if the evaluation depends on a variable that is not
|
||||
present in local_dict.
|
||||
"""
|
||||
try:
|
||||
c = test_expr(expr, _SAFE_OPCODES, mode="eval")
|
||||
globals_dict = {"__builtins__": _BUILTINS}
|
||||
# pylint: disable=eval-used,eval-referenced
|
||||
val = eval(c, globals_dict, locals_dict)
|
||||
except NameError:
|
||||
val = NameDataError("#NAME", traceback.format_exc())
|
||||
except ZeroDivisionError:
|
||||
# pylint: disable=redefined-variable-type
|
||||
val = DataError("#DIV/0", traceback.format_exc())
|
||||
except Exception:
|
||||
val = DataError("#ERR", traceback.format_exc())
|
||||
return val
|
96
mis_builder/models/prorata_read_group_mixin.py
Normal file
96
mis_builder/models/prorata_read_group_mixin.py
Normal file
@ -0,0 +1,96 @@
|
||||
# Copyright 2020 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from flectra import _, api, fields, models
|
||||
from flectra.exceptions import UserError
|
||||
from flectra.fields import Date
|
||||
|
||||
from .mis_kpi_data import intersect_days
|
||||
|
||||
|
||||
class ProRataReadGroupMixin(models.AbstractModel):
|
||||
_name = "prorata.read_group.mixin"
|
||||
_description = "Adapt model with date_from/date_to for pro-rata temporis read_group"
|
||||
|
||||
date_from = fields.Date(required=True)
|
||||
date_to = fields.Date(required=True)
|
||||
date = fields.Date(
|
||||
compute=lambda self: None,
|
||||
search="_search_date",
|
||||
help=(
|
||||
"Dummy field that adapts searches on date "
|
||||
"to searches on date_from/date_to."
|
||||
),
|
||||
)
|
||||
|
||||
def _search_date(self, operator, value):
|
||||
if operator in (">=", ">"):
|
||||
return [("date_to", operator, value)]
|
||||
elif operator in ("<=", "<"):
|
||||
return [("date_from", operator, value)]
|
||||
raise UserError(
|
||||
_("Unsupported operator %s for searching on date") % (operator,)
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _intersect_days(self, item_dt_from, item_dt_to, dt_from, dt_to):
|
||||
return intersect_days(item_dt_from, item_dt_to, dt_from, dt_to)
|
||||
|
||||
@api.model
|
||||
def read_group(
|
||||
self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True
|
||||
):
|
||||
"""Override read_group to perform pro-rata temporis adjustments.
|
||||
|
||||
When read_group is invoked with a domain that filters on
|
||||
a time period (date >= from and date <= to, or
|
||||
date_from <= to and date_to >= from), adjust the accumulated
|
||||
values pro-rata temporis.
|
||||
"""
|
||||
date_from = None
|
||||
date_to = None
|
||||
assert isinstance(domain, list)
|
||||
for domain_item in domain:
|
||||
if isinstance(domain_item, list | tuple):
|
||||
field, op, value = domain_item
|
||||
if field == "date" and op == ">=":
|
||||
date_from = value
|
||||
elif field == "date_to" and op == ">=":
|
||||
date_from = value
|
||||
elif field == "date" and op == "<=":
|
||||
date_to = value
|
||||
elif field == "date_from" and op == "<=":
|
||||
date_to = value
|
||||
if (
|
||||
date_from is not None
|
||||
and date_to is not None
|
||||
and not any(":" in f for f in fields)
|
||||
):
|
||||
dt_from = Date.from_string(date_from)
|
||||
dt_to = Date.from_string(date_to)
|
||||
res = {}
|
||||
sum_fields = set(fields) - set(groupby)
|
||||
read_fields = set(fields + ["date_from", "date_to"])
|
||||
for item in self.search(domain).read(read_fields):
|
||||
key = tuple(item[k] for k in groupby)
|
||||
if key not in res:
|
||||
res[key] = {k: item[k] for k in groupby}
|
||||
res[key].update({k: 0.0 for k in sum_fields})
|
||||
res_item = res[key]
|
||||
for sum_field in sum_fields:
|
||||
item_dt_from = Date.from_string(item["date_from"])
|
||||
item_dt_to = Date.from_string(item["date_to"])
|
||||
i_days, item_days = self._intersect_days(
|
||||
item_dt_from, item_dt_to, dt_from, dt_to
|
||||
)
|
||||
res_item[sum_field] += item[sum_field] * i_days / item_days
|
||||
return res.values()
|
||||
return super().read_group(
|
||||
domain,
|
||||
fields,
|
||||
groupby,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
orderby=orderby,
|
||||
lazy=lazy,
|
||||
)
|
184
mis_builder/models/simple_array.py
Normal file
184
mis_builder/models/simple_array.py
Normal file
@ -0,0 +1,184 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
""" A trivial immutable array that supports basic arithmetic operations.
|
||||
|
||||
>>> a = SimpleArray((1.0, 2.0, 3.0))
|
||||
>>> b = SimpleArray((4.0, 5.0, 6.0))
|
||||
>>> t = (4.0, 5.0, 6.0)
|
||||
>>> +a
|
||||
SimpleArray((1.0, 2.0, 3.0))
|
||||
>>> -a
|
||||
SimpleArray((-1.0, -2.0, -3.0))
|
||||
>>> a + b
|
||||
SimpleArray((5.0, 7.0, 9.0))
|
||||
>>> b + a
|
||||
SimpleArray((5.0, 7.0, 9.0))
|
||||
>>> a + t
|
||||
SimpleArray((5.0, 7.0, 9.0))
|
||||
>>> t + a
|
||||
SimpleArray((5.0, 7.0, 9.0))
|
||||
>>> a - b
|
||||
SimpleArray((-3.0, -3.0, -3.0))
|
||||
>>> a - t
|
||||
SimpleArray((-3.0, -3.0, -3.0))
|
||||
>>> t - a
|
||||
SimpleArray((3.0, 3.0, 3.0))
|
||||
>>> a * b
|
||||
SimpleArray((4.0, 10.0, 18.0))
|
||||
>>> b * a
|
||||
SimpleArray((4.0, 10.0, 18.0))
|
||||
>>> a * t
|
||||
SimpleArray((4.0, 10.0, 18.0))
|
||||
>>> t * a
|
||||
SimpleArray((4.0, 10.0, 18.0))
|
||||
>>> a / b
|
||||
SimpleArray((0.25, 0.4, 0.5))
|
||||
>>> b / a
|
||||
SimpleArray((4.0, 2.5, 2.0))
|
||||
>>> a / t
|
||||
SimpleArray((0.25, 0.4, 0.5))
|
||||
>>> t / a
|
||||
SimpleArray((4.0, 2.5, 2.0))
|
||||
>>> b / 2
|
||||
SimpleArray((2.0, 2.5, 3.0))
|
||||
>>> 2 * b
|
||||
SimpleArray((8.0, 10.0, 12.0))
|
||||
>>> 1 - b
|
||||
SimpleArray((-3.0, -4.0, -5.0))
|
||||
>>> b += 2 ; b
|
||||
SimpleArray((6.0, 7.0, 8.0))
|
||||
>>> a / ((1.0, 0.0, 1.0))
|
||||
SimpleArray((1.0, DataError('#DIV/0'), 3.0))
|
||||
>>> a / 0.0
|
||||
SimpleArray((DataError('#DIV/0'), DataError('#DIV/0'), DataError('#DIV/0')))
|
||||
>>> a * ((1.0, 'a', 1.0))
|
||||
SimpleArray((1.0, DataError('#ERR'), 3.0))
|
||||
>>> 6.0 / a
|
||||
SimpleArray((6.0, 3.0, 2.0))
|
||||
>>> Vector = named_simple_array('Vector', ('x', 'y'))
|
||||
>>> p1 = Vector((1, 2))
|
||||
>>> print(p1.x, p1.y, p1)
|
||||
1 2 Vector((1, 2))
|
||||
>>> p2 = Vector((2, 3))
|
||||
>>> print(p2.x, p2.y, p2)
|
||||
2 3 Vector((2, 3))
|
||||
>>> p3 = p1 + p2
|
||||
>>> print(p3.x, p3.y, p3)
|
||||
3 5 Vector((3, 5))
|
||||
>>> p4 = (4, 5) + p2
|
||||
>>> print(p4.x, p4.y, p4)
|
||||
6 8 Vector((6, 8))
|
||||
>>> p1 * 2
|
||||
Vector((2, 4))
|
||||
>>> 2 * p1
|
||||
Vector((2, 4))
|
||||
>>> p1 - 1
|
||||
Vector((0, 1))
|
||||
>>> 1 - p1
|
||||
Vector((0, -1))
|
||||
>>> p1 / 2.0
|
||||
Vector((0.5, 1.0))
|
||||
>>> v = 2.0 / p1
|
||||
>>> print(v.x, v.y, v)
|
||||
2.0 1.0 Vector((2.0, 1.0))
|
||||
"""
|
||||
|
||||
import itertools
|
||||
import operator
|
||||
import traceback
|
||||
|
||||
from .data_error import DataError
|
||||
|
||||
__all__ = ["SimpleArray", "named_simple_array"]
|
||||
|
||||
|
||||
class SimpleArray(tuple):
|
||||
def _op(self, op, other):
|
||||
def _o2(x, y):
|
||||
try:
|
||||
return op(x, y)
|
||||
except ZeroDivisionError:
|
||||
return DataError("#DIV/0", traceback.format_exc())
|
||||
except Exception:
|
||||
return DataError("#ERR", traceback.format_exc())
|
||||
|
||||
if isinstance(other, tuple):
|
||||
if len(other) != len(self):
|
||||
raise TypeError("tuples must have same length for %s" % op)
|
||||
return self.__class__(map(_o2, self, other))
|
||||
else:
|
||||
return self.__class__(_o2(z, other) for z in self)
|
||||
|
||||
def _cast(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return other
|
||||
elif isinstance(other, tuple):
|
||||
return self.__class__(other)
|
||||
else:
|
||||
# other is a scalar
|
||||
return self.__class__(itertools.repeat(other, len(self)))
|
||||
|
||||
def __add__(self, other):
|
||||
return self._op(operator.add, other)
|
||||
|
||||
__radd__ = __add__
|
||||
|
||||
def __pos__(self):
|
||||
return self.__class__(map(operator.pos, self))
|
||||
|
||||
def __neg__(self):
|
||||
return self.__class__(map(operator.neg, self))
|
||||
|
||||
def __sub__(self, other):
|
||||
return self._op(operator.sub, other)
|
||||
|
||||
def __rsub__(self, other):
|
||||
return self._cast(other)._op(operator.sub, self)
|
||||
|
||||
def __mul__(self, other):
|
||||
return self._op(operator.mul, other)
|
||||
|
||||
__rmul__ = __mul__
|
||||
|
||||
def __div__(self, other):
|
||||
return self._op(operator.div, other)
|
||||
|
||||
def __floordiv__(self, other):
|
||||
return self._op(operator.floordiv, other)
|
||||
|
||||
def __truediv__(self, other):
|
||||
return self._op(operator.truediv, other)
|
||||
|
||||
def __rdiv__(self, other):
|
||||
return self._cast(other)._op(operator.div, self)
|
||||
|
||||
def __rfloordiv__(self, other):
|
||||
return self._cast(other)._op(operator.floordiv, self)
|
||||
|
||||
def __rtruediv__(self, other):
|
||||
return self._cast(other)._op(operator.truediv, self)
|
||||
|
||||
def __repr__(self):
|
||||
return f"{self.__class__.__name__}({tuple.__repr__(self)})"
|
||||
|
||||
|
||||
def named_simple_array(typename, field_names):
|
||||
"""Return a subclass of SimpleArray, with named properties.
|
||||
|
||||
This method is to SimpleArray what namedtuple is to tuple.
|
||||
It's less sophisticated than namedtuple so some namedtuple
|
||||
advanced use cases may not work, but it's good enough for
|
||||
our needs in mis_builder, ie referring to subkpi values
|
||||
by name.
|
||||
"""
|
||||
props = {
|
||||
field_name: property(operator.itemgetter(i))
|
||||
for i, field_name in enumerate(field_names)
|
||||
}
|
||||
return type(typename, (SimpleArray,), props)
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
3
mis_builder/pyproject.toml
Normal file
3
mis_builder/pyproject.toml
Normal file
@ -0,0 +1,3 @@
|
||||
[build-system]
|
||||
requires = ["whool"]
|
||||
build-backend = "whool.buildapi"
|
5
mis_builder/report/__init__.py
Normal file
5
mis_builder/report/__init__.py
Normal file
@ -0,0 +1,5 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import mis_report_instance_qweb
|
||||
from . import mis_report_instance_xlsx
|
27
mis_builder/report/mis_report_instance_qweb.py
Normal file
27
mis_builder/report/mis_report_instance_qweb.py
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import logging
|
||||
|
||||
from flectra import models
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Report(models.Model):
|
||||
_inherit = "ir.actions.report"
|
||||
|
||||
def _render_qweb_pdf(self, report_ref, res_ids=None, data=None):
|
||||
if (
|
||||
self._get_report(report_ref).report_name
|
||||
== "mis_builder.report_mis_report_instance"
|
||||
):
|
||||
if not res_ids:
|
||||
res_ids = self.env.context.get("active_ids")
|
||||
mis_report_instance = self.env["mis.report.instance"].browse(res_ids)[0]
|
||||
# data=None, because it was there only to force Flectra
|
||||
# to propagate context
|
||||
return super(
|
||||
Report, self.with_context(landscape=mis_report_instance.landscape_pdf)
|
||||
)._render_qweb_pdf(report_ref, res_ids, data=None)
|
||||
return super()._render_qweb_pdf(report_ref, res_ids, data)
|
111
mis_builder/report/mis_report_instance_qweb.xml
Normal file
111
mis_builder/report/mis_report_instance_qweb.xml
Normal file
@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<flectra>
|
||||
<record id="qweb_pdf_export" model="ir.actions.report">
|
||||
<field name="name">MIS report instance QWEB PDF report</field>
|
||||
<field name="model">mis.report.instance</field>
|
||||
<field name="type">ir.actions.report</field>
|
||||
<field name="report_name">mis_builder.report_mis_report_instance</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
</record>
|
||||
<!--
|
||||
TODO we use divs with css table layout, but this has drawbacks:
|
||||
(bad layout of first column, no colspan for first header row),
|
||||
consider getting back to a plain HTML table.
|
||||
-->
|
||||
<template id="report_mis_report_instance">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<t t-call="web.internal_layout">
|
||||
<t t-set="matrix" t-value="o._compute_matrix()" />
|
||||
<t t-set="style_obj" t-value="o.env['mis.report.style']" />
|
||||
<div class="page">
|
||||
<h3>
|
||||
<span t-field="o.name" />
|
||||
<span>-</span>
|
||||
<t t-foreach="o.query_company_ids" t-as="company">
|
||||
<span t-field="company.name" />
|
||||
<span t-if="company != o.query_company_ids[-1]">,</span>
|
||||
</t>
|
||||
</h3>
|
||||
<p>
|
||||
<div class="mis_report_filers">
|
||||
<t
|
||||
t-foreach="o.get_filter_descriptions()"
|
||||
t-as="filter_description"
|
||||
>
|
||||
<div>
|
||||
<span t-out="filter_description" />
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</p>
|
||||
<div class="mis_table">
|
||||
<div class="mis_thead">
|
||||
<div class="mis_row">
|
||||
<div class="mis_cell mis_collabel" />
|
||||
<t t-foreach="matrix.iter_cols()" t-as="col">
|
||||
<div class="mis_cell mis_collabel">
|
||||
<t t-out="col.label" />
|
||||
<t t-if="col.description">
|
||||
<br />
|
||||
<t t-out="col.description" />
|
||||
</t>
|
||||
</div>
|
||||
<!-- add empty cells because we have no colspan with css tables -->
|
||||
<t
|
||||
t-foreach="list(col.iter_subcols())[1:]"
|
||||
t-as="subcol"
|
||||
>
|
||||
<div class="mis_cell mis_collabel" />
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<div class="mis_row">
|
||||
<div class="mis_cell mis_collabel" />
|
||||
<t t-foreach="matrix.iter_subcols()" t-as="subcol">
|
||||
<div class="mis_cell mis_collabel">
|
||||
<t t-out="subcol.label" />
|
||||
<t t-if="subcol.description">
|
||||
<br />
|
||||
<t t-out="subcol.description" />
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mis_tbody">
|
||||
<t t-foreach="matrix.iter_rows()" t-as="row">
|
||||
<div
|
||||
t-if="not ((row.style_props.hide_empty and row.is_empty()) or row.style_props.hide_always)"
|
||||
class="mis_row"
|
||||
>
|
||||
<div
|
||||
t-att-style="style_obj.to_css_style(row.style_props)"
|
||||
class="mis_cell mis_rowlabel"
|
||||
>
|
||||
<t t-out="row.label" />
|
||||
<t t-if="row.description">
|
||||
<br />
|
||||
<t t-out="row.description" />
|
||||
</t>
|
||||
</div>
|
||||
<t t-foreach="row.iter_cells()" t-as="cell">
|
||||
<div
|
||||
t-att-style="cell and style_obj.to_css_style(cell.style_props) or ''"
|
||||
class="mis_cell mis_amount"
|
||||
>
|
||||
<t
|
||||
t-out="cell and cell.val_rendered or ''"
|
||||
/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</flectra>
|
176
mis_builder/report/mis_report_instance_xlsx.py
Normal file
176
mis_builder/report/mis_report_instance_xlsx.py
Normal file
@ -0,0 +1,176 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import logging
|
||||
import numbers
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
|
||||
from flectra import _, fields, models
|
||||
|
||||
from ..models.accounting_none import AccountingNone
|
||||
from ..models.data_error import DataError
|
||||
from ..models.mis_report_style import TYPE_STR
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
ROW_HEIGHT = 15 # xlsxwriter units
|
||||
COL_WIDTH = 0.9 # xlsxwriter units
|
||||
MIN_COL_WIDTH = 10 # characters
|
||||
MAX_COL_WIDTH = 50 # characters
|
||||
|
||||
|
||||
class MisBuilderXlsx(models.AbstractModel):
|
||||
_name = "report.mis_builder.mis_report_instance_xlsx"
|
||||
_description = "MIS Builder XLSX report"
|
||||
_inherit = "report.report_xlsx.abstract"
|
||||
|
||||
def generate_xlsx_report(self, workbook, data, objects):
|
||||
# get the computed result of the report
|
||||
matrix = objects._compute_matrix()
|
||||
style_obj = self.env["mis.report.style"]
|
||||
|
||||
# create worksheet
|
||||
report_name = "{} - {}".format(
|
||||
objects[0].name, ", ".join([a.name for a in objects[0].query_company_ids])
|
||||
)
|
||||
sheet = workbook.add_worksheet(report_name[:31])
|
||||
row_pos = 0
|
||||
col_pos = 0
|
||||
# width of the labels column
|
||||
label_col_width = MIN_COL_WIDTH
|
||||
# {col_pos: max width in characters}
|
||||
col_width = defaultdict(lambda: MIN_COL_WIDTH)
|
||||
|
||||
# document title
|
||||
bold = workbook.add_format({"bold": True})
|
||||
header_format = workbook.add_format(
|
||||
{"bold": True, "align": "center", "bg_color": "#F0EEEE"}
|
||||
)
|
||||
sheet.write(row_pos, 0, report_name, bold)
|
||||
row_pos += 2
|
||||
|
||||
# filters
|
||||
filter_descriptions = objects.get_filter_descriptions()
|
||||
if filter_descriptions:
|
||||
for filter_description in objects.get_filter_descriptions():
|
||||
sheet.write(row_pos, 0, filter_description)
|
||||
row_pos += 1
|
||||
row_pos += 1
|
||||
|
||||
# column headers
|
||||
sheet.write(row_pos, 0, "", header_format)
|
||||
col_pos = 1
|
||||
for col in matrix.iter_cols():
|
||||
label = col.label
|
||||
if col.description:
|
||||
label += "\n" + col.description
|
||||
sheet.set_row(row_pos, ROW_HEIGHT * 2)
|
||||
if col.colspan > 1:
|
||||
sheet.merge_range(
|
||||
row_pos,
|
||||
col_pos,
|
||||
row_pos,
|
||||
col_pos + col.colspan - 1,
|
||||
label,
|
||||
header_format,
|
||||
)
|
||||
else:
|
||||
sheet.write(row_pos, col_pos, label, header_format)
|
||||
col_width[col_pos] = max(
|
||||
col_width[col_pos], len(col.label or ""), len(col.description or "")
|
||||
)
|
||||
col_pos += col.colspan
|
||||
row_pos += 1
|
||||
|
||||
# sub column headers
|
||||
sheet.write(row_pos, 0, "", header_format)
|
||||
col_pos = 1
|
||||
for subcol in matrix.iter_subcols():
|
||||
label = subcol.label
|
||||
if subcol.description:
|
||||
label += "\n" + subcol.description
|
||||
sheet.set_row(row_pos, ROW_HEIGHT * 2)
|
||||
sheet.write(row_pos, col_pos, label, header_format)
|
||||
col_width[col_pos] = max(
|
||||
col_width[col_pos],
|
||||
len(subcol.label or ""),
|
||||
len(subcol.description or ""),
|
||||
)
|
||||
col_pos += 1
|
||||
row_pos += 1
|
||||
|
||||
# rows
|
||||
for row in matrix.iter_rows():
|
||||
if (
|
||||
row.style_props.hide_empty and row.is_empty()
|
||||
) or row.style_props.hide_always:
|
||||
continue
|
||||
row_xlsx_style = style_obj.to_xlsx_style(TYPE_STR, row.style_props)
|
||||
row_format = workbook.add_format(row_xlsx_style)
|
||||
col_pos = 0
|
||||
label = row.label
|
||||
if row.description:
|
||||
label += "\n" + row.description
|
||||
sheet.set_row(row_pos, ROW_HEIGHT * 2)
|
||||
sheet.write(row_pos, col_pos, label, row_format)
|
||||
label_col_width = max(
|
||||
label_col_width, len(row.label or ""), len(row.description or "")
|
||||
)
|
||||
for cell in row.iter_cells():
|
||||
col_pos += 1
|
||||
if not cell or cell.val is AccountingNone:
|
||||
# TODO col/subcol format
|
||||
sheet.write(row_pos, col_pos, "", row_format)
|
||||
continue
|
||||
cell_xlsx_style = style_obj.to_xlsx_style(
|
||||
cell.val_type, cell.style_props, no_indent=True
|
||||
)
|
||||
cell_xlsx_style["align"] = "right"
|
||||
cell_format = workbook.add_format(cell_xlsx_style)
|
||||
if isinstance(cell.val, DataError):
|
||||
val = cell.val.name
|
||||
# TODO display cell.val.msg as Excel comment?
|
||||
elif cell.val is None or cell.val is AccountingNone:
|
||||
val = ""
|
||||
else:
|
||||
divider = float(cell.style_props.get("divider", 1))
|
||||
if (
|
||||
divider != 1
|
||||
and isinstance(cell.val, numbers.Number)
|
||||
and not cell.val_type == "pct"
|
||||
):
|
||||
val = cell.val / divider
|
||||
else:
|
||||
val = cell.val
|
||||
sheet.write(row_pos, col_pos, val, cell_format)
|
||||
col_width[col_pos] = max(
|
||||
col_width[col_pos], len(cell.val_rendered or "")
|
||||
)
|
||||
row_pos += 1
|
||||
|
||||
# Add date/time footer
|
||||
row_pos += 1
|
||||
footer_format = workbook.add_format(
|
||||
{"italic": True, "font_color": "#202020", "size": 9}
|
||||
)
|
||||
lang_model = self.env["res.lang"]
|
||||
lang = lang_model._lang_get(self.env.user.lang)
|
||||
|
||||
now_tz = fields.Datetime.context_timestamp(
|
||||
self.env["res.users"], datetime.now()
|
||||
)
|
||||
create_date = _(
|
||||
"Generated on %(gen_date)s at %(gen_time)s",
|
||||
gen_date=now_tz.strftime(lang.date_format),
|
||||
gen_time=now_tz.strftime(lang.time_format),
|
||||
)
|
||||
sheet.write(row_pos, 0, create_date, footer_format)
|
||||
|
||||
# adjust col widths
|
||||
sheet.set_column(0, 0, min(label_col_width, MAX_COL_WIDTH) * COL_WIDTH)
|
||||
data_col_width = min(MAX_COL_WIDTH, max(col_width.values()))
|
||||
min_col_pos = min(col_width.keys())
|
||||
max_col_pos = max(col_width.keys())
|
||||
sheet.set_column(min_col_pos, max_col_pos, data_col_width * COL_WIDTH)
|
11
mis_builder/report/mis_report_instance_xlsx.xml
Normal file
11
mis_builder/report/mis_report_instance_xlsx.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<flectra>
|
||||
<record id="xls_export" model="ir.actions.report">
|
||||
<field name="name">MIS report instance XLS report</field>
|
||||
<field name="model">mis.report.instance</field>
|
||||
<field name="type">ir.actions.report</field>
|
||||
<field name="report_name">mis_builder.mis_report_instance_xlsx</field>
|
||||
<field name="report_type">xlsx</field>
|
||||
<field name="report_file">mis_report_instance</field>
|
||||
</record>
|
||||
</flectra>
|
22
mis_builder/security/ir.model.access.csv
Normal file
22
mis_builder/security/ir.model.access.csv
Normal file
@ -0,0 +1,22 @@
|
||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
manage_mis_report_kpi,manage_mis_report_kpi,model_mis_report_kpi,account.group_account_manager,1,1,1,1
|
||||
access_mis_report_kpi,access_mis_report_kpi,model_mis_report_kpi,base.group_user,1,0,0,0
|
||||
manage_mis_report_query,manage_mis_report_query,model_mis_report_query,account.group_account_manager,1,1,1,1
|
||||
access_mis_report_query,access_mis_report_query,model_mis_report_query,base.group_user,1,0,0,0
|
||||
manage_mis_report,manage_mis_report,model_mis_report,account.group_account_manager,1,1,1,1
|
||||
access_mis_report,access_mis_report,model_mis_report,base.group_user,1,0,0,0
|
||||
manage_mis_report_instance_period,manage_mis_report_instance_period,model_mis_report_instance_period,account.group_account_manager,1,1,1,1
|
||||
access_mis_report_instance_period,access_mis_report_instance_period,model_mis_report_instance_period,base.group_user,1,0,0,0
|
||||
manage_mis_report_instance_period_sum,manage_mis_report_instance_period_sum,model_mis_report_instance_period_sum,account.group_account_manager,1,1,1,1
|
||||
access_mis_report_instance_period_sum,access_mis_report_instance_period_sum,model_mis_report_instance_period_sum,base.group_user,1,0,0,0
|
||||
manage_mis_report_instance,manage_mis_report_instance,model_mis_report_instance,account.group_account_manager,1,1,1,1
|
||||
access_mis_report_instance,access_mis_report_instance,model_mis_report_instance,base.group_user,1,0,0,0
|
||||
manage_mis_report_subkpi,access_mis_report_subkpi,model_mis_report_subkpi,account.group_account_manager,1,1,1,1
|
||||
access_mis_report_subkpi,access_mis_report_subkpi,model_mis_report_subkpi,base.group_user,1,0,0,0
|
||||
manage_mis_report_kpi_expression,access_mis_report_kpi_expression,model_mis_report_kpi_expression,account.group_account_manager,1,1,1,1
|
||||
access_mis_report_kpi_expression,access_mis_report_kpi_expression,model_mis_report_kpi_expression,base.group_user,1,0,0,0
|
||||
manage_mis_report_subreport,access_mis_report_subreport,model_mis_report_subreport,account.group_account_manager,1,1,1,1
|
||||
access_mis_report_subreport,access_mis_report_subreport,model_mis_report_subreport,base.group_user,1,0,0,0
|
||||
manage_mis_report_style,access_mis_report_style,model_mis_report_style,account.group_account_manager,1,1,1,1
|
||||
access_mis_report_style,access_mis_report_style,model_mis_report_style,base.group_user,1,0,0,0
|
||||
access_add_to_dashboard_wizard,access_add_to_dashboard_wizard,model_add_mis_report_instance_dashboard_wizard,base.group_user,1,1,1,0
|
|
11
mis_builder/security/mis_builder_security.xml
Normal file
11
mis_builder/security/mis_builder_security.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<flectra>
|
||||
<record id="mis_builder_multi_company_rule" model="ir.rule">
|
||||
<field name="name">Mis Report Instance multi company</field>
|
||||
<field name="model_id" ref="model_mis_report_instance" />
|
||||
<field name="domain_force">
|
||||
['|',('company_id','=',False),('company_id','in',company_ids), '|',
|
||||
('company_ids', '=', False), ('company_ids', 'in', company_ids)]
|
||||
</field>
|
||||
</record>
|
||||
</flectra>
|
BIN
mis_builder/static/description/ex_report_preview.png
Normal file
BIN
mis_builder/static/description/ex_report_preview.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
BIN
mis_builder/static/description/ex_report_settings.png
Normal file
BIN
mis_builder/static/description/ex_report_settings.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 101 KiB |
BIN
mis_builder/static/description/ex_report_template.png
Normal file
BIN
mis_builder/static/description/ex_report_template.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 98 KiB |
BIN
mis_builder/static/description/icon.png
Normal file
BIN
mis_builder/static/description/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
1054
mis_builder/static/description/index.html
Normal file
1054
mis_builder/static/description/index.html
Normal file
File diff suppressed because it is too large
Load Diff
67
mis_builder/static/src/components/mis_report_widget.css
Normal file
67
mis_builder/static/src/components/mis_report_widget.css
Normal file
@ -0,0 +1,67 @@
|
||||
.o_web_client .mis_builder_amount {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.o_web_client .mis_builder_collabel {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.o_web_client .mis_builder_rowlabel {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.o_web_client .mis_builder a {
|
||||
/* we don't want the link color, to respect user styles */
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.o_web_client .mis_builder a:hover {
|
||||
/* underline links on hover to give a visual cue */
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.oe_mis_builder_content {
|
||||
}
|
||||
|
||||
/* style for the control panel (search box and buttons) */
|
||||
|
||||
.oe_mis_builder_cp {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.oe_mis_builder_cp_left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.oe_mis_builder_cp_right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 2;
|
||||
max-width: 1280px;
|
||||
}
|
||||
|
||||
.oe_mis_builder_cp_right_top {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.oe_mis_builder_cp_right_bottom {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.oe_mis_builder_filter_buttons {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.oe_mis_builder_action_buttons {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
justify-content: flex-end;
|
||||
}
|
182
mis_builder/static/src/components/mis_report_widget.esm.js
Normal file
182
mis_builder/static/src/components/mis_report_widget.esm.js
Normal file
@ -0,0 +1,182 @@
|
||||
/** @flectra-module **/
|
||||
|
||||
import {Component, onWillStart, useState, useSubEnv} from "@flectra/owl";
|
||||
import {useBus, useService} from "@web/core/utils/hooks";
|
||||
import {DatePicker} from "@web/core/datepicker/datepicker";
|
||||
import {FilterMenu} from "@web/search/filter_menu/filter_menu";
|
||||
import {SearchBar} from "@web/search/search_bar/search_bar";
|
||||
import {SearchModel} from "@web/search/search_model";
|
||||
import {parseDate} from "@web/core/l10n/dates";
|
||||
import {registry} from "@web/core/registry";
|
||||
|
||||
export class MisReportWidget extends Component {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.orm = useService("orm");
|
||||
this.user = useService("user");
|
||||
this.action = useService("action");
|
||||
this.view = useService("view");
|
||||
this.JSON = JSON;
|
||||
this.state = useState({
|
||||
mis_report_data: {header: [], body: []},
|
||||
pivot_date: null,
|
||||
});
|
||||
this.searchModel = new SearchModel(this.env, {
|
||||
user: this.user,
|
||||
orm: this.orm,
|
||||
view: this.view,
|
||||
});
|
||||
useSubEnv({searchModel: this.searchModel});
|
||||
useBus(this.env.searchModel, "update", async () => {
|
||||
await this.env.searchModel.sectionsPromise;
|
||||
this.refresh();
|
||||
});
|
||||
onWillStart(this.willStart);
|
||||
}
|
||||
|
||||
// Lifecycle
|
||||
async willStart() {
|
||||
const [result] = await this.orm.read(
|
||||
"mis.report.instance",
|
||||
[this._instanceId()],
|
||||
[
|
||||
"source_aml_model_name",
|
||||
"widget_show_filters",
|
||||
"widget_show_settings_button",
|
||||
"widget_search_view_id",
|
||||
"pivot_date",
|
||||
"widget_show_pivot_date",
|
||||
],
|
||||
{context: this.context}
|
||||
);
|
||||
this.source_aml_model_name = result.source_aml_model_name;
|
||||
this.widget_show_filters = result.widget_show_filters;
|
||||
this.widget_show_settings_button = result.widget_show_settings_button;
|
||||
this.widget_search_view_id =
|
||||
result.widget_search_view_id && result.widget_search_view_id[0];
|
||||
this.state.pivot_date = parseDate(result.pivot_date);
|
||||
this.widget_show_pivot_date = result.widget_show_pivot_date;
|
||||
if (this.showSearchBar) {
|
||||
// Initialize the search model
|
||||
await this.searchModel.load({
|
||||
resModel: this.source_aml_model_name,
|
||||
searchViewId: this.widget_search_view_id,
|
||||
});
|
||||
}
|
||||
|
||||
// Compute the report
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
get showSearchBar() {
|
||||
return (
|
||||
this.source_aml_model_name &&
|
||||
this.widget_show_filters &&
|
||||
this.widget_search_view_id
|
||||
);
|
||||
}
|
||||
|
||||
get showPivotDate() {
|
||||
return this.widget_show_pivot_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the id of the mis.report.instance to which the widget is
|
||||
* bound.
|
||||
*
|
||||
* @returns int
|
||||
*/
|
||||
_instanceId() {
|
||||
if (this.props.value) {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
/*
|
||||
* This trick is needed because in a dashboard the view does
|
||||
* not seem to be bound to an instance: it seems to be a limitation
|
||||
* of Flectra dashboards that are not designed to contain forms but
|
||||
* rather tree views or charts.
|
||||
*/
|
||||
var context = this.props.record.context;
|
||||
if (context.active_model === "mis.report.instance") {
|
||||
return context.active_id;
|
||||
}
|
||||
}
|
||||
|
||||
get context() {
|
||||
var ctx = super.context;
|
||||
if (this.showSearchBar) {
|
||||
ctx = {
|
||||
...ctx,
|
||||
mis_analytic_domain: this.searchModel.searchDomain,
|
||||
};
|
||||
}
|
||||
if (this.showPivotDate && this.state.pivot_date) {
|
||||
ctx = {
|
||||
...ctx,
|
||||
mis_pivot_date: this.state.pivot_date,
|
||||
};
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
async drilldown(event) {
|
||||
const drilldown = $(event.target).data("drilldown");
|
||||
const action = await this.orm.call(
|
||||
"mis.report.instance",
|
||||
"drilldown",
|
||||
[this._instanceId(), drilldown],
|
||||
{context: this.context}
|
||||
);
|
||||
this.action.doAction(action);
|
||||
}
|
||||
|
||||
async refresh() {
|
||||
this.state.mis_report_data = await this.orm.call(
|
||||
"mis.report.instance",
|
||||
"compute",
|
||||
[this._instanceId()],
|
||||
{context: this.context}
|
||||
);
|
||||
}
|
||||
|
||||
async printPdf() {
|
||||
const action = await this.orm.call(
|
||||
"mis.report.instance",
|
||||
"print_pdf",
|
||||
[this._instanceId()],
|
||||
{context: this.context}
|
||||
);
|
||||
this.action.doAction(action);
|
||||
}
|
||||
|
||||
async exportXls() {
|
||||
const action = await this.orm.call(
|
||||
"mis.report.instance",
|
||||
"export_xls",
|
||||
[this._instanceId()],
|
||||
{context: this.context}
|
||||
);
|
||||
this.action.doAction(action);
|
||||
}
|
||||
|
||||
async displaySettings() {
|
||||
const action = await this.orm.call(
|
||||
"mis.report.instance",
|
||||
"display_settings",
|
||||
[this._instanceId()],
|
||||
{context: this.context}
|
||||
);
|
||||
this.action.doAction(action);
|
||||
}
|
||||
|
||||
onDateTimeChanged(ev) {
|
||||
this.state.pivot_date = ev;
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
MisReportWidget.components = {FilterMenu, SearchBar, DatePicker};
|
||||
MisReportWidget.template = "mis_builder.MisReportWidget";
|
||||
|
||||
registry.category("fields").add("mis_report_widget", MisReportWidget);
|
115
mis_builder/static/src/components/mis_report_widget.xml
Normal file
115
mis_builder/static/src/components/mis_report_widget.xml
Normal file
@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<templates>
|
||||
|
||||
<t t-name="mis_builder.MisReportWidget" owl="1">
|
||||
<div class="oe_mis_builder_content">
|
||||
<t t-if="state.mis_report_data">
|
||||
<div class="oe_mis_builder_cp">
|
||||
<div class="oe_mis_builder_cp_left">
|
||||
</div>
|
||||
<div class="oe_mis_builder_cp_right">
|
||||
<div class="oe_mis_builder_cp_right_top">
|
||||
<SearchBar t-if="showSearchBar" />
|
||||
</div>
|
||||
<div class="oe_mis_builder_cp_right_bottom">
|
||||
<div class="oe_mis_builder_filter_buttons">
|
||||
<FilterMenu t-if="showSearchBar" />
|
||||
<DatePicker
|
||||
date="state.pivot_date"
|
||||
onDateTimeChanged="onDateTimeChanged.bind(this)"
|
||||
placeholder="'Base date...'"
|
||||
t-if="showPivotDate"
|
||||
/>
|
||||
</div>
|
||||
<div class="oe_mis_builder_action_buttons">
|
||||
<button t-on-click="refresh" class="btn">
|
||||
<span class="fa fa-refresh" /> Refresh </button>
|
||||
<button t-on-click="printPdf" class="btn">
|
||||
<span class="fa fa-print" /> Print </button>
|
||||
<button t-on-click="exportXls" class="btn">
|
||||
<span class="fa fa-download" /> Export </button>
|
||||
<button
|
||||
t-on-click="displaySettings"
|
||||
t-if="widget_show_settings_button"
|
||||
class="btn"
|
||||
>
|
||||
<span class="fa fa-cog" /> Settings </button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_list_renderer o_renderer table-responsive">
|
||||
<table
|
||||
class="o_list_table table table-sm table-hover table-striped mis_builder"
|
||||
>
|
||||
<thead>
|
||||
<tr
|
||||
t-foreach="state.mis_report_data.header"
|
||||
t-as="row"
|
||||
t-key="row_index"
|
||||
class="oe_list_header_columns"
|
||||
>
|
||||
<th class="oe_list_header_char">
|
||||
|
||||
</th>
|
||||
<th
|
||||
t-foreach="row.cols"
|
||||
t-as="col"
|
||||
t-key="col_index"
|
||||
class="oe_list_header_char mis_builder_collabel"
|
||||
t-att-colspan="col.colspan"
|
||||
>
|
||||
<t t-esc="col.label" />
|
||||
<t t-if="col.description">
|
||||
<br />
|
||||
<t t-esc="col.description" />
|
||||
</t>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
t-foreach="state.mis_report_data.body"
|
||||
t-as="row"
|
||||
t-key="row_index"
|
||||
>
|
||||
<td t-att="{'style': row.style}">
|
||||
<t t-esc="row.label" />
|
||||
<t t-if="row.description">
|
||||
<br />
|
||||
<t t-esc="row.description" />
|
||||
</t>
|
||||
</td>
|
||||
<td
|
||||
t-foreach="row.cells"
|
||||
t-as="cell"
|
||||
t-key="cell_index"
|
||||
t-att="{'style': cell.style, 'title': cell.val_c}"
|
||||
class="mis_builder_amount"
|
||||
>
|
||||
<t t-if="cell.drilldown_arg">
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
class="mis_builder_drilldown"
|
||||
t-on-click="drilldown"
|
||||
t-att-data-drilldown="JSON.stringify(cell.drilldown_arg)"
|
||||
>
|
||||
<t t-esc="cell.val_r" />
|
||||
</a>
|
||||
</t>
|
||||
<t t-if="!cell.drilldown_arg">
|
||||
<t t-esc="cell.val_r" />
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr />
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
46
mis_builder/static/src/css/report.css
Normal file
46
mis_builder/static/src/css/report.css
Normal file
@ -0,0 +1,46 @@
|
||||
.mis_table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
.mis_row {
|
||||
display: table-row;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
.mis_cell {
|
||||
display: table-cell;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
.mis_thead {
|
||||
display: table-header-group;
|
||||
}
|
||||
.mis_tbody {
|
||||
display: table-row-group;
|
||||
}
|
||||
.mis_table,
|
||||
.mis_table .mis_row {
|
||||
border-left: 0px;
|
||||
border-right: 0px;
|
||||
text-align: left;
|
||||
padding-right: 3px;
|
||||
padding-left: 3px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.mis_table .mis_row {
|
||||
border-color: grey;
|
||||
border-bottom: 1px solid lightGrey;
|
||||
}
|
||||
.mis_table .mis_cell.mis_collabel {
|
||||
font-weight: bold;
|
||||
background-color: #f0f0f0;
|
||||
text-align: center;
|
||||
}
|
||||
.mis_table .mis_cell.mis_rowlabel {
|
||||
text-align: left;
|
||||
/*white-space: nowrap;*/
|
||||
}
|
||||
.mis_table .mis_cell.mis_amount {
|
||||
text-align: right;
|
||||
}
|
16
mis_builder/tests/__init__.py
Normal file
16
mis_builder/tests/__init__.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import test_accounting_none
|
||||
from . import test_aep
|
||||
from . import test_multi_company_aep
|
||||
from . import test_aggregate
|
||||
from . import test_data_sources
|
||||
from . import test_kpi_data
|
||||
from . import test_mis_report_instance
|
||||
from . import test_mis_safe_eval
|
||||
from . import test_period_dates
|
||||
from . import test_render
|
||||
from . import test_simple_array
|
||||
from . import test_target_move
|
||||
from . import test_utc_midnight
|
67
mis_builder/tests/common.py
Normal file
67
mis_builder/tests/common.py
Normal file
@ -0,0 +1,67 @@
|
||||
# Copyright 2017 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import doctest
|
||||
|
||||
from flectra.tests import BaseCase, tagged
|
||||
|
||||
|
||||
def _zip(iter1, iter2):
|
||||
i = 0
|
||||
iter1 = iter(iter1)
|
||||
iter2 = iter(iter2)
|
||||
while True:
|
||||
i1 = next(iter1, None)
|
||||
i2 = next(iter2, None)
|
||||
if i1 is None and i2 is None:
|
||||
return
|
||||
yield i, i1, i2
|
||||
i += 1
|
||||
|
||||
|
||||
def assert_matrix(matrix, expected):
|
||||
for i, row, expected_row in _zip(matrix.iter_rows(), expected):
|
||||
if row is None and expected_row is not None:
|
||||
raise AssertionError("not enough rows")
|
||||
if row is not None and expected_row is None:
|
||||
raise AssertionError("too many rows")
|
||||
for j, cell, expected_val in _zip(row.iter_cells(), expected_row):
|
||||
assert (
|
||||
cell and cell.val
|
||||
) == expected_val, "{} != {} in row {} col {}".format(
|
||||
cell and cell.val, expected_val, i, j
|
||||
)
|
||||
|
||||
|
||||
@tagged("doctest")
|
||||
class FlectraDocTestCase(BaseCase):
|
||||
"""
|
||||
We need a custom DocTestCase class in order to:
|
||||
- define test_tags to run as part of standard tests
|
||||
- output a more meaningful test name than default "DocTestCase.runTest"
|
||||
"""
|
||||
|
||||
__qualname__ = "doctests for "
|
||||
|
||||
def __init__(self, test):
|
||||
self.__test = test
|
||||
self.__name = test._dt_test.name
|
||||
super().__init__(self.__name)
|
||||
|
||||
def __getattr__(self, item):
|
||||
if item == self.__name:
|
||||
return self.__test
|
||||
|
||||
|
||||
def load_doctests(module):
|
||||
"""
|
||||
Generates a tests loading method for the doctests of the given module
|
||||
https://docs.python.org/3/library/unittest.html#load-tests-protocol
|
||||
"""
|
||||
|
||||
def load_tests(loader, tests, ignore):
|
||||
for test in doctest.DocTestSuite(module):
|
||||
tests.addTest(FlectraDocTestCase(test))
|
||||
return tests
|
||||
|
||||
return load_tests
|
7
mis_builder/tests/fake_models.py
Normal file
7
mis_builder/tests/fake_models.py
Normal file
@ -0,0 +1,7 @@
|
||||
from flectra import models
|
||||
|
||||
|
||||
class MisKpiDataTestItem(models.Model):
|
||||
_name = "mis.kpi.data.test.item"
|
||||
_inherit = "mis.kpi.data"
|
||||
_description = "MIS Kpi Data test item"
|
8
mis_builder/tests/test_accounting_none.py
Normal file
8
mis_builder/tests/test_accounting_none.py
Normal file
@ -0,0 +1,8 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
|
||||
from ..models import accounting_none
|
||||
from .common import load_doctests
|
||||
|
||||
load_tests = load_doctests(accounting_none)
|
397
mis_builder/tests/test_aep.py
Normal file
397
mis_builder/tests/test_aep.py
Normal file
@ -0,0 +1,397 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import datetime
|
||||
import time
|
||||
|
||||
import flectra.tests.common as common
|
||||
from flectra import fields
|
||||
from flectra.exceptions import UserError
|
||||
from flectra.tools.safe_eval import safe_eval
|
||||
|
||||
from ..models.accounting_none import AccountingNone
|
||||
from ..models.aep import AccountingExpressionProcessor as AEP
|
||||
from ..models.aep import _is_domain
|
||||
|
||||
|
||||
class TestAEP(common.TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.res_company = self.env["res.company"]
|
||||
self.account_model = self.env["account.account"]
|
||||
self.move_model = self.env["account.move"]
|
||||
self.journal_model = self.env["account.journal"]
|
||||
self.curr_year = datetime.date.today().year
|
||||
self.prev_year = self.curr_year - 1
|
||||
# create company
|
||||
self.company = self.res_company.create({"name": "AEP Company"})
|
||||
# create receivable bs account
|
||||
self.account_ar = self.account_model.create(
|
||||
{
|
||||
"company_id": self.company.id,
|
||||
"code": "400AR",
|
||||
"name": "Receivable",
|
||||
"account_type": "asset_receivable",
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
# create income pl account
|
||||
self.account_in = self.account_model.create(
|
||||
{
|
||||
"company_id": self.company.id,
|
||||
"code": "700IN",
|
||||
"name": "Income",
|
||||
"account_type": "income",
|
||||
}
|
||||
)
|
||||
# create journal
|
||||
self.journal = self.journal_model.create(
|
||||
{
|
||||
"company_id": self.company.id,
|
||||
"name": "Sale journal",
|
||||
"code": "VEN",
|
||||
"type": "sale",
|
||||
}
|
||||
)
|
||||
# create move in December last year
|
||||
self._create_move(
|
||||
date=datetime.date(self.prev_year, 12, 1),
|
||||
amount=100,
|
||||
debit_acc=self.account_ar,
|
||||
credit_acc=self.account_in,
|
||||
)
|
||||
# create move in January this year
|
||||
self._create_move(
|
||||
date=datetime.date(self.curr_year, 1, 1),
|
||||
amount=300,
|
||||
debit_acc=self.account_ar,
|
||||
credit_acc=self.account_in,
|
||||
)
|
||||
# create move in March this year
|
||||
self._create_move(
|
||||
date=datetime.date(self.curr_year, 3, 1),
|
||||
amount=500,
|
||||
debit_acc=self.account_ar,
|
||||
credit_acc=self.account_in,
|
||||
)
|
||||
# create the AEP, and prepare the expressions we'll need
|
||||
self.aep = AEP(self.company)
|
||||
self.aep.parse_expr("bali[]")
|
||||
self.aep.parse_expr("bale[]")
|
||||
self.aep.parse_expr("balp[]")
|
||||
self.aep.parse_expr("balu[]")
|
||||
self.aep.parse_expr("bali[700IN]")
|
||||
self.aep.parse_expr("bale[700IN]")
|
||||
self.aep.parse_expr("balp[700IN]")
|
||||
self.aep.parse_expr("bali[400AR]")
|
||||
self.aep.parse_expr("bale[400AR]")
|
||||
self.aep.parse_expr("balp[400AR]")
|
||||
self.aep.parse_expr("debp[400A%]")
|
||||
self.aep.parse_expr("crdp[700I%]")
|
||||
self.aep.parse_expr("bali[400%]")
|
||||
self.aep.parse_expr("bale[700%]")
|
||||
self.aep.parse_expr("balp[]" "[('account_id.code', '=', '400AR')]")
|
||||
self.aep.parse_expr(
|
||||
"balp[]" "[('account_id.account_type', '=', " " 'asset_receivable')]"
|
||||
)
|
||||
self.aep.parse_expr("balp[('account_type', '=', " " 'asset_receivable')]")
|
||||
self.aep.parse_expr(
|
||||
"balp['&', "
|
||||
" ('account_type', '=', "
|
||||
" 'asset_receivable'), "
|
||||
" ('code', '=', '400AR')]"
|
||||
)
|
||||
self.aep.parse_expr("bal_700IN") # deprecated
|
||||
self.aep.parse_expr("bals[700IN]") # deprecated
|
||||
|
||||
def _create_move(self, date, amount, debit_acc, credit_acc, post=True):
|
||||
move = self.move_model.create(
|
||||
{
|
||||
"journal_id": self.journal.id,
|
||||
"date": fields.Date.to_string(date),
|
||||
"line_ids": [
|
||||
(0, 0, {"name": "/", "debit": amount, "account_id": debit_acc.id}),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{"name": "/", "credit": amount, "account_id": credit_acc.id},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
if post:
|
||||
move._post()
|
||||
return move
|
||||
|
||||
def _do_queries(self, date_from, date_to):
|
||||
self.aep.do_queries(
|
||||
date_from=fields.Date.to_string(date_from),
|
||||
date_to=fields.Date.to_string(date_to),
|
||||
)
|
||||
|
||||
def _eval(self, expr):
|
||||
eval_dict = {"AccountingNone": AccountingNone}
|
||||
return safe_eval(self.aep.replace_expr(expr), eval_dict)
|
||||
|
||||
def _eval_by_account_id(self, expr):
|
||||
res = {}
|
||||
eval_dict = {"AccountingNone": AccountingNone}
|
||||
for account_id, replaced_exprs in self.aep.replace_exprs_by_account_id([expr]):
|
||||
res[account_id] = safe_eval(replaced_exprs[0], eval_dict)
|
||||
return res
|
||||
|
||||
def test_sanity_check(self):
|
||||
self.assertEqual(self.company.fiscalyear_last_day, 31)
|
||||
self.assertEqual(self.company.fiscalyear_last_month, "12")
|
||||
|
||||
def test_aep_basic(self):
|
||||
self.aep.done_parsing()
|
||||
# let's query for december
|
||||
self._do_queries(
|
||||
datetime.date(self.prev_year, 12, 1), datetime.date(self.prev_year, 12, 31)
|
||||
)
|
||||
# initial balance must be None
|
||||
self.assertIs(self._eval("bali[400AR]"), AccountingNone)
|
||||
self.assertIs(self._eval("bali[700IN]"), AccountingNone)
|
||||
# check variation
|
||||
self.assertEqual(self._eval("balp[400AR]"), 100)
|
||||
self.assertEqual(self._eval("balp[][('account_id.code', '=', '400AR')]"), 100)
|
||||
self.assertEqual(
|
||||
self._eval(
|
||||
"balp[]" "[('account_id.account_type', '=', " " 'asset_receivable')]"
|
||||
),
|
||||
100,
|
||||
)
|
||||
self.assertEqual(
|
||||
self._eval("balp[('account_type', '=', " " 'asset_receivable')]"),
|
||||
100,
|
||||
)
|
||||
self.assertEqual(
|
||||
self._eval(
|
||||
"balp['&', "
|
||||
" ('account_type', '=', "
|
||||
" 'asset_receivable'), "
|
||||
" ('code', '=', '400AR')]"
|
||||
),
|
||||
100,
|
||||
)
|
||||
self.assertEqual(self._eval("balp[700IN]"), -100)
|
||||
# check ending balance
|
||||
self.assertEqual(self._eval("bale[400AR]"), 100)
|
||||
self.assertEqual(self._eval("bale[700IN]"), -100)
|
||||
|
||||
# let's query for January
|
||||
self._do_queries(
|
||||
datetime.date(self.curr_year, 1, 1), datetime.date(self.curr_year, 1, 31)
|
||||
)
|
||||
# initial balance is None for income account (it's not carried over)
|
||||
self.assertEqual(self._eval("bali[400AR]"), 100)
|
||||
self.assertIs(self._eval("bali[700IN]"), AccountingNone)
|
||||
# check variation
|
||||
self.assertEqual(self._eval("balp[400AR]"), 300)
|
||||
self.assertEqual(self._eval("balp[700IN]"), -300)
|
||||
# check ending balance
|
||||
self.assertEqual(self._eval("bale[400AR]"), 400)
|
||||
self.assertEqual(self._eval("bale[700IN]"), -300)
|
||||
|
||||
# let's query for March
|
||||
self._do_queries(
|
||||
datetime.date(self.curr_year, 3, 1), datetime.date(self.curr_year, 3, 31)
|
||||
)
|
||||
# initial balance is the ending balance fo January
|
||||
self.assertEqual(self._eval("bali[400AR]"), 400)
|
||||
self.assertEqual(self._eval("bali[700IN]"), -300)
|
||||
self.assertEqual(self._eval("pbali[400AR]"), 400)
|
||||
self.assertEqual(self._eval("nbali[400AR]"), 0)
|
||||
self.assertEqual(self._eval("nbali[700IN]"), -300)
|
||||
self.assertEqual(self._eval("pbali[700IN]"), 0)
|
||||
# check variation
|
||||
self.assertEqual(self._eval("balp[400AR]"), 500)
|
||||
self.assertEqual(self._eval("balp[700IN]"), -500)
|
||||
self.assertEqual(self._eval("nbalp[400AR]"), 0)
|
||||
self.assertEqual(self._eval("pbalp[400AR]"), 500)
|
||||
self.assertEqual(self._eval("nbalp[700IN]"), -500)
|
||||
self.assertEqual(self._eval("pbalp[700IN]"), 0)
|
||||
# check ending balance
|
||||
self.assertEqual(self._eval("bale[400AR]"), 900)
|
||||
self.assertEqual(self._eval("nbale[400AR]"), 0)
|
||||
self.assertEqual(self._eval("pbale[400AR]"), 900)
|
||||
self.assertEqual(self._eval("bale[700IN]"), -800)
|
||||
self.assertEqual(self._eval("nbale[700IN]"), -800)
|
||||
self.assertEqual(self._eval("pbale[700IN]"), 0)
|
||||
# check some variant expressions, for coverage
|
||||
self.assertEqual(self._eval("crdp[700I%]"), 500)
|
||||
self.assertEqual(self._eval("debp[400A%]"), 500)
|
||||
self.assertEqual(self._eval("bal_700IN"), -500)
|
||||
self.assertEqual(self._eval("bals[700IN]"), -800)
|
||||
|
||||
# unallocated p&l from previous year
|
||||
self.assertEqual(self._eval("balu[]"), -100)
|
||||
|
||||
# TODO allocate profits, and then...
|
||||
|
||||
def test_aep_by_account(self):
|
||||
self.aep.done_parsing()
|
||||
self._do_queries(
|
||||
datetime.date(self.curr_year, 3, 1), datetime.date(self.curr_year, 3, 31)
|
||||
)
|
||||
variation = self._eval_by_account_id("balp[]")
|
||||
self.assertEqual(variation, {self.account_ar.id: 500, self.account_in.id: -500})
|
||||
variation = self._eval_by_account_id("pbalp[]")
|
||||
self.assertEqual(
|
||||
variation, {self.account_ar.id: 500, self.account_in.id: AccountingNone}
|
||||
)
|
||||
variation = self._eval_by_account_id("nbalp[]")
|
||||
self.assertEqual(
|
||||
variation, {self.account_ar.id: AccountingNone, self.account_in.id: -500}
|
||||
)
|
||||
variation = self._eval_by_account_id("balp[700IN]")
|
||||
self.assertEqual(variation, {self.account_in.id: -500})
|
||||
variation = self._eval_by_account_id("crdp[700IN] - debp[400AR]")
|
||||
self.assertEqual(variation, {self.account_ar.id: -500, self.account_in.id: 500})
|
||||
end = self._eval_by_account_id("bale[]")
|
||||
self.assertEqual(end, {self.account_ar.id: 900, self.account_in.id: -800})
|
||||
|
||||
def test_aep_convenience_methods(self):
|
||||
initial = AEP.get_balances_initial(self.company, time.strftime("%Y") + "-03-01")
|
||||
self.assertEqual(
|
||||
initial, {self.account_ar.id: (400, 0), self.account_in.id: (0, 300)}
|
||||
)
|
||||
variation = AEP.get_balances_variation(
|
||||
self.company,
|
||||
time.strftime("%Y") + "-03-01",
|
||||
time.strftime("%Y") + "-03-31",
|
||||
)
|
||||
self.assertEqual(
|
||||
variation, {self.account_ar.id: (500, 0), self.account_in.id: (0, 500)}
|
||||
)
|
||||
end = AEP.get_balances_end(self.company, time.strftime("%Y") + "-03-31")
|
||||
self.assertEqual(
|
||||
end, {self.account_ar.id: (900, 0), self.account_in.id: (0, 800)}
|
||||
)
|
||||
unallocated = AEP.get_unallocated_pl(
|
||||
self.company, time.strftime("%Y") + "-03-15"
|
||||
)
|
||||
self.assertEqual(unallocated, (0, 100))
|
||||
|
||||
def test_float_is_zero(self):
|
||||
dp = self.company.currency_id.decimal_places
|
||||
self.assertEqual(dp, 2)
|
||||
# make initial balance at Jan 1st equal to 0.01
|
||||
self._create_move(
|
||||
date=datetime.date(self.prev_year, 12, 1),
|
||||
amount=100.01,
|
||||
debit_acc=self.account_in,
|
||||
credit_acc=self.account_ar,
|
||||
)
|
||||
initial = AEP.get_balances_initial(self.company, time.strftime("%Y") + "-01-01")
|
||||
self.assertEqual(initial, {self.account_ar.id: (100.00, 100.01)})
|
||||
# make initial balance at Jan 1st equal to 0.001
|
||||
self._create_move(
|
||||
date=datetime.date(self.prev_year, 12, 1),
|
||||
amount=0.009,
|
||||
debit_acc=self.account_ar,
|
||||
credit_acc=self.account_in,
|
||||
)
|
||||
initial = AEP.get_balances_initial(self.company, time.strftime("%Y") + "-01-01")
|
||||
# epsilon initial balances is reported as empty
|
||||
self.assertEqual(initial, {})
|
||||
|
||||
def test_get_account_ids_for_expr(self):
|
||||
self.aep.done_parsing()
|
||||
expr = "balp[700IN]"
|
||||
account_ids = self.aep.get_account_ids_for_expr(expr)
|
||||
self.assertEqual(account_ids, {self.account_in.id})
|
||||
expr = "balp[700%]"
|
||||
account_ids = self.aep.get_account_ids_for_expr(expr)
|
||||
self.assertEqual(account_ids, {self.account_in.id})
|
||||
expr = "bali[400%], bale[700%]" # subkpis combined expression
|
||||
account_ids = self.aep.get_account_ids_for_expr(expr)
|
||||
self.assertEqual(account_ids, {self.account_in.id, self.account_ar.id})
|
||||
|
||||
def test_get_aml_domain_for_expr(self):
|
||||
self.aep.done_parsing()
|
||||
expr = "balp[700IN]"
|
||||
domain = self.aep.get_aml_domain_for_expr(expr, "2017-01-01", "2017-03-31")
|
||||
self.assertEqual(
|
||||
domain,
|
||||
[
|
||||
("account_id", "in", (self.account_in.id,)),
|
||||
"&",
|
||||
("date", ">=", "2017-01-01"),
|
||||
("date", "<=", "2017-03-31"),
|
||||
],
|
||||
)
|
||||
expr = "debi[700IN] - crdi[400AR]"
|
||||
domain = self.aep.get_aml_domain_for_expr(expr, "2017-02-01", "2017-03-31")
|
||||
self.assertEqual(
|
||||
domain,
|
||||
[
|
||||
"|",
|
||||
# debi[700IN]
|
||||
"&",
|
||||
("account_id", "in", (self.account_in.id,)),
|
||||
("debit", "<>", 0.0),
|
||||
# crdi[400AR]
|
||||
"&",
|
||||
("account_id", "in", (self.account_ar.id,)),
|
||||
("credit", "<>", 0.0),
|
||||
"&",
|
||||
# for P&L accounts, only after fy start
|
||||
"|",
|
||||
("date", ">=", "2017-01-01"),
|
||||
("account_id.include_initial_balance", "=", True),
|
||||
# everything must be before from_date for initial balance
|
||||
("date", "<", "2017-02-01"),
|
||||
],
|
||||
)
|
||||
|
||||
def test_is_domain(self):
|
||||
self.assertTrue(_is_domain("('a', '=' 1)"))
|
||||
self.assertTrue(_is_domain("'&', ('a', '=' 1), ('b', '=', 1)"))
|
||||
self.assertTrue(_is_domain("'|', ('a', '=' 1), ('b', '=', 1)"))
|
||||
self.assertTrue(_is_domain("'!', ('a', '=' 1), ('b', '=', 1)"))
|
||||
self.assertTrue(_is_domain("\"&\", ('a', '=' 1), ('b', '=', 1)"))
|
||||
self.assertTrue(_is_domain("\"|\", ('a', '=' 1), ('b', '=', 1)"))
|
||||
self.assertTrue(_is_domain("\"!\", ('a', '=' 1), ('b', '=', 1)"))
|
||||
self.assertFalse(_is_domain("123%"))
|
||||
self.assertFalse(_is_domain("123%,456"))
|
||||
self.assertFalse(_is_domain(""))
|
||||
|
||||
def test_inactive_tax(self):
|
||||
expr = 'balp[][("tax_ids.name", "=", "test tax")]'
|
||||
self.aep.parse_expr(expr)
|
||||
self.aep.done_parsing()
|
||||
|
||||
tax = self.env["account.tax"].create(
|
||||
dict(name="test tax", active=True, amount=0, company_id=self.company.id)
|
||||
)
|
||||
move = self._create_move(
|
||||
date=datetime.date(self.prev_year, 12, 1),
|
||||
amount=100,
|
||||
debit_acc=self.account_ar,
|
||||
credit_acc=self.account_in,
|
||||
post=False,
|
||||
)
|
||||
for ml in move.line_ids:
|
||||
if ml.credit:
|
||||
ml.write(dict(tax_ids=[(6, 0, [tax.id])]))
|
||||
tax.active = False
|
||||
move._post()
|
||||
# let's query for december 1st
|
||||
self._do_queries(
|
||||
datetime.date(self.prev_year, 12, 1), datetime.date(self.prev_year, 12, 1)
|
||||
)
|
||||
# let's see if there was a match
|
||||
self.assertEqual(self._eval(expr), -100)
|
||||
|
||||
def test_invalid_field(self):
|
||||
expr = 'balp[][("invalid_field", "=", "...")]'
|
||||
self.aep.parse_expr(expr)
|
||||
self.aep.done_parsing()
|
||||
with self.assertRaises(UserError) as cm:
|
||||
self._do_queries(
|
||||
datetime.date(self.prev_year, 12, 1),
|
||||
datetime.date(self.prev_year, 12, 1),
|
||||
)
|
||||
assert "Error while querying move line source" in str(cm.exception)
|
7
mis_builder/tests/test_aggregate.py
Normal file
7
mis_builder/tests/test_aggregate.py
Normal file
@ -0,0 +1,7 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from ..models import aggregate
|
||||
from .common import load_doctests
|
||||
|
||||
load_tests = load_doctests(aggregate)
|
219
mis_builder/tests/test_data_sources.py
Normal file
219
mis_builder/tests/test_data_sources.py
Normal file
@ -0,0 +1,219 @@
|
||||
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import flectra.tests.common as common
|
||||
|
||||
from ..models.accounting_none import AccountingNone
|
||||
from ..models.mis_report import CMP_DIFF
|
||||
from ..models.mis_report_instance import (
|
||||
MODE_NONE,
|
||||
SRC_ACTUALS_ALT,
|
||||
SRC_CMPCOL,
|
||||
SRC_SUMCOL,
|
||||
)
|
||||
from .common import assert_matrix
|
||||
|
||||
|
||||
class TestMisReportInstanceDataSources(common.TransactionCase):
|
||||
"""Test sum and comparison data source."""
|
||||
|
||||
def _create_move(self, date, amount, debit_acc, credit_acc):
|
||||
move = self.move_model.create(
|
||||
{
|
||||
"journal_id": self.journal.id,
|
||||
"date": date,
|
||||
"line_ids": [
|
||||
(0, 0, {"name": "/", "debit": amount, "account_id": debit_acc.id}),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{"name": "/", "credit": amount, "account_id": credit_acc.id},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
move._post()
|
||||
return move
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.account_model = self.env["account.account"]
|
||||
self.move_model = self.env["account.move"]
|
||||
self.journal_model = self.env["account.journal"]
|
||||
# create receivable bs account
|
||||
self.account_ar = self.account_model.create(
|
||||
{
|
||||
"company_id": self.env.user.company_id.id,
|
||||
"code": "400AR",
|
||||
"name": "Receivable",
|
||||
"account_type": "asset_receivable",
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
# create income account
|
||||
self.account_in = self.account_model.create(
|
||||
{
|
||||
"company_id": self.env.user.company_id.id,
|
||||
"code": "700IN",
|
||||
"name": "Income",
|
||||
"account_type": "income",
|
||||
}
|
||||
)
|
||||
self.account_in2 = self.account_model.create(
|
||||
{
|
||||
"company_id": self.env.user.company_id.id,
|
||||
"code": "700IN2",
|
||||
"name": "Income",
|
||||
"account_type": "income",
|
||||
}
|
||||
)
|
||||
# create journal
|
||||
self.journal = self.journal_model.create(
|
||||
{
|
||||
"company_id": self.env.user.company_id.id,
|
||||
"name": "Sale journal",
|
||||
"code": "VEN",
|
||||
"type": "sale",
|
||||
}
|
||||
)
|
||||
# create move
|
||||
self._create_move(
|
||||
date="2017-01-01",
|
||||
amount=11,
|
||||
debit_acc=self.account_ar,
|
||||
credit_acc=self.account_in,
|
||||
)
|
||||
# create move
|
||||
self._create_move(
|
||||
date="2017-02-01",
|
||||
amount=13,
|
||||
debit_acc=self.account_ar,
|
||||
credit_acc=self.account_in,
|
||||
)
|
||||
self._create_move(
|
||||
date="2017-02-01",
|
||||
amount=17,
|
||||
debit_acc=self.account_ar,
|
||||
credit_acc=self.account_in2,
|
||||
)
|
||||
# create report
|
||||
self.report = self.env["mis.report"].create(dict(name="test report"))
|
||||
self.kpi1 = self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report.id,
|
||||
name="k1",
|
||||
description="kpi 1",
|
||||
expression="-balp[700IN]",
|
||||
compare_method=CMP_DIFF,
|
||||
)
|
||||
)
|
||||
self.expr1 = self.kpi1.expression_ids[0]
|
||||
self.kpi2 = self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report.id,
|
||||
name="k2",
|
||||
description="kpi 2",
|
||||
expression="-balp[700%]",
|
||||
compare_method=CMP_DIFF,
|
||||
auto_expand_accounts=True,
|
||||
)
|
||||
)
|
||||
self.instance = self.env["mis.report.instance"].create(
|
||||
dict(name="test instance", report_id=self.report.id, comparison_mode=True)
|
||||
)
|
||||
self.p1 = self.env["mis.report.instance.period"].create(
|
||||
dict(
|
||||
name="p1",
|
||||
report_instance_id=self.instance.id,
|
||||
manual_date_from="2017-01-01",
|
||||
manual_date_to="2017-01-31",
|
||||
)
|
||||
)
|
||||
self.p2 = self.env["mis.report.instance.period"].create(
|
||||
dict(
|
||||
name="p2",
|
||||
report_instance_id=self.instance.id,
|
||||
manual_date_from="2017-02-01",
|
||||
manual_date_to="2017-02-28",
|
||||
)
|
||||
)
|
||||
|
||||
def test_sum(self):
|
||||
self.psum = self.env["mis.report.instance.period"].create(
|
||||
dict(
|
||||
name="psum",
|
||||
report_instance_id=self.instance.id,
|
||||
mode=MODE_NONE,
|
||||
source=SRC_SUMCOL,
|
||||
source_sumcol_ids=[
|
||||
(0, 0, dict(period_to_sum_id=self.p1.id, sign="+")),
|
||||
(0, 0, dict(period_to_sum_id=self.p2.id, sign="+")),
|
||||
],
|
||||
)
|
||||
)
|
||||
matrix = self.instance._compute_matrix()
|
||||
# None in last col because account details are not summed by default
|
||||
assert_matrix(
|
||||
matrix,
|
||||
[
|
||||
[11, 13, 24],
|
||||
[11, 30, 41],
|
||||
[11, 13, AccountingNone],
|
||||
[AccountingNone, 17, AccountingNone],
|
||||
],
|
||||
)
|
||||
|
||||
def test_sum_diff(self):
|
||||
self.psum = self.env["mis.report.instance.period"].create(
|
||||
dict(
|
||||
name="psum",
|
||||
report_instance_id=self.instance.id,
|
||||
mode=MODE_NONE,
|
||||
source=SRC_SUMCOL,
|
||||
source_sumcol_ids=[
|
||||
(0, 0, dict(period_to_sum_id=self.p1.id, sign="+")),
|
||||
(0, 0, dict(period_to_sum_id=self.p2.id, sign="-")),
|
||||
],
|
||||
source_sumcol_accdet=True,
|
||||
)
|
||||
)
|
||||
matrix = self.instance._compute_matrix()
|
||||
assert_matrix(
|
||||
matrix,
|
||||
[[11, 13, -2], [11, 30, -19], [11, 13, -2], [AccountingNone, 17, -17]],
|
||||
)
|
||||
|
||||
def test_cmp(self):
|
||||
self.pcmp = self.env["mis.report.instance.period"].create(
|
||||
dict(
|
||||
name="pcmp",
|
||||
report_instance_id=self.instance.id,
|
||||
mode=MODE_NONE,
|
||||
source=SRC_CMPCOL,
|
||||
source_cmpcol_from_id=self.p1.id,
|
||||
source_cmpcol_to_id=self.p2.id,
|
||||
)
|
||||
)
|
||||
matrix = self.instance._compute_matrix()
|
||||
assert_matrix(
|
||||
matrix, [[11, 13, 2], [11, 30, 19], [11, 13, 2], [AccountingNone, 17, 17]]
|
||||
)
|
||||
|
||||
def test_actuals(self):
|
||||
matrix = self.instance._compute_matrix()
|
||||
assert_matrix(matrix, [[11, 13], [11, 30], [11, 13], [AccountingNone, 17]])
|
||||
|
||||
def test_actuals_disable_auto_expand_accounts(self):
|
||||
self.instance.no_auto_expand_accounts = True
|
||||
matrix = self.instance._compute_matrix()
|
||||
assert_matrix(matrix, [[11, 13], [11, 30]])
|
||||
|
||||
def test_actuals_alt(self):
|
||||
aml_model = self.env["ir.model"].search([("name", "=", "account.move.line")])
|
||||
self.kpi2.auto_expand_accounts = False
|
||||
self.p1.source = SRC_ACTUALS_ALT
|
||||
self.p1.source_aml_model_id = aml_model.id
|
||||
self.p2.source = SRC_ACTUALS_ALT
|
||||
self.p1.source_aml_model_id = aml_model.id
|
||||
matrix = self.instance._compute_matrix()
|
||||
assert_matrix(matrix, [[11, 13], [11, 30]])
|
142
mis_builder/tests/test_kpi_data.py
Normal file
142
mis_builder/tests/test_kpi_data.py
Normal file
@ -0,0 +1,142 @@
|
||||
# Copyright 2017 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from flectra_test_helper import FakeModelLoader
|
||||
|
||||
from flectra.tests.common import TransactionCase
|
||||
|
||||
from ..models.mis_kpi_data import ACC_AVG, ACC_SUM
|
||||
|
||||
|
||||
class TestKpiData(TransactionCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
cls.loader = FakeModelLoader(cls.env, cls.__module__)
|
||||
cls.loader.backup_registry()
|
||||
from .fake_models import MisKpiDataTestItem
|
||||
|
||||
cls.loader.update_registry((MisKpiDataTestItem,))
|
||||
|
||||
report = cls.env["mis.report"].create(dict(name="test report"))
|
||||
cls.kpi1 = cls.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=report.id,
|
||||
name="k1",
|
||||
description="kpi 1",
|
||||
expression="AccountingNone",
|
||||
)
|
||||
)
|
||||
cls.expr1 = cls.kpi1.expression_ids[0]
|
||||
cls.kpi2 = cls.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=report.id,
|
||||
name="k2",
|
||||
description="kpi 2",
|
||||
expression="AccountingNone",
|
||||
)
|
||||
)
|
||||
cls.expr2 = cls.kpi2.expression_ids[0]
|
||||
cls.kd11 = cls.env["mis.kpi.data.test.item"].create(
|
||||
dict(
|
||||
kpi_expression_id=cls.expr1.id,
|
||||
date_from="2017-05-01",
|
||||
date_to="2017-05-10",
|
||||
amount=10,
|
||||
)
|
||||
)
|
||||
cls.kd12 = cls.env["mis.kpi.data.test.item"].create(
|
||||
dict(
|
||||
kpi_expression_id=cls.expr1.id,
|
||||
date_from="2017-05-11",
|
||||
date_to="2017-05-20",
|
||||
amount=20,
|
||||
)
|
||||
)
|
||||
cls.kd13 = cls.env["mis.kpi.data.test.item"].create(
|
||||
dict(
|
||||
kpi_expression_id=cls.expr1.id,
|
||||
date_from="2017-05-21",
|
||||
date_to="2017-05-25",
|
||||
amount=30,
|
||||
)
|
||||
)
|
||||
cls.kd21 = cls.env["mis.kpi.data.test.item"].create(
|
||||
dict(
|
||||
kpi_expression_id=cls.expr2.id,
|
||||
date_from="2017-06-01",
|
||||
date_to="2017-06-30",
|
||||
amount=3,
|
||||
)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.loader.restore_registry()
|
||||
return super().tearDownClass()
|
||||
|
||||
def test_kpi_data_name(self):
|
||||
self.assertEqual(self.kd11.name, "k1: 2017-05-01 - 2017-05-10")
|
||||
self.assertEqual(self.kd12.name, "k1: 2017-05-11 - 2017-05-20")
|
||||
|
||||
def test_kpi_data_sum(self):
|
||||
self.assertEqual(self.kpi1.accumulation_method, ACC_SUM)
|
||||
# one full
|
||||
r = self.env["mis.kpi.data.test.item"]._query_kpi_data(
|
||||
"2017-05-01", "2017-05-10", []
|
||||
)
|
||||
self.assertEqual(r, {self.expr1: 10})
|
||||
# one half
|
||||
r = self.env["mis.kpi.data.test.item"]._query_kpi_data(
|
||||
"2017-05-01", "2017-05-05", []
|
||||
)
|
||||
self.assertEqual(r, {self.expr1: 5})
|
||||
# two full
|
||||
r = self.env["mis.kpi.data.test.item"]._query_kpi_data(
|
||||
"2017-05-01", "2017-05-20", []
|
||||
)
|
||||
self.assertEqual(r, {self.expr1: 30})
|
||||
# two half
|
||||
r = self.env["mis.kpi.data.test.item"]._query_kpi_data(
|
||||
"2017-05-06", "2017-05-15", []
|
||||
)
|
||||
self.assertEqual(r, {self.expr1: 15})
|
||||
# more than covered range
|
||||
r = self.env["mis.kpi.data.test.item"]._query_kpi_data(
|
||||
"2017-01-01", "2017-05-31", []
|
||||
)
|
||||
self.assertEqual(r, {self.expr1: 60})
|
||||
# two kpis
|
||||
r = self.env["mis.kpi.data.test.item"]._query_kpi_data(
|
||||
"2017-05-21", "2017-06-30", []
|
||||
)
|
||||
self.assertEqual(r, {self.expr1: 30, self.expr2: 3})
|
||||
|
||||
def test_kpi_data_avg(self):
|
||||
self.kpi1.accumulation_method = ACC_AVG
|
||||
# one full
|
||||
r = self.env["mis.kpi.data.test.item"]._query_kpi_data(
|
||||
"2017-05-01", "2017-05-10", []
|
||||
)
|
||||
self.assertEqual(r, {self.expr1: 10})
|
||||
# one half
|
||||
r = self.env["mis.kpi.data.test.item"]._query_kpi_data(
|
||||
"2017-05-01", "2017-05-05", []
|
||||
)
|
||||
self.assertEqual(r, {self.expr1: 10})
|
||||
# two full
|
||||
r = self.env["mis.kpi.data.test.item"]._query_kpi_data(
|
||||
"2017-05-01", "2017-05-20", []
|
||||
)
|
||||
self.assertEqual(r, {self.expr1: (10 * 10 + 20 * 10) / 20})
|
||||
# two half
|
||||
r = self.env["mis.kpi.data.test.item"]._query_kpi_data(
|
||||
"2017-05-06", "2017-05-15", []
|
||||
)
|
||||
self.assertEqual(r, {self.expr1: (10 * 5 + 20 * 5) / 10})
|
||||
# more than covered range
|
||||
r = self.env["mis.kpi.data.test.item"]._query_kpi_data(
|
||||
"2017-01-01", "2017-05-31", []
|
||||
)
|
||||
self.assertEqual(r, {self.expr1: (10 * 10 + 20 * 10 + 30 * 5) / 25})
|
589
mis_builder/tests/test_mis_report_instance.py
Normal file
589
mis_builder/tests/test_mis_report_instance.py
Normal file
@ -0,0 +1,589 @@
|
||||
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import flectra.tests.common as common
|
||||
from flectra.tools import test_reports
|
||||
|
||||
from ..models.accounting_none import AccountingNone
|
||||
from ..models.mis_report import TYPE_STR, SubKPITupleLengthError, SubKPIUnknownTypeError
|
||||
|
||||
|
||||
class TestMisReportInstance(common.HttpCase):
|
||||
"""Basic integration test to exercise mis.report.instance.
|
||||
|
||||
We don't check the actual results here too much as computation correctness
|
||||
should be covered by lower level unit tests.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
partner_model_id = self.env.ref("base.model_res_partner").id
|
||||
partner_create_date_field_id = self.env.ref(
|
||||
"base.field_res_partner__create_date"
|
||||
).id
|
||||
partner_debit_field_id = self.env.ref("account.field_res_partner__debit").id
|
||||
# create a report with 2 subkpis and one query
|
||||
self.report = self.env["mis.report"].create(
|
||||
dict(
|
||||
name="test report",
|
||||
subkpi_ids=[
|
||||
(0, 0, dict(name="sk1", description="subkpi 1", sequence=1)),
|
||||
(0, 0, dict(name="sk2", description="subkpi 2", sequence=2)),
|
||||
],
|
||||
query_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="partner",
|
||||
model_id=partner_model_id,
|
||||
field_ids=[(4, partner_debit_field_id, None)],
|
||||
date_field=partner_create_date_field_id,
|
||||
aggregate="sum",
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
# create another report with 2 subkpis, no query
|
||||
self.report_2 = self.env["mis.report"].create(
|
||||
dict(
|
||||
name="another test report",
|
||||
subkpi_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="subkpi1_report2",
|
||||
description="subkpi 1, report 2",
|
||||
sequence=1,
|
||||
),
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="subkpi2_report2",
|
||||
description="subkpi 2, report 2",
|
||||
sequence=2,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
)
|
||||
# Third report, 2 subkpis, no query
|
||||
self.report_3 = self.env["mis.report"].create(
|
||||
dict(
|
||||
name="test report 3",
|
||||
subkpi_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="subkpi1_report3",
|
||||
description="subkpi 1, report 3",
|
||||
sequence=1,
|
||||
),
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="subkpi2_report3",
|
||||
description="subkpi 2, report 3",
|
||||
sequence=2,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
)
|
||||
# kpi with accounting formulas
|
||||
self.kpi1 = self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report.id,
|
||||
description="kpi 1",
|
||||
name="k1",
|
||||
multi=True,
|
||||
expression_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(name="bale[200%]", subkpi_id=self.report.subkpi_ids[0].id),
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(name="balp[200%]", subkpi_id=self.report.subkpi_ids[1].id),
|
||||
),
|
||||
],
|
||||
)
|
||||
)
|
||||
# kpi with accounting formula and query
|
||||
self.kpi2 = self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report.id,
|
||||
description="kpi 2",
|
||||
name="k2",
|
||||
multi=True,
|
||||
expression_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(name="balp[200%]", subkpi_id=self.report.subkpi_ids[0].id),
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="partner.debit", subkpi_id=self.report.subkpi_ids[1].id
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
)
|
||||
# kpi with a simple expression summing other multi-valued kpis
|
||||
self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report.id,
|
||||
description="kpi 4",
|
||||
name="k4",
|
||||
multi=False,
|
||||
expression="k1 + k2 + k3",
|
||||
)
|
||||
)
|
||||
# kpi with 2 constants
|
||||
self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report.id,
|
||||
description="kpi 3",
|
||||
name="k3",
|
||||
multi=True,
|
||||
expression_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="AccountingNone",
|
||||
subkpi_id=self.report.subkpi_ids[0].id,
|
||||
),
|
||||
),
|
||||
(0, 0, dict(name="1.0", subkpi_id=self.report.subkpi_ids[1].id)),
|
||||
],
|
||||
)
|
||||
)
|
||||
# kpi with a NameError (x not defined)
|
||||
self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report.id,
|
||||
description="kpi 5",
|
||||
name="k5",
|
||||
multi=True,
|
||||
expression_ids=[
|
||||
(0, 0, dict(name="x", subkpi_id=self.report.subkpi_ids[0].id)),
|
||||
(0, 0, dict(name="1.0", subkpi_id=self.report.subkpi_ids[1].id)),
|
||||
],
|
||||
)
|
||||
)
|
||||
# string-type kpi
|
||||
self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report.id,
|
||||
description="kpi 6",
|
||||
name="k6",
|
||||
multi=True,
|
||||
type=TYPE_STR,
|
||||
expression_ids=[
|
||||
(0, 0, dict(name='"bla"', subkpi_id=self.report.subkpi_ids[0].id)),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(name='"blabla"', subkpi_id=self.report.subkpi_ids[1].id),
|
||||
),
|
||||
],
|
||||
)
|
||||
)
|
||||
# kpi that references another subkpi by name
|
||||
self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report.id,
|
||||
description="kpi 7",
|
||||
name="k7",
|
||||
multi=True,
|
||||
expression_ids=[
|
||||
(0, 0, dict(name="k3.sk1", subkpi_id=self.report.subkpi_ids[0].id)),
|
||||
(0, 0, dict(name="k3.sk2", subkpi_id=self.report.subkpi_ids[1].id)),
|
||||
],
|
||||
)
|
||||
)
|
||||
# Report 2 : kpi with AccountingNone value
|
||||
self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report_2.id,
|
||||
description="AccountingNone kpi",
|
||||
name="AccountingNoneKPI",
|
||||
multi=False,
|
||||
)
|
||||
)
|
||||
# Report 2 : 'classic' kpi with values for each sub-KPI
|
||||
self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report_2.id,
|
||||
description="Classic kpi",
|
||||
name="classic_kpi_r2",
|
||||
multi=True,
|
||||
expression_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="bale[200%]", subkpi_id=self.report_2.subkpi_ids[0].id
|
||||
),
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="balp[200%]", subkpi_id=self.report_2.subkpi_ids[1].id
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
)
|
||||
# Report 3 : kpi with wrong tuple length
|
||||
self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report_3.id,
|
||||
description="Wrong tuple length kpi",
|
||||
name="wrongTupleLen",
|
||||
multi=False,
|
||||
expression="('hello', 'does', 'this', 'work')",
|
||||
)
|
||||
)
|
||||
# Report 3 : 'classic' kpi
|
||||
self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report_3.id,
|
||||
description="Classic kpi",
|
||||
name="classic_kpi_r2",
|
||||
multi=True,
|
||||
expression_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="bale[200%]", subkpi_id=self.report_3.subkpi_ids[0].id
|
||||
),
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="balp[200%]", subkpi_id=self.report_3.subkpi_ids[1].id
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
)
|
||||
# create a report instance
|
||||
self.report_instance = self.env["mis.report.instance"].create(
|
||||
dict(
|
||||
name="test instance",
|
||||
report_id=self.report.id,
|
||||
company_id=self.env.ref("base.main_company").id,
|
||||
period_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="p1",
|
||||
mode="relative",
|
||||
type="d",
|
||||
subkpi_ids=[(4, self.report.subkpi_ids[0].id, None)],
|
||||
),
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="p2",
|
||||
mode="fix",
|
||||
manual_date_from="2014-01-01",
|
||||
manual_date_to="2014-12-31",
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
)
|
||||
# same for report 2
|
||||
self.report_instance_2 = self.env["mis.report.instance"].create(
|
||||
dict(
|
||||
name="test instance 2",
|
||||
report_id=self.report_2.id,
|
||||
company_id=self.env.ref("base.main_company").id,
|
||||
period_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="p3",
|
||||
mode="fix",
|
||||
manual_date_from="2019-01-01",
|
||||
manual_date_to="2019-12-31",
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
# and for report 3
|
||||
self.report_instance_3 = self.env["mis.report.instance"].create(
|
||||
dict(
|
||||
name="test instance 3",
|
||||
report_id=self.report_3.id,
|
||||
company_id=self.env.ref("base.main_company").id,
|
||||
period_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(
|
||||
name="p4",
|
||||
mode="fix",
|
||||
manual_date_from="2019-01-01",
|
||||
manual_date_to="2019-12-31",
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
def test_compute(self):
|
||||
matrix = self.report_instance._compute_matrix()
|
||||
for row in matrix.iter_rows():
|
||||
vals = [c.val for c in row.iter_cells()]
|
||||
if row.kpi.name == "k3":
|
||||
# k3 is constant
|
||||
self.assertEqual(vals, [AccountingNone, AccountingNone, 1.0])
|
||||
elif row.kpi.name == "k6":
|
||||
# k6 is a string kpi
|
||||
self.assertEqual(vals, ["bla", "bla", "blabla"])
|
||||
elif row.kpi.name == "k7":
|
||||
# k7 references k3 via subkpi names
|
||||
self.assertEqual(vals, [AccountingNone, AccountingNone, 1.0])
|
||||
|
||||
def test_multi_company_compute(self):
|
||||
self.report_instance.write(
|
||||
{
|
||||
"multi_company": True,
|
||||
"company_ids": [(6, 0, self.report_instance.company_id.ids)],
|
||||
}
|
||||
)
|
||||
self.report_instance.report_id.kpi_ids.write({"auto_expand_accounts": True})
|
||||
matrix = self.report_instance._compute_matrix()
|
||||
for row in matrix.iter_rows():
|
||||
if row.account_id:
|
||||
account = self.env["account.account"].browse(row.account_id)
|
||||
self.assertEqual(
|
||||
row.label,
|
||||
f"{account.code} {account.name} [{account.company_id.name}]",
|
||||
)
|
||||
self.report_instance.write({"multi_company": False})
|
||||
matrix = self.report_instance._compute_matrix()
|
||||
for row in matrix.iter_rows():
|
||||
if row.account_id:
|
||||
account = self.env["account.account"].browse(row.account_id)
|
||||
self.assertEqual(row.label, f"{account.code} {account.name}")
|
||||
|
||||
def test_evaluate(self):
|
||||
company = self.env.ref("base.main_company")
|
||||
aep = self.report._prepare_aep(company)
|
||||
r = self.report.evaluate(aep, date_from="2014-01-01", date_to="2014-12-31")
|
||||
self.assertEqual(r["k3"], (AccountingNone, 1.0))
|
||||
self.assertEqual(r["k6"], ("bla", "blabla"))
|
||||
self.assertEqual(r["k7"], (AccountingNone, 1.0))
|
||||
|
||||
def test_json(self):
|
||||
self.report_instance.compute()
|
||||
|
||||
def test_drilldown(self):
|
||||
action = self.report_instance.drilldown(
|
||||
dict(expr="balp[200%]", period_id=self.report_instance.period_ids[0].id)
|
||||
)
|
||||
account_ids = (
|
||||
self.env["account.account"]
|
||||
.search(
|
||||
[
|
||||
("code", "=like", "200%"),
|
||||
("company_id", "=", self.env.ref("base.main_company").id),
|
||||
]
|
||||
)
|
||||
.ids
|
||||
)
|
||||
self.assertTrue(("account_id", "in", tuple(account_ids)) in action["domain"])
|
||||
self.assertEqual(action["res_model"], "account.move.line")
|
||||
|
||||
def test_drilldown_action_name_with_account(self):
|
||||
period = self.report_instance.period_ids[0]
|
||||
account = self.env["account.account"].search([], limit=1)
|
||||
args = {
|
||||
"period_id": period.id,
|
||||
"kpi_id": self.kpi1.id,
|
||||
"account_id": account.id,
|
||||
}
|
||||
action_name = self.report_instance._get_drilldown_action_name(args)
|
||||
expected_name = "{kpi} - {account} - {period}".format(
|
||||
kpi=self.kpi1.description,
|
||||
account=account.display_name,
|
||||
period=period.display_name,
|
||||
)
|
||||
assert action_name == expected_name
|
||||
|
||||
def test_drilldown_action_name_without_account(self):
|
||||
period = self.report_instance.period_ids[0]
|
||||
args = {
|
||||
"period_id": period.id,
|
||||
"kpi_id": self.kpi1.id,
|
||||
}
|
||||
action_name = self.report_instance._get_drilldown_action_name(args)
|
||||
expected_name = f"{self.kpi1.description} - {period.display_name}"
|
||||
assert action_name == expected_name
|
||||
|
||||
def test_qweb(self):
|
||||
self.report_instance.print_pdf() # get action
|
||||
test_reports.try_report(
|
||||
self.env.cr,
|
||||
self.env.uid,
|
||||
"mis_builder.report_mis_report_instance",
|
||||
[self.report_instance.id],
|
||||
report_type="qweb-pdf",
|
||||
)
|
||||
|
||||
def test_xlsx(self):
|
||||
self.report_instance.export_xls() # get action
|
||||
test_reports.try_report(
|
||||
self.env.cr,
|
||||
self.env.uid,
|
||||
"mis_builder.mis_report_instance_xlsx",
|
||||
[self.report_instance.id],
|
||||
report_type="xlsx",
|
||||
)
|
||||
|
||||
def test_get_kpis_by_account_id(self):
|
||||
account_ids = (
|
||||
self.env["account.account"]
|
||||
.search(
|
||||
[
|
||||
("code", "=like", "200%"),
|
||||
("company_id", "=", self.env.ref("base.main_company").id),
|
||||
]
|
||||
)
|
||||
.ids
|
||||
)
|
||||
kpi200 = {self.kpi1, self.kpi2}
|
||||
res = self.report.get_kpis_by_account_id(self.env.ref("base.main_company"))
|
||||
for account_id in account_ids:
|
||||
self.assertTrue(account_id in res)
|
||||
self.assertEqual(res[account_id], kpi200)
|
||||
|
||||
def test_kpi_name_get_name_search(self):
|
||||
r = self.env["mis.report.kpi"].name_search("k1")
|
||||
self.assertEqual(len(r), 1)
|
||||
self.assertEqual(r[0][0], self.kpi1.id)
|
||||
self.assertEqual(r[0][1], "kpi 1 (k1)")
|
||||
r = self.env["mis.report.kpi"].name_search("kpi 1")
|
||||
self.assertEqual(len(r), 1)
|
||||
self.assertEqual(r[0][0], self.kpi1.id)
|
||||
self.assertEqual(r[0][1], "kpi 1 (k1)")
|
||||
|
||||
def test_kpi_expr_name_get_name_search(self):
|
||||
r = self.env["mis.report.kpi.expression"].name_search("k1")
|
||||
self.assertEqual(
|
||||
[i[1] for i in r],
|
||||
["kpi 1 / subkpi 1 (k1.sk1)", "kpi 1 / subkpi 2 (k1.sk2)"],
|
||||
)
|
||||
r = self.env["mis.report.kpi.expression"].name_search("k1.sk1")
|
||||
self.assertEqual([i[1] for i in r], ["kpi 1 / subkpi 1 (k1.sk1)"])
|
||||
r = self.env["mis.report.kpi.expression"].name_search("k4")
|
||||
self.assertEqual([i[1] for i in r], ["kpi 4 (k4)"])
|
||||
|
||||
def test_query_company_ids(self):
|
||||
# sanity check single company mode
|
||||
assert not self.report_instance.multi_company
|
||||
assert self.report_instance.company_id
|
||||
assert self.report_instance.query_company_ids == self.report_instance.company_id
|
||||
# create a second company
|
||||
c1 = self.report_instance.company_id
|
||||
c2 = self.env["res.company"].create(
|
||||
dict(
|
||||
name="company 2",
|
||||
)
|
||||
)
|
||||
self.report_instance.write(dict(multi_company=True, company_id=False))
|
||||
self.report_instance.company_ids |= c1
|
||||
self.report_instance.company_ids |= c2
|
||||
assert len(self.report_instance.company_ids) == 2
|
||||
self.assertFalse(self.report_instance.query_company_ids - self.env.companies)
|
||||
# In a user context where there is only one company, ensure
|
||||
# query_company_ids only has one company too.
|
||||
assert (
|
||||
self.report_instance.with_context(
|
||||
allowed_company_ids=(c1.id,)
|
||||
).query_company_ids
|
||||
== c1
|
||||
)
|
||||
|
||||
def test_multi_company_onchange(self):
|
||||
# not multi company
|
||||
self.assertTrue(self.report_instance.company_id)
|
||||
self.assertFalse(self.report_instance.multi_company)
|
||||
self.assertFalse(self.report_instance.company_ids)
|
||||
self.assertEqual(
|
||||
self.report_instance.query_company_ids[0], self.report_instance.company_id
|
||||
)
|
||||
# create a child company
|
||||
self.env["res.company"].create(
|
||||
dict(name="company 2", parent_id=self.report_instance.company_id.id)
|
||||
)
|
||||
self.report_instance.multi_company = True
|
||||
# multi company, company_ids not set
|
||||
self.assertEqual(self.report_instance.query_company_ids, self.env.companies)
|
||||
# set company_ids
|
||||
previous_company = self.report_instance.company_id
|
||||
self.report_instance._onchange_company()
|
||||
self.assertFalse(self.report_instance.company_id)
|
||||
self.assertTrue(self.report_instance.multi_company)
|
||||
self.assertEqual(self.report_instance.company_ids, previous_company)
|
||||
self.assertEqual(self.report_instance.query_company_ids, previous_company)
|
||||
# reset single company mode
|
||||
self.report_instance.multi_company = False
|
||||
self.report_instance._onchange_company()
|
||||
self.assertEqual(
|
||||
self.report_instance.query_company_ids[0], self.report_instance.company_id
|
||||
)
|
||||
self.assertFalse(self.report_instance.company_ids)
|
||||
|
||||
def test_mis_report_analytic_filters(self):
|
||||
# Check that matrix has no values when using a filter with a non existing value
|
||||
matrix = self.report_instance.with_context(
|
||||
analytic_domain=[("partner_id", "=", -1)]
|
||||
)._compute_matrix()
|
||||
for row in matrix.iter_rows():
|
||||
vals = [c.val for c in row.iter_cells()]
|
||||
if row.kpi.name == "k1":
|
||||
self.assertEqual(vals, [AccountingNone, AccountingNone, AccountingNone])
|
||||
elif row.kpi.name == "k2":
|
||||
self.assertEqual(vals, [AccountingNone, AccountingNone, None])
|
||||
elif row.kpi.name == "k4":
|
||||
self.assertEqual(vals, [AccountingNone, AccountingNone, 1.0])
|
||||
|
||||
def test_raise_when_unknown_kpi_value_type(self):
|
||||
with self.assertRaises(SubKPIUnknownTypeError):
|
||||
self.report_instance_2.compute()
|
||||
|
||||
def test_raise_when_wrong_tuple_length_with_subkpis(self):
|
||||
with self.assertRaises(SubKPITupleLengthError):
|
||||
self.report_instance_3.compute()
|
||||
|
||||
def test_unprivileged(self):
|
||||
test_user = common.new_test_user(
|
||||
self.env, "mis_you", groups="base.group_user,account.group_account_readonly"
|
||||
)
|
||||
self.report_instance.with_user(test_user).compute()
|
25
mis_builder/tests/test_mis_safe_eval.py
Normal file
25
mis_builder/tests/test_mis_safe_eval.py
Normal file
@ -0,0 +1,25 @@
|
||||
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import flectra.tests.common as common
|
||||
|
||||
from ..models.mis_safe_eval import DataError, NameDataError, mis_safe_eval
|
||||
|
||||
|
||||
class TestMisSafeEval(common.TransactionCase):
|
||||
def test_nominal(self):
|
||||
val = mis_safe_eval("a + 1", {"a": 1})
|
||||
self.assertEqual(val, 2)
|
||||
|
||||
def test_exceptions(self):
|
||||
val = mis_safe_eval("1/0", {}) # division by zero
|
||||
self.assertTrue(isinstance(val, DataError))
|
||||
self.assertEqual(val.name, "#DIV/0")
|
||||
val = mis_safe_eval("1a", {}) # syntax error
|
||||
self.assertTrue(isinstance(val, DataError))
|
||||
self.assertEqual(val.name, "#ERR")
|
||||
|
||||
def test_name_error(self):
|
||||
val = mis_safe_eval("a + 1", {})
|
||||
self.assertTrue(isinstance(val, NameDataError))
|
||||
self.assertEqual(val.name, "#NAME")
|
208
mis_builder/tests/test_multi_company_aep.py
Normal file
208
mis_builder/tests/test_multi_company_aep.py
Normal file
@ -0,0 +1,208 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import datetime
|
||||
|
||||
import flectra.tests.common as common
|
||||
from flectra import fields
|
||||
from flectra.tools.safe_eval import safe_eval
|
||||
|
||||
from ..models.accounting_none import AccountingNone
|
||||
from ..models.aep import AccountingExpressionProcessor as AEP
|
||||
|
||||
|
||||
class TestMultiCompanyAEP(common.TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.res_company = self.env["res.company"]
|
||||
self.account_model = self.env["account.account"]
|
||||
self.move_model = self.env["account.move"]
|
||||
self.journal_model = self.env["account.journal"]
|
||||
self.currency_model = self.env["res.currency"]
|
||||
self.curr_year = datetime.date.today().year
|
||||
self.prev_year = self.curr_year - 1
|
||||
self.usd = self.currency_model.with_context(active_test=False).search(
|
||||
[("name", "=", "USD")]
|
||||
)
|
||||
self.eur = self.currency_model.with_context(active_test=False).search(
|
||||
[("name", "=", "EUR")]
|
||||
)
|
||||
# create company A and B
|
||||
self.company_eur = self.res_company.create(
|
||||
{"name": "CYEUR", "currency_id": self.eur.id}
|
||||
)
|
||||
self.company_usd = self.res_company.create(
|
||||
{"name": "CYUSD", "currency_id": self.usd.id}
|
||||
)
|
||||
self.env["res.currency.rate"].search([]).unlink()
|
||||
for company, divider in [(self.company_eur, 1.0), (self.company_usd, 2.0)]:
|
||||
# create receivable bs account
|
||||
company_key = company.name
|
||||
setattr(
|
||||
self,
|
||||
"account_ar_" + company_key,
|
||||
self.account_model.create(
|
||||
{
|
||||
"company_id": company.id,
|
||||
"code": "400AR",
|
||||
"name": "Receivable",
|
||||
"account_type": "asset_receivable",
|
||||
"reconcile": True,
|
||||
}
|
||||
),
|
||||
)
|
||||
# create income pl account
|
||||
setattr(
|
||||
self,
|
||||
"account_in_" + company_key,
|
||||
self.account_model.create(
|
||||
{
|
||||
"company_id": company.id,
|
||||
"code": "700IN",
|
||||
"name": "Income",
|
||||
"account_type": "income",
|
||||
}
|
||||
),
|
||||
)
|
||||
# create journal
|
||||
setattr(
|
||||
self,
|
||||
"journal" + company_key,
|
||||
self.journal_model.create(
|
||||
{
|
||||
"company_id": company.id,
|
||||
"name": "Sale journal",
|
||||
"code": "VEN",
|
||||
"type": "sale",
|
||||
}
|
||||
),
|
||||
)
|
||||
# create move in december last year
|
||||
self._create_move(
|
||||
journal=getattr(self, "journal" + company_key),
|
||||
date=datetime.date(self.prev_year, 12, 1),
|
||||
amount=100 / divider,
|
||||
debit_acc=getattr(self, "account_ar_" + company_key),
|
||||
credit_acc=getattr(self, "account_in_" + company_key),
|
||||
)
|
||||
# create move in january this year
|
||||
self._create_move(
|
||||
journal=getattr(self, "journal" + company_key),
|
||||
date=datetime.date(self.curr_year, 1, 1),
|
||||
amount=300 / divider,
|
||||
debit_acc=getattr(self, "account_ar_" + company_key),
|
||||
credit_acc=getattr(self, "account_in_" + company_key),
|
||||
)
|
||||
# create move in february this year
|
||||
self._create_move(
|
||||
journal=getattr(self, "journal" + company_key),
|
||||
date=datetime.date(self.curr_year, 3, 1),
|
||||
amount=500 / divider,
|
||||
debit_acc=getattr(self, "account_ar_" + company_key),
|
||||
credit_acc=getattr(self, "account_in_" + company_key),
|
||||
)
|
||||
|
||||
def _create_move(self, journal, date, amount, debit_acc, credit_acc):
|
||||
move = self.move_model.create(
|
||||
{
|
||||
"journal_id": journal.id,
|
||||
"date": fields.Date.to_string(date),
|
||||
"line_ids": [
|
||||
(0, 0, {"name": "/", "debit": amount, "account_id": debit_acc.id}),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{"name": "/", "credit": amount, "account_id": credit_acc.id},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
move._post()
|
||||
return move
|
||||
|
||||
def _do_queries(self, companies, currency, date_from, date_to):
|
||||
# create the AEP, and prepare the expressions we'll need
|
||||
aep = AEP(companies, currency)
|
||||
aep.parse_expr("bali[]")
|
||||
aep.parse_expr("bale[]")
|
||||
aep.parse_expr("balp[]")
|
||||
aep.parse_expr("balu[]")
|
||||
aep.parse_expr("bali[700IN]")
|
||||
aep.parse_expr("bale[700IN]")
|
||||
aep.parse_expr("balp[700IN]")
|
||||
aep.parse_expr("bali[400AR]")
|
||||
aep.parse_expr("bale[400AR]")
|
||||
aep.parse_expr("balp[400AR]")
|
||||
aep.parse_expr("debp[400A%]")
|
||||
aep.parse_expr("crdp[700I%]")
|
||||
aep.parse_expr("bali[400%]")
|
||||
aep.parse_expr("bale[700%]")
|
||||
aep.done_parsing()
|
||||
aep.do_queries(
|
||||
date_from=fields.Date.to_string(date_from),
|
||||
date_to=fields.Date.to_string(date_to),
|
||||
)
|
||||
return aep
|
||||
|
||||
def _eval(self, aep, expr):
|
||||
eval_dict = {"AccountingNone": AccountingNone}
|
||||
return safe_eval(aep.replace_expr(expr), eval_dict)
|
||||
|
||||
def _eval_by_account_id(self, aep, expr):
|
||||
res = {}
|
||||
eval_dict = {"AccountingNone": AccountingNone}
|
||||
for account_id, replaced_exprs in aep.replace_exprs_by_account_id([expr]):
|
||||
res[account_id] = safe_eval(replaced_exprs[0], eval_dict)
|
||||
return res
|
||||
|
||||
def test_aep_basic(self):
|
||||
# let's query for december, one company
|
||||
aep = self._do_queries(
|
||||
self.company_eur,
|
||||
None,
|
||||
datetime.date(self.prev_year, 12, 1),
|
||||
datetime.date(self.prev_year, 12, 31),
|
||||
)
|
||||
self.assertEqual(self._eval(aep, "balp[700IN]"), -100)
|
||||
aep = self._do_queries(
|
||||
self.company_usd,
|
||||
None,
|
||||
datetime.date(self.prev_year, 12, 1),
|
||||
datetime.date(self.prev_year, 12, 31),
|
||||
)
|
||||
self.assertEqual(self._eval(aep, "balp[700IN]"), -50)
|
||||
# let's query for december, two companies
|
||||
aep = self._do_queries(
|
||||
self.company_eur | self.company_usd,
|
||||
self.eur,
|
||||
datetime.date(self.prev_year, 12, 1),
|
||||
datetime.date(self.prev_year, 12, 31),
|
||||
)
|
||||
self.assertEqual(self._eval(aep, "balp[700IN]"), -150)
|
||||
|
||||
def test_aep_multi_currency(self):
|
||||
date_from = datetime.date(self.prev_year, 12, 1)
|
||||
date_to = datetime.date(self.prev_year, 12, 31)
|
||||
today = datetime.date.today()
|
||||
self.env["res.currency.rate"].create(
|
||||
dict(currency_id=self.usd.id, name=date_to, rate=1.1)
|
||||
)
|
||||
self.env["res.currency.rate"].create(
|
||||
dict(currency_id=self.usd.id, name=today, rate=1.2)
|
||||
)
|
||||
# let's query for december, one company, default currency = eur
|
||||
aep = self._do_queries(self.company_eur, None, date_from, date_to)
|
||||
self.assertEqual(self._eval(aep, "balp[700IN]"), -100)
|
||||
# let's query for december, two companies
|
||||
aep = self._do_queries(
|
||||
self.company_eur | self.company_usd, self.eur, date_from, date_to
|
||||
)
|
||||
self.assertAlmostEqual(self._eval(aep, "balp[700IN]"), -100 - 50 / 1.1)
|
||||
# let's query for december, one company, currency = usd
|
||||
aep = self._do_queries(self.company_eur, self.usd, date_from, date_to)
|
||||
self.assertAlmostEqual(self._eval(aep, "balp[700IN]"), -100 * 1.1)
|
||||
# let's query for december, two companies, currency = usd
|
||||
aep = self._do_queries(
|
||||
self.company_eur | self.company_usd, self.usd, date_from, date_to
|
||||
)
|
||||
self.assertAlmostEqual(self._eval(aep, "balp[700IN]"), -100 * 1.1 - 50)
|
159
mis_builder/tests/test_period_dates.py
Normal file
159
mis_builder/tests/test_period_dates.py
Normal file
@ -0,0 +1,159 @@
|
||||
# Copyright 2017 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import flectra.tests.common as common
|
||||
from flectra import fields
|
||||
|
||||
from ..models.mis_report_instance import (
|
||||
MODE_FIX,
|
||||
MODE_NONE,
|
||||
MODE_REL,
|
||||
SRC_SUMCOL,
|
||||
DateFilterForbidden,
|
||||
DateFilterRequired,
|
||||
)
|
||||
from .common import assert_matrix
|
||||
|
||||
|
||||
class TestPeriodDates(common.TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.report_obj = self.env["mis.report"]
|
||||
self.instance_obj = self.env["mis.report.instance"]
|
||||
self.period_obj = self.env["mis.report.instance.period"]
|
||||
self.report = self.report_obj.create(dict(name="test-report"))
|
||||
self.instance = self.instance_obj.create(
|
||||
dict(name="test-instance", report_id=self.report.id, comparison_mode=False)
|
||||
)
|
||||
self.assertEqual(len(self.instance.period_ids), 1)
|
||||
self.period = self.instance.period_ids[0]
|
||||
|
||||
def assertDateEqual(self, first, second, msg=None):
|
||||
self.assertEqual(first, fields.Date.from_string(second), msg)
|
||||
|
||||
def test_date_filter_constraints(self):
|
||||
self.instance.comparison_mode = True
|
||||
with self.assertRaises(DateFilterRequired):
|
||||
self.period.write(dict(mode=MODE_NONE))
|
||||
with self.assertRaises(DateFilterForbidden):
|
||||
self.period.write(dict(mode=MODE_FIX, source=SRC_SUMCOL))
|
||||
|
||||
def test_simple_mode(self):
|
||||
# not comparison_mode
|
||||
self.assertFalse(self.instance.comparison_mode)
|
||||
period = self.instance.period_ids[0]
|
||||
self.assertEqual(period.date_from, self.instance.date_from)
|
||||
self.assertEqual(period.date_to, self.instance.date_to)
|
||||
|
||||
def tests_mode_none(self):
|
||||
self.instance.comparison_mode = True
|
||||
self.period.write(dict(mode=MODE_NONE, source=SRC_SUMCOL))
|
||||
self.assertFalse(self.period.date_from)
|
||||
self.assertFalse(self.period.date_to)
|
||||
self.assertTrue(self.period.valid)
|
||||
|
||||
def tests_mode_fix(self):
|
||||
self.instance.comparison_mode = True
|
||||
self.period.write(
|
||||
dict(
|
||||
mode=MODE_FIX,
|
||||
manual_date_from="2017-01-01",
|
||||
manual_date_to="2017-12-31",
|
||||
)
|
||||
)
|
||||
self.assertDateEqual(self.period.date_from, "2017-01-01")
|
||||
self.assertDateEqual(self.period.date_to, "2017-12-31")
|
||||
self.assertTrue(self.period.valid)
|
||||
|
||||
def test_rel_day(self):
|
||||
self.instance.write(dict(comparison_mode=True, date="2017-01-01"))
|
||||
self.period.write(dict(mode=MODE_REL, type="d", offset="-2"))
|
||||
self.assertDateEqual(self.period.date_from, "2016-12-30")
|
||||
self.assertDateEqual(self.period.date_to, "2016-12-30")
|
||||
self.assertTrue(self.period.valid)
|
||||
|
||||
def test_rel_day_ytd(self):
|
||||
self.instance.write(dict(comparison_mode=True, date="2019-05-03"))
|
||||
self.period.write(dict(mode=MODE_REL, type="d", offset="-2", is_ytd=True))
|
||||
self.assertDateEqual(self.period.date_from, "2019-01-01")
|
||||
self.assertDateEqual(self.period.date_to, "2019-05-01")
|
||||
self.assertTrue(self.period.valid)
|
||||
|
||||
def test_rel_week(self):
|
||||
self.instance.write(dict(comparison_mode=True, date="2016-12-30"))
|
||||
self.period.write(dict(mode=MODE_REL, type="w", offset="1", duration=2))
|
||||
# from Monday to Sunday, the week after 2016-12-30
|
||||
self.assertDateEqual(self.period.date_from, "2017-01-02")
|
||||
self.assertDateEqual(self.period.date_to, "2017-01-15")
|
||||
self.assertTrue(self.period.valid)
|
||||
|
||||
def test_rel_week_ytd(self):
|
||||
self.instance.write(dict(comparison_mode=True, date="2019-05-27"))
|
||||
self.period.write(
|
||||
dict(mode=MODE_REL, type="w", offset="1", duration=2, is_ytd=True)
|
||||
)
|
||||
self.assertDateEqual(self.period.date_from, "2019-01-01")
|
||||
self.assertDateEqual(self.period.date_to, "2019-06-16")
|
||||
self.assertTrue(self.period.valid)
|
||||
|
||||
def test_rel_month(self):
|
||||
self.instance.write(dict(comparison_mode=True, date="2017-01-05"))
|
||||
self.period.write(dict(mode=MODE_REL, type="m", offset="1"))
|
||||
self.assertDateEqual(self.period.date_from, "2017-02-01")
|
||||
self.assertDateEqual(self.period.date_to, "2017-02-28")
|
||||
self.assertTrue(self.period.valid)
|
||||
|
||||
def test_rel_month_ytd(self):
|
||||
self.instance.write(dict(comparison_mode=True, date="2019-05-15"))
|
||||
self.period.write(dict(mode=MODE_REL, type="m", offset="-1", is_ytd=True))
|
||||
self.assertDateEqual(self.period.date_from, "2019-01-01")
|
||||
self.assertDateEqual(self.period.date_to, "2019-04-30")
|
||||
self.assertTrue(self.period.valid)
|
||||
|
||||
def test_rel_year(self):
|
||||
self.instance.write(dict(comparison_mode=True, date="2017-05-06"))
|
||||
self.period.write(dict(mode=MODE_REL, type="y", offset="1"))
|
||||
self.assertDateEqual(self.period.date_from, "2018-01-01")
|
||||
self.assertDateEqual(self.period.date_to, "2018-12-31")
|
||||
self.assertTrue(self.period.valid)
|
||||
|
||||
def test_rel_date_range(self):
|
||||
# create a few date ranges
|
||||
date_range_type = self.env["date.range.type"].create(dict(name="Year"))
|
||||
for year in (2016, 2017, 2018):
|
||||
self.env["date.range"].create(
|
||||
dict(
|
||||
type_id=date_range_type.id,
|
||||
name="%d" % year,
|
||||
date_start="%d-01-01" % year,
|
||||
date_end="%d-12-31" % year,
|
||||
company_id=date_range_type.company_id.id,
|
||||
)
|
||||
)
|
||||
self.instance.write(dict(comparison_mode=True, date="2017-06-15"))
|
||||
self.period.write(
|
||||
dict(
|
||||
mode=MODE_REL,
|
||||
type="date_range",
|
||||
date_range_type_id=date_range_type.id,
|
||||
offset="-1",
|
||||
duration=3,
|
||||
)
|
||||
)
|
||||
self.assertDateEqual(self.period.date_from, "2016-01-01")
|
||||
self.assertDateEqual(self.period.date_to, "2018-12-31")
|
||||
self.assertTrue(self.period.valid)
|
||||
|
||||
def test_dates_in_expr(self):
|
||||
self.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=self.report.id,
|
||||
name="k1",
|
||||
description="kpi 1",
|
||||
expression="(date_to - date_from).days + 1",
|
||||
)
|
||||
)
|
||||
self.instance.date_from = "2017-01-01"
|
||||
self.instance.date_to = "2017-01-31"
|
||||
matrix = self.instance._compute_matrix()
|
||||
assert_matrix(matrix, [[31]])
|
315
mis_builder/tests/test_render.py
Normal file
315
mis_builder/tests/test_render.py
Normal file
@ -0,0 +1,315 @@
|
||||
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import flectra.tests.common as common
|
||||
|
||||
from ..models.accounting_none import AccountingNone
|
||||
from ..models.data_error import DataError
|
||||
from ..models.mis_report_style import CMP_DIFF, CMP_PCT, TYPE_NUM, TYPE_PCT, TYPE_STR
|
||||
|
||||
|
||||
class TestRendering(common.TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.style_obj = self.env["mis.report.style"]
|
||||
self.kpi_obj = self.env["mis.report.kpi"]
|
||||
self.style = self.style_obj.create(dict(name="teststyle"))
|
||||
self.lang = (
|
||||
self.env["res.lang"]
|
||||
.with_context(active_test=False)
|
||||
.search([("code", "=", "en_US")])[0]
|
||||
)
|
||||
|
||||
def _render(self, value, var_type=TYPE_NUM):
|
||||
style_props = self.style_obj.merge([self.style])
|
||||
return self.style_obj.render(self.lang, style_props, var_type, value)
|
||||
|
||||
def _compare_and_render(
|
||||
self, value, base_value, var_type=TYPE_NUM, compare_method=CMP_PCT
|
||||
):
|
||||
style_props = self.style_obj.merge([self.style])
|
||||
r = self.style_obj.compare_and_render(
|
||||
self.lang, style_props, var_type, compare_method, value, base_value
|
||||
)[:2]
|
||||
if r[0]:
|
||||
return (round(r[0], 8), r[1])
|
||||
else:
|
||||
return r
|
||||
|
||||
def test_render(self):
|
||||
self.assertEqual("1", self._render(1))
|
||||
self.assertEqual("1", self._render(1.1))
|
||||
self.assertEqual("2", self._render(1.6))
|
||||
self.style.dp_inherit = False
|
||||
self.style.dp = 2
|
||||
self.assertEqual("1.00", self._render(1))
|
||||
self.assertEqual("1.10", self._render(1.1))
|
||||
self.assertEqual("1.60", self._render(1.6))
|
||||
self.assertEqual("1.61", self._render(1.606))
|
||||
self.assertEqual("12,345.67", self._render(12345.67))
|
||||
|
||||
def test_render_negative(self):
|
||||
# non breaking hyphen
|
||||
self.assertEqual("\u20111", self._render(-1))
|
||||
|
||||
def test_render_zero(self):
|
||||
self.assertEqual("0", self._render(0))
|
||||
self.assertEqual("", self._render(None))
|
||||
self.assertEqual("", self._render(AccountingNone))
|
||||
|
||||
def test_render_suffix(self):
|
||||
self.style.suffix_inherit = False
|
||||
self.style.suffix = "€"
|
||||
self.assertEqual("1\xa0€", self._render(1))
|
||||
self.style.suffix = "k€"
|
||||
self.style.divider_inherit = False
|
||||
self.style.divider = "1e3"
|
||||
self.assertEqual("1\xa0k€", self._render(1000))
|
||||
|
||||
def test_render_prefix(self):
|
||||
self.style.prefix_inherit = False
|
||||
self.style.prefix = "$"
|
||||
self.assertEqual("$\xa01", self._render(1))
|
||||
self.style.prefix = "k$"
|
||||
self.style.divider_inherit = False
|
||||
self.style.divider = "1e3"
|
||||
self.assertEqual("k$\xa01", self._render(1000))
|
||||
|
||||
def test_render_divider(self):
|
||||
self.style.divider_inherit = False
|
||||
self.style.divider = "1e3"
|
||||
self.style.dp_inherit = False
|
||||
self.style.dp = 0
|
||||
self.assertEqual("1", self._render(1000))
|
||||
self.style.divider = "1e6"
|
||||
self.style.dp = 3
|
||||
self.assertEqual("0.001", self._render(1000))
|
||||
self.style.divider = "1e-3"
|
||||
self.style.dp = 0
|
||||
self.assertEqual("1,000", self._render(1))
|
||||
self.style.divider = "1e-6"
|
||||
self.style.dp = 0
|
||||
self.assertEqual("1,000,000", self._render(1))
|
||||
|
||||
def test_render_pct(self):
|
||||
self.assertEqual("100\xa0%", self._render(1, TYPE_PCT))
|
||||
self.assertEqual("50\xa0%", self._render(0.5, TYPE_PCT))
|
||||
self.style.dp_inherit = False
|
||||
self.style.dp = 2
|
||||
self.assertEqual("51.23\xa0%", self._render(0.5123, TYPE_PCT))
|
||||
|
||||
def test_render_string(self):
|
||||
self.assertEqual("", self._render("", TYPE_STR))
|
||||
self.assertEqual("", self._render(None, TYPE_STR))
|
||||
self.assertEqual("abcdé", self._render("abcdé", TYPE_STR))
|
||||
|
||||
def test_compare_num_pct(self):
|
||||
self.assertEqual((1.0, "+100.0\xa0%"), self._compare_and_render(100, 50))
|
||||
self.assertEqual((0.5, "+50.0\xa0%"), self._compare_and_render(75, 50))
|
||||
self.assertEqual((0.5, "+50.0\xa0%"), self._compare_and_render(-25, -50))
|
||||
self.assertEqual((1.0, "+100.0\xa0%"), self._compare_and_render(0, -50))
|
||||
self.assertEqual((2.0, "+200.0\xa0%"), self._compare_and_render(50, -50))
|
||||
self.assertEqual((-0.5, "\u201150.0\xa0%"), self._compare_and_render(25, 50))
|
||||
self.assertEqual((-1.0, "\u2011100.0\xa0%"), self._compare_and_render(0, 50))
|
||||
self.assertEqual((-2.0, "\u2011200.0\xa0%"), self._compare_and_render(-50, 50))
|
||||
self.assertEqual((-0.5, "\u201150.0\xa0%"), self._compare_and_render(-75, -50))
|
||||
self.assertEqual(
|
||||
(AccountingNone, ""), self._compare_and_render(50, AccountingNone)
|
||||
)
|
||||
self.assertEqual((AccountingNone, ""), self._compare_and_render(50, None))
|
||||
self.assertEqual((AccountingNone, ""), self._compare_and_render(50, 50))
|
||||
self.assertEqual((0.002, "+0.2\xa0%"), self._compare_and_render(50.1, 50))
|
||||
self.assertEqual((AccountingNone, ""), self._compare_and_render(50.01, 50))
|
||||
self.assertEqual(
|
||||
(-1.0, "\u2011100.0\xa0%"), self._compare_and_render(AccountingNone, 50)
|
||||
)
|
||||
self.assertEqual((-1.0, "\u2011100.0\xa0%"), self._compare_and_render(None, 50))
|
||||
self.assertEqual(
|
||||
(AccountingNone, ""), self._compare_and_render(DataError("#ERR", "."), 1)
|
||||
)
|
||||
self.assertEqual(
|
||||
(AccountingNone, ""), self._compare_and_render(1, DataError("#ERR", "."))
|
||||
)
|
||||
|
||||
def test_compare_num_diff(self):
|
||||
self.assertEqual(
|
||||
(25, "+25"), self._compare_and_render(75, 50, TYPE_NUM, CMP_DIFF)
|
||||
)
|
||||
self.assertEqual(
|
||||
(-25, "\u201125"), self._compare_and_render(25, 50, TYPE_NUM, CMP_DIFF)
|
||||
)
|
||||
self.style.suffix_inherit = False
|
||||
self.style.suffix = "€"
|
||||
self.assertEqual(
|
||||
(-25, "\u201125\xa0€"),
|
||||
self._compare_and_render(25, 50, TYPE_NUM, CMP_DIFF),
|
||||
)
|
||||
self.style.suffix = ""
|
||||
self.assertEqual(
|
||||
(50.0, "+50"),
|
||||
self._compare_and_render(50, AccountingNone, TYPE_NUM, CMP_DIFF),
|
||||
)
|
||||
self.assertEqual(
|
||||
(50.0, "+50"), self._compare_and_render(50, None, TYPE_NUM, CMP_DIFF)
|
||||
)
|
||||
self.assertEqual(
|
||||
(-50.0, "\u201150"),
|
||||
self._compare_and_render(AccountingNone, 50, TYPE_NUM, CMP_DIFF),
|
||||
)
|
||||
self.assertEqual(
|
||||
(-50.0, "\u201150"), self._compare_and_render(None, 50, TYPE_NUM, CMP_DIFF)
|
||||
)
|
||||
self.style.dp_inherit = False
|
||||
self.style.dp = 2
|
||||
self.assertEqual(
|
||||
(0.1, "+0.10"), self._compare_and_render(1.1, 1.0, TYPE_NUM, CMP_DIFF)
|
||||
)
|
||||
self.assertEqual(
|
||||
(AccountingNone, ""),
|
||||
self._compare_and_render(1.001, 1.0, TYPE_NUM, CMP_DIFF),
|
||||
)
|
||||
|
||||
def test_compare_pct(self):
|
||||
self.assertEqual(
|
||||
(0.25, "+25\xa0pp"), self._compare_and_render(0.75, 0.50, TYPE_PCT)
|
||||
)
|
||||
self.assertEqual(
|
||||
(AccountingNone, ""), self._compare_and_render(0.751, 0.750, TYPE_PCT)
|
||||
)
|
||||
|
||||
def test_compare_pct_result_type(self):
|
||||
style_props = self.style_obj.merge([self.style])
|
||||
result = self.style_obj.compare_and_render(
|
||||
self.lang, style_props, TYPE_PCT, CMP_DIFF, 0.75, 0.50
|
||||
)
|
||||
self.assertEqual(result[3], TYPE_NUM)
|
||||
|
||||
def test_merge(self):
|
||||
self.style.color = "#FF0000"
|
||||
self.style.color_inherit = False
|
||||
style_props = self.style_obj.merge([self.style])
|
||||
self.assertEqual(style_props, {"color": "#FF0000"})
|
||||
style_dict = {"color": "#00FF00", "dp": 0}
|
||||
style_props = self.style_obj.merge([self.style, style_dict])
|
||||
self.assertEqual(style_props, {"color": "#00FF00", "dp": 0})
|
||||
style2 = self.style_obj.create(
|
||||
dict(
|
||||
name="teststyle2",
|
||||
dp_inherit=False,
|
||||
dp=1,
|
||||
# color_inherit=True: will not be applied
|
||||
color="#0000FF",
|
||||
)
|
||||
)
|
||||
style_props = self.style_obj.merge([self.style, style_dict, style2])
|
||||
self.assertEqual(style_props, {"color": "#00FF00", "dp": 1})
|
||||
|
||||
def test_css(self):
|
||||
self.style.color_inherit = False
|
||||
self.style.color = "#FF0000"
|
||||
self.style.background_color_inherit = False
|
||||
self.style.background_color = "#0000FF"
|
||||
self.style.suffix_inherit = False
|
||||
self.style.suffix = "s"
|
||||
self.style.prefix_inherit = False
|
||||
self.style.prefix = "p"
|
||||
self.style.font_style_inherit = False
|
||||
self.style.font_style = "italic"
|
||||
self.style.font_weight_inherit = False
|
||||
self.style.font_weight = "bold"
|
||||
self.style.font_size_inherit = False
|
||||
self.style.font_size = "small"
|
||||
self.style.indent_level_inherit = False
|
||||
self.style.indent_level = 2
|
||||
style_props = self.style_obj.merge([self.style])
|
||||
css = self.style_obj.to_css_style(style_props)
|
||||
self.assertEqual(
|
||||
css,
|
||||
"font-style: italic; "
|
||||
"font-weight: bold; "
|
||||
"font-size: small; "
|
||||
"color: #FF0000; "
|
||||
"background-color: #0000FF; "
|
||||
"text-indent: 2em",
|
||||
)
|
||||
css = self.style_obj.to_css_style(style_props, no_indent=True)
|
||||
self.assertEqual(
|
||||
css,
|
||||
"font-style: italic; "
|
||||
"font-weight: bold; "
|
||||
"font-size: small; "
|
||||
"color: #FF0000; "
|
||||
"background-color: #0000FF",
|
||||
)
|
||||
|
||||
def test_xslx(self):
|
||||
self.style.color_inherit = False
|
||||
self.style.color = "#FF0000"
|
||||
self.style.background_color_inherit = False
|
||||
self.style.background_color = "#0000FF"
|
||||
self.style.suffix_inherit = False
|
||||
self.style.suffix = "s"
|
||||
self.style.prefix_inherit = False
|
||||
self.style.prefix = "p"
|
||||
self.style.dp_inherit = False
|
||||
self.style.dp = 2
|
||||
self.style.font_style_inherit = False
|
||||
self.style.font_style = "italic"
|
||||
self.style.font_weight_inherit = False
|
||||
self.style.font_weight = "bold"
|
||||
self.style.font_size_inherit = False
|
||||
self.style.font_size = "small"
|
||||
self.style.indent_level_inherit = False
|
||||
self.style.indent_level = 2
|
||||
style_props = self.style_obj.merge([self.style])
|
||||
xlsx = self.style_obj.to_xlsx_style(TYPE_NUM, style_props)
|
||||
self.assertEqual(
|
||||
xlsx,
|
||||
{
|
||||
"italic": True,
|
||||
"bold": True,
|
||||
"size": 9,
|
||||
"font_color": "#FF0000",
|
||||
"bg_color": "#0000FF",
|
||||
"num_format": '"p "#,##0.00" s"',
|
||||
"indent": 2,
|
||||
},
|
||||
)
|
||||
xlsx = self.style_obj.to_xlsx_style(TYPE_NUM, style_props, no_indent=True)
|
||||
self.assertEqual(
|
||||
xlsx,
|
||||
{
|
||||
"italic": True,
|
||||
"bold": True,
|
||||
"size": 9,
|
||||
"font_color": "#FF0000",
|
||||
"bg_color": "#0000FF",
|
||||
"num_format": '"p "#,##0.00" s"',
|
||||
},
|
||||
)
|
||||
# percent type ignore prefix and suffix
|
||||
xlsx = self.style_obj.to_xlsx_style(TYPE_PCT, style_props, no_indent=True)
|
||||
self.assertEqual(
|
||||
xlsx,
|
||||
{
|
||||
"italic": True,
|
||||
"bold": True,
|
||||
"size": 9,
|
||||
"font_color": "#FF0000",
|
||||
"bg_color": "#0000FF",
|
||||
"num_format": "0.00%",
|
||||
},
|
||||
)
|
||||
|
||||
# str type have no num_format style
|
||||
xlsx = self.style_obj.to_xlsx_style(TYPE_STR, style_props, no_indent=True)
|
||||
self.assertEqual(
|
||||
xlsx,
|
||||
{
|
||||
"italic": True,
|
||||
"bold": True,
|
||||
"size": 9,
|
||||
"font_color": "#FF0000",
|
||||
"bg_color": "#0000FF",
|
||||
},
|
||||
)
|
7
mis_builder/tests/test_simple_array.py
Normal file
7
mis_builder/tests/test_simple_array.py
Normal file
@ -0,0 +1,7 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from ..models import simple_array
|
||||
from .common import load_doctests
|
||||
|
||||
load_tests = load_doctests(simple_array)
|
96
mis_builder/tests/test_subreport.py
Normal file
96
mis_builder/tests/test_subreport.py
Normal file
@ -0,0 +1,96 @@
|
||||
# Copyright 2020 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from flectra.tests.common import TransactionCase
|
||||
|
||||
from flectra.addons.mis_builder.models.expression_evaluator import ExpressionEvaluator
|
||||
from flectra.addons.mis_builder.models.mis_report_subreport import (
|
||||
InvalidNameError,
|
||||
ParentLoopError,
|
||||
)
|
||||
|
||||
|
||||
class TestMisSubreport(TransactionCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
# create report
|
||||
cls.subreport = cls.env["mis.report"].create(dict(name="test subreport"))
|
||||
cls.subreport_kpi1 = cls.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=cls.subreport.id,
|
||||
name="sk1",
|
||||
description="subreport kpi 1",
|
||||
expression="11",
|
||||
)
|
||||
)
|
||||
cls.report = cls.env["mis.report"].create(
|
||||
dict(
|
||||
name="test report",
|
||||
subreport_ids=[
|
||||
(0, 0, dict(name="subreport", subreport_id=cls.subreport.id))
|
||||
],
|
||||
)
|
||||
)
|
||||
cls.report_kpi1 = cls.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=cls.report.id,
|
||||
name="k1",
|
||||
description="report kpi 1",
|
||||
expression="subreport.sk1 + 1",
|
||||
)
|
||||
)
|
||||
cls.parent_report = cls.env["mis.report"].create(
|
||||
dict(
|
||||
name="parent report",
|
||||
subreport_ids=[(0, 0, dict(name="report", subreport_id=cls.report.id))],
|
||||
)
|
||||
)
|
||||
cls.parent_report_kpi1 = cls.env["mis.report.kpi"].create(
|
||||
dict(
|
||||
report_id=cls.parent_report.id,
|
||||
name="pk1",
|
||||
description="parent report kpi 1",
|
||||
expression="report.k1 + 1",
|
||||
)
|
||||
)
|
||||
|
||||
def test_basic(self):
|
||||
ee = ExpressionEvaluator(aep=None, date_from="2017-01-01", date_to="2017-01-16")
|
||||
d = self.report._evaluate(ee)
|
||||
assert d["k1"] == 12
|
||||
|
||||
def test_two_levels(self):
|
||||
ee = ExpressionEvaluator(aep=None, date_from="2017-01-01", date_to="2017-01-16")
|
||||
d = self.parent_report._evaluate(ee)
|
||||
assert d["pk1"] == 13
|
||||
|
||||
def test_detect_loop(self):
|
||||
with self.assertRaises(ParentLoopError):
|
||||
self.report.write(
|
||||
dict(
|
||||
subreport_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(name="preport1", subreport_id=self.parent_report.id),
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
with self.assertRaises(ParentLoopError):
|
||||
self.report.write(
|
||||
dict(
|
||||
subreport_ids=[
|
||||
(
|
||||
0,
|
||||
0,
|
||||
dict(name="preport2", subreport_id=self.report.id),
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
def test_invalid_name(self):
|
||||
with self.assertRaises(InvalidNameError):
|
||||
self.report.subreport_ids[0].name = "ab c"
|
36
mis_builder/tests/test_target_move.py
Normal file
36
mis_builder/tests/test_target_move.py
Normal file
@ -0,0 +1,36 @@
|
||||
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import flectra.tests.common as common
|
||||
|
||||
|
||||
class TestMisReportInstance(common.TransactionCase):
|
||||
def test_supports_target_move_filter(self):
|
||||
self.assertTrue(
|
||||
self.env["mis.report"]._supports_target_move_filter("account.move.line")
|
||||
)
|
||||
|
||||
def test_supports_target_move_filter_no_parent_state(self):
|
||||
self.assertFalse(
|
||||
self.env["mis.report"]._supports_target_move_filter("account.move")
|
||||
)
|
||||
|
||||
def test_target_move_domain_posted(self):
|
||||
self.assertEqual(
|
||||
self.env["mis.report"]._get_target_move_domain(
|
||||
"posted", "account.move.line"
|
||||
),
|
||||
[("parent_state", "=", "posted")],
|
||||
)
|
||||
|
||||
def test_target_move_domain_all(self):
|
||||
self.assertEqual(
|
||||
self.env["mis.report"]._get_target_move_domain("all", "account.move.line"),
|
||||
[("parent_state", "in", ("posted", "draft"))],
|
||||
)
|
||||
|
||||
def test_target_move_domain_no_parent_state(self):
|
||||
"""Test get_target_move_domain on a model that has no parent_state."""
|
||||
self.assertEqual(
|
||||
self.env["mis.report"]._get_target_move_domain("all", "account.move"), []
|
||||
)
|
19
mis_builder/tests/test_utc_midnight.py
Normal file
19
mis_builder/tests/test_utc_midnight.py
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import flectra.tests.common as common
|
||||
|
||||
from ..models.mis_report import _utc_midnight
|
||||
|
||||
|
||||
class TestUtcMidnight(common.TransactionCase):
|
||||
def test_utc_midnight(self):
|
||||
date_to_convert = "2014-07-05"
|
||||
date_time_convert = _utc_midnight(date_to_convert, "Europe/Brussels")
|
||||
self.assertEqual(date_time_convert, "2014-07-04 22:00:00")
|
||||
date_time_convert = _utc_midnight(date_to_convert, "Europe/Brussels", add_day=1)
|
||||
self.assertEqual(date_time_convert, "2014-07-05 22:00:00")
|
||||
date_time_convert = _utc_midnight(date_to_convert, "US/Pacific")
|
||||
self.assertEqual(date_time_convert, "2014-07-05 07:00:00")
|
||||
date_time_convert = _utc_midnight(date_to_convert, "US/Pacific", add_day=1)
|
||||
self.assertEqual(date_time_convert, "2014-07-06 07:00:00")
|
301
mis_builder/views/mis_report.xml
Normal file
301
mis_builder/views/mis_report.xml
Normal file
@ -0,0 +1,301 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<flectra>
|
||||
<record model="ir.ui.view" id="mis_report_view_tree">
|
||||
<field name="name">mis.report.view.tree</field>
|
||||
<field name="model">mis.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name" />
|
||||
<field name="description" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="mis_report_view_form">
|
||||
<field name="name">mis.report.view.form</field>
|
||||
<field name="model">mis.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="MIS Report">
|
||||
<sheet>
|
||||
<group col="2">
|
||||
<field name="name" />
|
||||
<field name="description" />
|
||||
<field name="style_id" />
|
||||
<field name="move_lines_source" options="{'no_open': true}" />
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="KPI's">
|
||||
<field
|
||||
name="kpi_ids"
|
||||
nolabel="1"
|
||||
colspan="2"
|
||||
context="{'default_report_id': id}"
|
||||
>
|
||||
<tree>
|
||||
<field name="sequence" widget="handle" />
|
||||
<field name="description" />
|
||||
<field name="name" />
|
||||
<field name="type" />
|
||||
<field
|
||||
name="compare_method"
|
||||
attrs="{'invisible': [('type', '=', 'str')]}"
|
||||
/>
|
||||
<field
|
||||
name="accumulation_method"
|
||||
attrs="{'invisible': [('type', '=', 'str')]}"
|
||||
/>
|
||||
<field name="expression" />
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Queries">
|
||||
<field
|
||||
name="query_ids"
|
||||
nolabel="1"
|
||||
colspan="2"
|
||||
context="{'default_report_id': id}"
|
||||
>
|
||||
<tree editable="bottom">
|
||||
<field name="name" />
|
||||
<field name="model_id" />
|
||||
<field
|
||||
name="field_ids"
|
||||
domain="[('model_id', '=', model_id)]"
|
||||
widget="many2many_tags"
|
||||
/>
|
||||
<field name="field_names" />
|
||||
<field name="aggregate" />
|
||||
<field
|
||||
name="date_field"
|
||||
domain="[('model_id', '=', model_id), ('ttype', 'in', ('date', 'datetime'))]"
|
||||
/>
|
||||
<field name="domain" />
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Sub KPI's">
|
||||
<field name="subkpi_ids" nolabel="1" colspan="2">
|
||||
<tree editable="bottom">
|
||||
<field name="sequence" widget="handle" />
|
||||
<field name="description" />
|
||||
<field name="name" />
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Sub Reports">
|
||||
<field
|
||||
name="subreport_ids"
|
||||
nolabel="1"
|
||||
colspan="2"
|
||||
context="{'default_report_id': id}"
|
||||
>
|
||||
<tree editable="bottom">
|
||||
<field name="name" />
|
||||
<field
|
||||
name="subreport_id"
|
||||
domain="[('id', '!=', parent.id)]"
|
||||
/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="mis_report_view_kpi_form" model="ir.ui.view">
|
||||
<field name="name">mis.report.view.kpi.form</field>
|
||||
<field name="model">mis.report.kpi</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="MIS Report KPI">
|
||||
<group col="4">
|
||||
<field name="description" />
|
||||
<field name="name" />
|
||||
<field name="type" />
|
||||
<newline />
|
||||
<field name="compare_method" />
|
||||
<field name="accumulation_method" />
|
||||
<field name="style_id" />
|
||||
<field name="style_expression" />
|
||||
<field name='id' invisible='1' />
|
||||
<field
|
||||
name="report_id"
|
||||
invisible="1"
|
||||
attrs="{'required': [('id', '!=', False)]}"
|
||||
/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Expressions">
|
||||
<group col="2">
|
||||
<field name="multi" />
|
||||
<newline />
|
||||
<field
|
||||
name="expression_ids"
|
||||
colspan="2"
|
||||
nolabel="1"
|
||||
attrs="{'invisible': [('multi', '=', False)]}"
|
||||
>
|
||||
<tree editable="bottom">
|
||||
<field
|
||||
name="subkpi_id"
|
||||
domain="[('report_id', '=', parent.report_id)]"
|
||||
/>
|
||||
<field name="name" />
|
||||
</tree>
|
||||
</field>
|
||||
<field
|
||||
name="expression"
|
||||
colspan="2"
|
||||
nolabel="1"
|
||||
attrs="{'invisible': [('multi', '=', True)],
|
||||
'readonly': [('multi', '=', True)]}"
|
||||
placeholder="Enter expression here, for example balp[70%]. See also help tab."
|
||||
/>
|
||||
</group>
|
||||
<group col="4" string="Auto expand">
|
||||
<field name="auto_expand_accounts" />
|
||||
<field
|
||||
name="auto_expand_accounts_style_id"
|
||||
attrs="{'invisible': [('auto_expand_accounts', '!=', True)]}"
|
||||
/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Help (for KPI expressions)">
|
||||
<div style="display: flex; width: 100;">
|
||||
<div>
|
||||
<p>
|
||||
Expressions can be any valid python expressions.
|
||||
</p>
|
||||
<p
|
||||
> The following special elements are recognized in the expressions
|
||||
to compute accounting data: <code
|
||||
>{bal|crd|deb|pbal|nbal}{pieu}[account
|
||||
selector][journal items domain]</code>. </p>
|
||||
<ul>
|
||||
<li>
|
||||
<code>bal</code>, <code>crd</code>, <code
|
||||
>deb</code>, <code>
|
||||
pbal</code>, <code
|
||||
>nbal</code> : balance, debit, credit,
|
||||
positive balance, negative balance. </li>
|
||||
<li>
|
||||
<code>p</code>, <code>i</code>, <code
|
||||
>e</code> : respectively variation over the period,
|
||||
initial balance, ending balance </li>
|
||||
<li> The <b
|
||||
>account selector</b> is a like expression on the
|
||||
account code (eg <code
|
||||
>70%</code>, etc), or a domain over accounts
|
||||
(eg <code
|
||||
>[('code', 'like', '60%')]</code>). </li>
|
||||
<li> The <b
|
||||
>journal items domain</b> is an Flectra domain filter on
|
||||
journal items. </li>
|
||||
<li>
|
||||
<code>balu[]</code> : (<code
|
||||
>u</code> for unallocated) is a special expression
|
||||
that shows the unallocated profit/loss of previous fiscal
|
||||
years. </li>
|
||||
</ul>
|
||||
<p>
|
||||
Expressions can involve other KPI, sub KPI and
|
||||
query results by name (eg <code>kpi1 + kpi2</code>,
|
||||
<code>kpi2.subkpi1</code>, <code
|
||||
>query1.field1</code>).
|
||||
</p>
|
||||
<p>
|
||||
Additionally following variables are available
|
||||
in the evaluation context:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<code>sum</code>, <code>min</code>,
|
||||
<code>max</code>, <code>len</code>,
|
||||
<code>avg</code> : behave as expected, very
|
||||
similar to the python builtins. </li>
|
||||
<li>
|
||||
<code>datetime</code>, <code
|
||||
>datetime</code>, <code
|
||||
>dateutil</code> : the python modules. </li>
|
||||
<li>
|
||||
<code>date_from</code>, <code
|
||||
>date_to</code> : beginning and end date of the
|
||||
period. </li>
|
||||
<li>
|
||||
<code
|
||||
>AccountingNone</code> : a null value that behaves as 0 in
|
||||
arithmetic operations. </li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p>Examples:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<code
|
||||
>bal[70]</code> : variation of the balance of account 70 over
|
||||
the period (it is the same as <code
|
||||
>balp[70]</code>. </li>
|
||||
<li>
|
||||
<code
|
||||
>bali[70,60]</code> : initial balance of accounts 70 and 60. </li>
|
||||
<li>
|
||||
<code
|
||||
>bale[1%%]</code> : balance of accounts starting with 1 at
|
||||
end of period. </li>
|
||||
<li>
|
||||
<code
|
||||
>crdp[40%]</code> : sum of all credits on accounts starting
|
||||
with 40 during the period. </li>
|
||||
<li>
|
||||
<code>
|
||||
debp[55%][('journal_id.code', '=',
|
||||
'BNK1')]
|
||||
</code>
|
||||
: sum of all debits on accounts 55 and journal BNK1 during
|
||||
the period. </li>
|
||||
<li>
|
||||
<code>
|
||||
balp[('user_type_id', '=',
|
||||
ref('account.
|
||||
data_account_type_receivable').id)][]
|
||||
</code>
|
||||
: variation of the balance of all receivable accounts over
|
||||
the period. </li>
|
||||
<li>
|
||||
<code>
|
||||
balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]
|
||||
</code>
|
||||
: balance of move lines related to tax grid 56. </li>
|
||||
<li>
|
||||
<code
|
||||
>pbale[55%]</code> : sum of all ending balances of accounts
|
||||
starting with 55 whose ending balance is positive. </li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="mis_report_view_action">
|
||||
<field name="name">MIS Report Templates</field>
|
||||
<field name="view_id" ref="mis_report_view_tree" />
|
||||
<field name="res_model">mis.report</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem
|
||||
id="mis_report_conf_menu"
|
||||
parent="account.menu_finance_configuration"
|
||||
name="MIS Reporting"
|
||||
sequence="90"
|
||||
/>
|
||||
<menuitem
|
||||
id="mis_report_view_menu"
|
||||
parent="mis_report_conf_menu"
|
||||
name="MIS Report Templates"
|
||||
action="mis_report_view_action"
|
||||
sequence="21"
|
||||
/>
|
||||
</flectra>
|
421
mis_builder/views/mis_report_instance.xml
Normal file
421
mis_builder/views/mis_report_instance.xml
Normal file
@ -0,0 +1,421 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<flectra>
|
||||
<record model="ir.ui.view" id="mis_report_instance_result_view_form">
|
||||
<field name="name">mis.report.instance.result.view.form</field>
|
||||
<field name="model">mis.report.instance</field>
|
||||
<field name="priority" eval="20 " />
|
||||
<field name="arch" type="xml">
|
||||
<form
|
||||
string="MIS Report Preview"
|
||||
edit="false"
|
||||
create="false"
|
||||
delete="false"
|
||||
>
|
||||
<sheet>
|
||||
<field
|
||||
name="id"
|
||||
widget="mis_report_widget"
|
||||
nolabel="1"
|
||||
style="width:100%"
|
||||
/>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="mis_report_instance_view_tree">
|
||||
<field name="name">mis.report.instance.view.tree</field>
|
||||
<field name="model">mis.report.instance</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<button
|
||||
type="object"
|
||||
name="preview"
|
||||
string="Preview"
|
||||
icon="fa-search"
|
||||
/>
|
||||
<button type="object" name="print_pdf" string="Print" icon="fa-print" />
|
||||
<button
|
||||
type="object"
|
||||
name="export_xls"
|
||||
string="Export"
|
||||
icon="fa-download"
|
||||
/>
|
||||
<field name="name" />
|
||||
<field name="report_id" string="Template" />
|
||||
<field name="company_id" groups="base.group_multi_company" />
|
||||
<field name="multi_company" groups="base.group_multi_company" />
|
||||
<field name="currency_id" groups="base.group_multi_currency" />
|
||||
<field name="target_move" />
|
||||
<field name="pivot_date" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="mis_report_instance_view_form">
|
||||
<field name="name">mis.report.instance.view.form</field>
|
||||
<field name="model">mis.report.instance</field>
|
||||
<field name="priority" eval="15" />
|
||||
<field name="arch" type="xml">
|
||||
<form string="MIS Report Instance">
|
||||
<sheet>
|
||||
<field name="temporary" invisible="1" />
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<button
|
||||
type="object"
|
||||
name="preview"
|
||||
string="Preview"
|
||||
icon="fa-search"
|
||||
/>
|
||||
<button
|
||||
type="object"
|
||||
name="print_pdf"
|
||||
string="Print"
|
||||
icon="fa-print"
|
||||
/>
|
||||
<button
|
||||
type="object"
|
||||
name="export_xls"
|
||||
string="Export"
|
||||
icon="fa-download"
|
||||
/>
|
||||
<button
|
||||
type="action"
|
||||
name="%(mis_report_instance_add_to_dashboard_action)d"
|
||||
string="Add to dashboard"
|
||||
icon="fa-plus"
|
||||
attrs="{'invisible': [('temporary', '=', True)]}"
|
||||
/>
|
||||
<button
|
||||
type="object"
|
||||
name="save_report"
|
||||
string="Save"
|
||||
icon="fa-save"
|
||||
attrs="{'invisible': [('temporary', '=', False)]}"
|
||||
/>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<div class="oe_edit_only">
|
||||
<label for="name" />
|
||||
</div>
|
||||
<h1>
|
||||
<field name="name" placeholder="Name" />
|
||||
</h1>
|
||||
<field name="description" />
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="report_id" string="Template" />
|
||||
<field
|
||||
name="currency_id"
|
||||
groups="base.group_multi_currency"
|
||||
/>
|
||||
<field name="comparison_mode" />
|
||||
</group>
|
||||
<group>
|
||||
<group
|
||||
name="simple_mode"
|
||||
attrs="{'invisible': [('comparison_mode', '=', True)]}"
|
||||
colspan="4"
|
||||
>
|
||||
<field name="date_range_id" />
|
||||
<field
|
||||
name="date_from"
|
||||
attrs="{'required': [('comparison_mode', '=', False)]}"
|
||||
/>
|
||||
<field
|
||||
name="date_to"
|
||||
attrs="{'required': [('comparison_mode', '=', False)]}"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page
|
||||
string="Columns"
|
||||
attrs="{'invisible': [('comparison_mode', '=', False)]}"
|
||||
>
|
||||
<group>
|
||||
<group>
|
||||
<field name="date" />
|
||||
</group>
|
||||
<group>
|
||||
|
||||
</group>
|
||||
<field
|
||||
name="period_ids"
|
||||
nolabel="1"
|
||||
colspan="4"
|
||||
attrs="{'required': [('comparison_mode', '=', True)]}"
|
||||
context="{'default_report_instance_id': id}"
|
||||
>
|
||||
<tree decoration-danger="not valid">
|
||||
<field name="sequence" widget="handle" />
|
||||
<field name="name" />
|
||||
<field name="source" />
|
||||
<field name="source_aml_model_id" />
|
||||
<field name="date_from" />
|
||||
<field name="date_to" />
|
||||
<field name="valid" invisible="1" />
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Filters">
|
||||
<group name="filters">
|
||||
<field name="target_move" widget="radio" />
|
||||
<field
|
||||
name="multi_company"
|
||||
groups="base.group_multi_company"
|
||||
/>
|
||||
<field
|
||||
name="company_id"
|
||||
groups="base.group_multi_company"
|
||||
attrs="{'required': [('multi_company', '=', False)], 'invisible': [('multi_company', '=', True)]}"
|
||||
/>
|
||||
<field
|
||||
name="company_ids"
|
||||
groups="base.group_multi_company"
|
||||
widget="many2many_tags"
|
||||
attrs="{'invisible': [('multi_company', '=', False)]}"
|
||||
/>
|
||||
<field
|
||||
name="query_company_ids"
|
||||
groups="base.group_multi_company"
|
||||
widget="many2many_tags"
|
||||
/>
|
||||
<field name="source_aml_model_name" invisible="1" />
|
||||
<field
|
||||
name="analytic_domain"
|
||||
widget="domain"
|
||||
options="{'model': 'source_aml_model_name'}"
|
||||
/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Layout">
|
||||
<group name="layout">
|
||||
<field name="landscape_pdf" />
|
||||
<field name="no_auto_expand_accounts" />
|
||||
<field name="display_columns_description" />
|
||||
</group>
|
||||
</page>
|
||||
<page string="Widget">
|
||||
<group name="widget">
|
||||
<field name="widget_show_filters" />
|
||||
<field
|
||||
name="widget_search_view_id"
|
||||
attrs="{'invisible': [('widget_show_filters', '=', False)]}"
|
||||
/>
|
||||
<field name="widget_show_settings_button" />
|
||||
<field name="widget_show_pivot_date" />
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="mis_report_instance_view_action">
|
||||
<field name="name">MIS Reports</field>
|
||||
<field name="view_id" ref="mis_report_instance_view_tree" />
|
||||
<field name="res_model">mis.report.instance</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('temporary', '=', False)]</field>
|
||||
</record>
|
||||
<menuitem
|
||||
id="mis_report_finance_menu"
|
||||
parent="account.menu_finance_reports"
|
||||
name="MIS Reporting"
|
||||
sequence="101"
|
||||
groups="account.group_account_manager"
|
||||
/>
|
||||
<menuitem
|
||||
id="mis_report_instance_view_menu"
|
||||
parent="mis_report_finance_menu"
|
||||
name="MIS Reports"
|
||||
action="mis_report_instance_view_action"
|
||||
sequence="10"
|
||||
/>
|
||||
<record id="wizard_mis_report_instance_view_form" model="ir.ui.view">
|
||||
<field name="model">mis.report.instance</field>
|
||||
<field name="priority">99</field>
|
||||
<field name="inherit_id" ref="mis_builder.mis_report_instance_view_form" />
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<field name="name" position="attributes">
|
||||
<attribute name="readonly">1</attribute>
|
||||
</field>
|
||||
<label for="name" position="replace" />
|
||||
<field name="report_id" position="attributes">
|
||||
<attribute name="invisible">1</attribute>
|
||||
</field>
|
||||
<div name="buttons" position="attributes">
|
||||
<attribute name="invisible">1</attribute>
|
||||
</div>
|
||||
<sheet position="after">
|
||||
<footer>
|
||||
<button
|
||||
type="object"
|
||||
name="save_report"
|
||||
string="Save"
|
||||
icon="fa-save"
|
||||
/>
|
||||
<button
|
||||
type="object"
|
||||
name="preview"
|
||||
string="Preview"
|
||||
icon="fa-search"
|
||||
/>
|
||||
<button
|
||||
type="object"
|
||||
name="print_pdf"
|
||||
string="Print"
|
||||
icon="fa-print"
|
||||
/>
|
||||
<button
|
||||
type="object"
|
||||
name="export_xls"
|
||||
string="Export"
|
||||
icon="fa-download"
|
||||
/> or <button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</sheet>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="last_mis_report_instance_view_action">
|
||||
<field name="name">Last Reports Generated</field>
|
||||
<field name="view_id" ref="mis_report_instance_view_tree" />
|
||||
<field name="res_model">mis.report.instance</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('temporary', '=', True)]</field>
|
||||
</record>
|
||||
<menuitem
|
||||
id="last_wizard_mis_report_instance_view_menu"
|
||||
parent="mis_report_finance_menu"
|
||||
name="Last Reports Generated"
|
||||
action="last_mis_report_instance_view_action"
|
||||
sequence="20"
|
||||
/>
|
||||
<record model="ir.ui.view" id="mis_report_instance_period_view_form">
|
||||
<field name="model">mis.report.instance.period</field>
|
||||
<field name="priority" eval="16" />
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group col="4">
|
||||
<field name="name" placeholder="Name" />
|
||||
<field
|
||||
name="subkpi_ids"
|
||||
domain="[('report_id', '=', parent.report_id)]"
|
||||
widget="many2many_tags"
|
||||
options="{'no_create': True}"
|
||||
/>
|
||||
<field name="valid" invisible="1" />
|
||||
<field
|
||||
name="report_instance_id"
|
||||
invisible="1"
|
||||
attrs="{'required': [('id', '!=', False)]}"
|
||||
/>
|
||||
<field name="report_id" invisible="1" />
|
||||
<field name="id" invisible="1" />
|
||||
</group>
|
||||
<group string="Source" col="4">
|
||||
<group colspan="2" name="source">
|
||||
<field name="source" />
|
||||
</group>
|
||||
<group col="2" colspan="2" name="source_data">
|
||||
<field
|
||||
name="source_aml_model_id"
|
||||
attrs="{'invisible': [('source', '!=', 'actuals_alt')], 'required': [('source', '==', 'actuals_alt')]}"
|
||||
/>
|
||||
<field name="source_aml_model_name" invisible="1" />
|
||||
<field
|
||||
name="source_sumcol_ids"
|
||||
attrs="{'invisible': [('source', '!=', 'sumcol')]}"
|
||||
nolabel="1"
|
||||
colspan="2"
|
||||
>
|
||||
<tree editable="bottom">
|
||||
<field name="sign" />
|
||||
<field
|
||||
name="period_to_sum_id"
|
||||
domain="[('report_instance_id', '=', parent.report_instance_id), ('id', '!=', parent.id)]"
|
||||
options="{'no_create': True, 'no_open': True}"
|
||||
/>
|
||||
</tree>
|
||||
</field>
|
||||
<field
|
||||
name="source_sumcol_accdet"
|
||||
attrs="{'invisible': [('source', '!=', 'sumcol')]}"
|
||||
/>
|
||||
<field name="allowed_cmpcol_ids" invisible="1" />
|
||||
<field
|
||||
name="source_cmpcol_to_id"
|
||||
attrs="{'invisible': [('source', '!=', 'cmpcol')], 'required': [('source', '=', 'cmpcol')]}"
|
||||
domain="[('id', 'in', allowed_cmpcol_ids)]"
|
||||
options="{'no_create': True, 'no_open': True}"
|
||||
/>
|
||||
<field
|
||||
name="source_cmpcol_from_id"
|
||||
attrs="{'invisible': [('source', '!=', 'cmpcol')], 'required': [('source', '=', 'cmpcol')]}"
|
||||
domain="[('id', 'in', allowed_cmpcol_ids)]"
|
||||
options="{'no_create': True, 'no_open': True}"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Dates">
|
||||
<group colspan="4">
|
||||
<field name="mode" widget="radio" />
|
||||
</group>
|
||||
<group
|
||||
name="relative"
|
||||
attrs="{'invisible': [('mode', '!=', 'relative')]}"
|
||||
colspan="4"
|
||||
>
|
||||
<group>
|
||||
<field
|
||||
name="type"
|
||||
attrs="{'required': [('mode', '=', 'relative')]}"
|
||||
/>
|
||||
<field name="is_ytd" />
|
||||
<field
|
||||
name="date_range_type_id"
|
||||
attrs="{'invisible': [('type', '!=', 'date_range')], 'required': [('type', '=', 'date_range'), ('mode', '=', 'relative')]}"
|
||||
/>
|
||||
<field name="offset" />
|
||||
<field name="duration" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="date_from" />
|
||||
<field name="date_to" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
name="fix"
|
||||
attrs="{'invisible': [('mode', '!=', 'fix')]}"
|
||||
colspan="4"
|
||||
>
|
||||
<group>
|
||||
<field name="date_range_id" />
|
||||
</group>
|
||||
<group>
|
||||
<field
|
||||
name="manual_date_from"
|
||||
attrs="{'required': [('mode', '=', 'fix')]}"
|
||||
/>
|
||||
<field
|
||||
name="manual_date_to"
|
||||
attrs="{'required': [('mode', '=', 'fix')]}"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Filters">
|
||||
<field
|
||||
name="analytic_domain"
|
||||
widget="domain"
|
||||
options="{'model': 'source_aml_model_name'}"
|
||||
attrs="{'invisible': [('source_aml_model_name', '=', False)]}"
|
||||
/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</flectra>
|
110
mis_builder/views/mis_report_style.xml
Normal file
110
mis_builder/views/mis_report_style.xml
Normal file
@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<flectra>
|
||||
<record model="ir.ui.view" id="mis_report_style_view_tree">
|
||||
<field name="name">mis.report.style.view.tree</field>
|
||||
<field name="model">mis.report.style</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="mis_report_style_view_form" model="ir.ui.view">
|
||||
<field name="name">mis.report.style.view.form</field>
|
||||
<field name="model">mis.report.style</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="MIS Report Style">
|
||||
<sheet>
|
||||
<group string="Style" col="2">
|
||||
<field name="name" />
|
||||
</group>
|
||||
<group string="Number" col="4">
|
||||
<field name="dp_inherit" string="Rounding inherit" />
|
||||
<field
|
||||
name="dp"
|
||||
attrs="{'invisible': [('dp_inherit', '=', True)]}"
|
||||
/>
|
||||
<field name="divider_inherit" string="Factor inherit" />
|
||||
<field
|
||||
name="divider"
|
||||
attrs="{'invisible': [('divider_inherit', '=', True)]}"
|
||||
/>
|
||||
<field name="prefix_inherit" />
|
||||
<field
|
||||
name="prefix"
|
||||
attrs="{'invisible': [('prefix_inherit', '=', True)]}"
|
||||
/>
|
||||
<field name="suffix_inherit" />
|
||||
<field
|
||||
name="suffix"
|
||||
attrs="{'invisible': [('suffix_inherit', '=', True)]}"
|
||||
/>
|
||||
</group>
|
||||
<group string="Color" col="4">
|
||||
<field name="color_inherit" />
|
||||
<field
|
||||
name="color"
|
||||
attrs="{'invisible': [('color_inherit', '=', True)]}"
|
||||
widget="color"
|
||||
/>
|
||||
<field name="background_color_inherit" />
|
||||
<field
|
||||
name="background_color"
|
||||
attrs="{'invisible': [('background_color_inherit', '=', True)]}"
|
||||
widget="color"
|
||||
/>
|
||||
</group>
|
||||
<group string="Font" col="4">
|
||||
<field name="font_style_inherit" />
|
||||
<field
|
||||
name="font_style"
|
||||
attrs="{'invisible': [('font_style_inherit', '=', True)]}"
|
||||
/>
|
||||
<field name="font_weight_inherit" />
|
||||
<field
|
||||
name="font_weight"
|
||||
attrs="{'invisible': [('font_weight_inherit', '=', True)]}"
|
||||
/>
|
||||
<field name="font_size_inherit" />
|
||||
<field
|
||||
name="font_size"
|
||||
attrs="{'invisible': [('font_size_inherit', '=', True)]}"
|
||||
/>
|
||||
</group>
|
||||
<group string="Indent" col="4">
|
||||
<field name="indent_level_inherit" />
|
||||
<field
|
||||
name="indent_level"
|
||||
attrs="{'invisible': [('indent_level_inherit', '=', True)]}"
|
||||
/>
|
||||
</group>
|
||||
<group string="Visibility" col="4">
|
||||
<field name="hide_empty_inherit" />
|
||||
<field
|
||||
name="hide_empty"
|
||||
attrs="{'invisible': [('hide_empty_inherit', '=', True)]}"
|
||||
/>
|
||||
<field name="hide_always_inherit" />
|
||||
<field
|
||||
name="hide_always"
|
||||
attrs="{'invisible': [('hide_always_inherit', '=', True)]}"
|
||||
/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="mis_report_style_view_action">
|
||||
<field name="name">MIS Report Styles</field>
|
||||
<field name="view_id" ref="mis_report_style_view_tree" />
|
||||
<field name="res_model">mis.report.style</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem
|
||||
id="mis_report_style_view_menu"
|
||||
parent="mis_report_conf_menu"
|
||||
name="MIS Report Styles"
|
||||
action="mis_report_style_view_action"
|
||||
sequence="22"
|
||||
/>
|
||||
</flectra>
|
4
mis_builder/wizard/__init__.py
Normal file
4
mis_builder/wizard/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import mis_builder_dashboard
|
95
mis_builder/wizard/mis_builder_dashboard.py
Normal file
95
mis_builder/wizard/mis_builder_dashboard.py
Normal file
@ -0,0 +1,95 @@
|
||||
# Copyright 2014 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# Copyright 2020 CorporateHub (https://corporatehub.eu)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from lxml import etree
|
||||
|
||||
from flectra import api, fields, models
|
||||
|
||||
|
||||
class AddMisReportInstanceDashboard(models.TransientModel):
|
||||
_name = "add.mis.report.instance.dashboard.wizard"
|
||||
_description = "MIS Report Add to Dashboard Wizard"
|
||||
|
||||
name = fields.Char(required=True)
|
||||
|
||||
dashboard_id = fields.Many2one(
|
||||
"ir.actions.act_window",
|
||||
string="Dashboard",
|
||||
required=True,
|
||||
domain="[('res_model', '=', " "'board.board')]",
|
||||
)
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields_list):
|
||||
res = {}
|
||||
if self.env.context.get("active_id", False):
|
||||
res = super().default_get(fields_list)
|
||||
# get report instance name
|
||||
res["name"] = (
|
||||
self.env["mis.report.instance"]
|
||||
.browse(self.env.context["active_id"])
|
||||
.name
|
||||
)
|
||||
return res
|
||||
|
||||
def action_add_to_dashboard(self):
|
||||
active_model = self.env.context.get("active_model")
|
||||
assert active_model == "mis.report.instance"
|
||||
active_id = self.env.context.get("active_id")
|
||||
assert active_id
|
||||
# create the act_window corresponding to this report
|
||||
self.env.ref("mis_builder.mis_report_instance_result_view_form")
|
||||
view = self.env.ref("mis_builder.mis_report_instance_result_view_form")
|
||||
report_result = (
|
||||
self.env["ir.actions.act_window"]
|
||||
.sudo()
|
||||
.create(
|
||||
{
|
||||
"name": "mis.report.instance.result.view.action.%d"
|
||||
% self.env.context["active_id"],
|
||||
"res_model": active_model,
|
||||
"res_id": active_id,
|
||||
"target": "current",
|
||||
"view_mode": "form",
|
||||
"view_id": view.id,
|
||||
"context": self.env.context,
|
||||
}
|
||||
)
|
||||
)
|
||||
# add this result in the selected dashboard
|
||||
last_customization = self.env["ir.ui.view.custom"].search(
|
||||
[
|
||||
("user_id", "=", self.env.uid),
|
||||
("ref_id", "=", self.dashboard_id.view_id.id),
|
||||
],
|
||||
limit=1,
|
||||
)
|
||||
arch = self.dashboard_id.view_id.arch
|
||||
if last_customization:
|
||||
arch = self.env["ir.ui.view.custom"].browse(last_customization[0].id).arch
|
||||
new_arch = etree.fromstring(arch)
|
||||
column = new_arch.xpath("//column")[0]
|
||||
# Due to native dashboard doesn't support form view
|
||||
# add "from_dashboard" to context to get correct views in "get_views"
|
||||
context = dict(self.env.context, from_dashboard=True)
|
||||
column.append(
|
||||
etree.Element(
|
||||
"action",
|
||||
{
|
||||
"context": str(context),
|
||||
"name": str(report_result.id),
|
||||
"string": self.name,
|
||||
"view_mode": "form",
|
||||
},
|
||||
)
|
||||
)
|
||||
self.env["ir.ui.view.custom"].create(
|
||||
{
|
||||
"user_id": self.env.uid,
|
||||
"ref_id": self.dashboard_id.view_id.id,
|
||||
"arch": etree.tostring(new_arch, pretty_print=True),
|
||||
}
|
||||
)
|
||||
|
||||
return {"type": "ir.actions.act_window_close"}
|
36
mis_builder/wizard/mis_builder_dashboard.xml
Normal file
36
mis_builder/wizard/mis_builder_dashboard.xml
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<flectra>
|
||||
<record model="ir.ui.view" id="mis_report_instance_add_to_dashboard_form_view">
|
||||
<field name="name">add.mis.report.instance.dashboard.wizard.view</field>
|
||||
<field name="model">add.mis.report.instance.dashboard.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Add to dashboard">
|
||||
<group>
|
||||
<field name="name" />
|
||||
<field name="dashboard_id" />
|
||||
</group>
|
||||
<footer>
|
||||
<button
|
||||
name="action_add_to_dashboard"
|
||||
string="Add to dashboard"
|
||||
type="object"
|
||||
default_focus="1"
|
||||
class="oe_highlight"
|
||||
/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record
|
||||
model="ir.actions.act_window"
|
||||
id="mis_report_instance_add_to_dashboard_action"
|
||||
>
|
||||
<field name="name">Add to dashboard</field>
|
||||
<field name="res_model">add.mis.report.instance.dashboard.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="mis_report_instance_add_to_dashboard_form_view" />
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
</flectra>
|
22
mis_builder_budget/COPYRIGHT
Normal file
22
mis_builder_budget/COPYRIGHT
Normal file
@ -0,0 +1,22 @@
|
||||
Most of the files are
|
||||
|
||||
:Copyright: This stylesheet has been placed in the public domain.
|
||||
<!-- Copyright 2017 ACSONE SA/NV
|
||||
<!-- Copyright 2017-2018 ACSONE SA/NV
|
||||
<!-- Copyright 2017-2020 ACSONE SA/NV
|
||||
Copyright 2017 ACSONE SA/NV
|
||||
Copyright 2017 ACSONE SA/NV (<http://acsone.eu>)
|
||||
Copyright 2017-2018 ACSONE SA/NV
|
||||
Copyright 2017-2020 ACSONE SA/NV
|
||||
Copyright 2023 ACSONE SA/NV (<http://acsone.eu>)
|
||||
Copyright 2018 Flectra Community
|
||||
|
||||
Many files also contain contributions from third
|
||||
parties. In this case the original copyright of
|
||||
the contributions can be traced through the
|
||||
history of the source version control system.
|
||||
|
||||
When that is not the case, the files contain a prominent
|
||||
notice stating the original copyright and applicable
|
||||
license, or come with their own dedicated COPYRIGHT
|
||||
and/or LICENSE file.
|
663
mis_builder_budget/LICENSE
Normal file
663
mis_builder_budget/LICENSE
Normal file
@ -0,0 +1,663 @@
|
||||
For copyright information, please see the COPYRIGHT file.
|
||||
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are 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.
|
||||
|
||||
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.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
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 Affero 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. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
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 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 work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero 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 Affero 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 Affero 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 Affero 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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
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 AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
246
mis_builder_budget/README.rst
Normal file
246
mis_builder_budget/README.rst
Normal file
@ -0,0 +1,246 @@
|
||||
==================
|
||||
MIS Builder Budget
|
||||
==================
|
||||
|
||||
..
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:ae54cfc3d390dd5240d9a2931e6e444756b9d061f64d9e4a9f4e7bc33dac6015
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
|
||||
:target: https://odoo-community.org/page/development-status
|
||||
:alt: Production/Stable
|
||||
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmis--builder-lightgray.png?logo=github
|
||||
:target: https://github.com/OCA/mis-builder/tree/16.0/mis_builder_budget
|
||||
:alt: OCA/mis-builder
|
||||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
||||
:target: https://translation.odoo-community.org/projects/mis-builder-16-0/mis-builder-16-0-mis_builder_budget
|
||||
: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/mis-builder&target_branch=16.0
|
||||
:alt: Try me on Runboat
|
||||
|
||||
|badge1| |badge2| |badge3| |badge4| |badge5|
|
||||
|
||||
Create budgets for MIS reports.
|
||||
|
||||
This module lets you create budgets for any MIS report. Several budgets can be
|
||||
created for a given report template (ie one budget per year). Budget figures
|
||||
are provided by KPI or by GL account, with different time periods. A budget can
|
||||
then be selected as a data source for a MIS report column, and the report will
|
||||
show the budgeted values for each KPI, adjusted for the period of the column.
|
||||
|
||||
**Table of contents**
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
There are two ways to use this module: create budgets by KPI or budgets by
|
||||
GL accounts. Currently, the two methods cannot be combined in the same budget.
|
||||
|
||||
**Budget by KPIs**
|
||||
|
||||
To use this this mode, you first need to flag at least some KPI in a MIS report
|
||||
to be budgetable. You also need to configure the accumulation method on the KPI
|
||||
according to their type.
|
||||
|
||||
The accumulation method determines how budgeted values spanning over a
|
||||
time period are transformed to match the reporting period.
|
||||
|
||||
* Sum: values of shorter period are added, values of longest or partially overlapping
|
||||
periods are adjusted pro-rata temporis (eg monetary amount such as revenue).
|
||||
* Average: values of included period are averaged with a pro-rata temporis weight.
|
||||
Typically used for values that do not accumulate over time (eg a number of employees).
|
||||
|
||||
When KPI are configured, you need to create a budget, using the MIS Budget (by
|
||||
KPIs) menu, then click on the budget items button to create or import the
|
||||
budgeted amounts for all your KPI and time periods.
|
||||
|
||||
**Budget by GL accounts**
|
||||
|
||||
You can also create budgets by GL accounts. In this case, the budget is
|
||||
populated with one line per GL account (and optionally analytic account and/or
|
||||
tags) and time period.
|
||||
|
||||
**Add budget columns to report instances**
|
||||
|
||||
Finally, a column (aka period) must be added to a MIS report instance,
|
||||
selecting your newly created budget as a data source. The data will be adjusted
|
||||
to the reporting period when displayed. Columns can be compared by adding a
|
||||
column of type "comparison" or "sum".
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
The mis_builder `roadmap <https://github.com/OCA/mis-builder/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement>`_
|
||||
and `known issues <https://github.com/OCA/mis-builder/issues?q=is%3Aopen+is%3Aissue+label%3Abug>`_ can
|
||||
be found on GitHub.
|
||||
|
||||
Changelog
|
||||
=========
|
||||
|
||||
16.0.5.0.0 (2023-04-01)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
- Migration to 16.0.
|
||||
|
||||
- removal of analytic fetures because the upstream ``analytic_distribution`` mechanism
|
||||
is not compatible; support may be introduced in separate module, depending on use
|
||||
cases (`#472 <https://github.com/OCA/mis-builder/issues/472>`_)
|
||||
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Fix display of budgets in presence of sub KPIs. (`#428 <https://github.com/OCA/mis-builder/issues/428>`_)
|
||||
|
||||
|
||||
14.0.4.0.0 (2022-01-08)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
- A label field has been added to MIS Budget by Account items. When overlap between budget
|
||||
items is allowed this allows creating a budget with several contributions for a given
|
||||
account. (`#382 <https://github.com/OCA/mis-builder/issues/382>`_)
|
||||
- The balance field on MIS Budget by Account items is now writeable. This allows for
|
||||
easier data entry and import. (`#383 <https://github.com/OCA/mis-builder/issues/383>`_)
|
||||
- MIS Budget by Account can now be configured to allow budget items with overlapping
|
||||
dates. Each overlapping item contributes to the budget of the corresponding period. (`#384 <https://github.com/OCA/mis-builder/issues/384>`_)
|
||||
|
||||
|
||||
14.0.3.5.1 (2021-04-06)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Fix incorrect budget by account multi company security rules. (`#347 <https://github.com/OCA/mis-builder/issues/347>`_)
|
||||
|
||||
|
||||
13.0.3.5.0 (2020-03-28)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
- Budget by GL account: allow budgeting by GL account in addition to the
|
||||
existing mechanism to budget by KPI. Budget items have a begin and end
|
||||
date, and when reporting a pro-rata temporis adjustment is made to match
|
||||
the reporting period. (`#259 <https://github.com/OCA/mis-builder/issues/259>`_)
|
||||
|
||||
|
||||
13.0.3.4.0 (2020-01-??)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Migration to odoo 13.0.
|
||||
|
||||
12.0.3.4.0 (2019-10-26)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Consider analytic tags too when detecting overlapping budget items.
|
||||
Previously only analytic account was considered, and this overlap detection
|
||||
mechanism was overlooked when analytic tags were added to budget items. (`#241 <https://github.com/oca/mis-builder/issues/241>`_)
|
||||
|
||||
|
||||
11.0.3.3.0 (2019-01-13)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Features**
|
||||
|
||||
- Support analytic filters. (`#15 <https://github.com/oca/mis-builder/issues/15>`_)
|
||||
|
||||
|
||||
11.0.3.2.1 (2018-06-30)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- [IMP] Support analytic tags in budget items
|
||||
(`#100 <https://github.com/OCA/mis-builder/pull/100>`_)
|
||||
|
||||
11.0.3.2.0 (2018-05-02)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- [FIX] #NAME error in out-of-order computation of non
|
||||
budgetable items in budget columns
|
||||
(`#68 <https://github.com/OCA/mis-builder/pull/69>`_)
|
||||
|
||||
11.0.3.1.1 (2018-02-04)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Migration to Odoo 11. No new feature.
|
||||
(`#67 <https://github.com/OCA/mis-builder/pull/67>`_)
|
||||
|
||||
10.0.3.1.0 (2017-11-14)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
New features:
|
||||
|
||||
- [ADD] multi-company record rule for MIS Budgets
|
||||
(`#27 <https://github.com/OCA/mis-builder/issues/27>`_)
|
||||
|
||||
10.0.1.1.1 (2017-10-01)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
First version.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/mis-builder/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/mis-builder/issues/new?body=module:%20mis_builder_budget%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
|
||||
~~~~~~~
|
||||
|
||||
* ACSONE SA/NV
|
||||
|
||||
Contributors
|
||||
~~~~~~~~~~~~
|
||||
|
||||
* Stéphane Bidoul <stephane.bidoul@acsone.eu>
|
||||
* Adrien Peiffer <adrien.peiffer@acsone.eu>
|
||||
* Benjamin Willig <benjamin.willig@acsone.eu>
|
||||
* Artem Kostyuk <a.kostyuk@mobilunity.com>
|
||||
* Dzung Tran <dungtd@trobz.com>
|
||||
|
||||
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-sbidoul| image:: https://github.com/sbidoul.png?size=40px
|
||||
:target: https://github.com/sbidoul
|
||||
:alt: sbidoul
|
||||
|
||||
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|
||||
|
||||
|maintainer-sbidoul|
|
||||
|
||||
This module is part of the `OCA/mis-builder <https://github.com/OCA/mis-builder/tree/16.0/mis_builder_budget>`_ project on GitHub.
|
||||
|
||||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
1
mis_builder_budget/__init__.py
Normal file
1
mis_builder_budget/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from . import models
|
28
mis_builder_budget/__manifest__.py
Normal file
28
mis_builder_budget/__manifest__.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright 2017-2018 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "MIS Builder Budget",
|
||||
"summary": """
|
||||
Create budgets for MIS reports""",
|
||||
"version": "3.0.5.0.2",
|
||||
"license": "AGPL-3",
|
||||
"author": "ACSONE SA/NV, " "Odoo Community Association (OCA)",
|
||||
"website": "https://gitlab.com/flectra-community/mis-builder",
|
||||
"depends": ["mis_builder", "account"],
|
||||
"data": [
|
||||
"views/mis_report_instance_period.xml",
|
||||
"views/mis_report.xml",
|
||||
"security/mis_budget_item.xml",
|
||||
"views/mis_budget_item.xml",
|
||||
"security/mis_budget.xml",
|
||||
"views/mis_budget.xml",
|
||||
"security/mis_budget_by_account_item.xml",
|
||||
"views/mis_budget_by_account_item.xml",
|
||||
"security/mis_budget_by_account.xml",
|
||||
"views/mis_budget_by_account.xml",
|
||||
],
|
||||
"installable": False,
|
||||
"development_status": "Production/Stable",
|
||||
"maintainers": ["sbidoul"],
|
||||
}
|
611
mis_builder_budget/i18n/ca.po
Normal file
611
mis_builder_budget/i18n/ca.po
Normal file
@ -0,0 +1,611 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 11.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2023-06-23 10:10+0000\n"
|
||||
"Last-Translator: eccit-quim <quim@eccit.com>\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: ca\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.17\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr "%s (còpia)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr "La data d'inici de %s no pot ser posterior a la data de finalització"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
msgid "Account"
|
||||
msgstr "Compte"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr "Acció necessària"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a "
|
||||
"database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
"Actualitat: dades actuals, de comptabilitat i altres consultes.\n"
|
||||
"Actualitat (alternativa): dades actuals d’una font alternativa (per exemple, "
|
||||
"una vista de base de dades que ofereix línies de desplaçament del compte "
|
||||
"semblants).\n"
|
||||
"Suma columnes: suma (+/-) d'altres columnes.\n"
|
||||
"Compara amb columna: compara amb una altra columna.\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr "Permet la superposició d'elements"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr "Import"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr "Nombre d’adjunts"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
msgid "Balance"
|
||||
msgstr "Equilibri"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr "Pressupost"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
msgid "Budget Date From"
|
||||
msgstr "Data pressupostària de"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
msgid "Budget Date To"
|
||||
msgstr "Data del pressupost a"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr "Pressupost per compte"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
msgid "Budget by KPI"
|
||||
msgstr "Pressupost per KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr "Elements de pressupost"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr "Pressupostable"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel·lar"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr "Cancel·lat"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr "Companyia"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Company Currency"
|
||||
msgstr "Moneda de l'empresa"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmar"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr "Confirmat"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Creat per"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Creat el"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr "Crèdit"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr "Data"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr "Rang de data"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr "Dèbit"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr "Descripció"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nom mostrat"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr "Esborrany"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
"Camp fictici que adapta les cerques de la data a les cerques de la data_des/"
|
||||
"data_fins."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr "Seguidors"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr "Seguidors (socis)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr "Des del"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr "Si es marca, els missatges nous requereixen la vostra atenció."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr ""
|
||||
"Si està marcat, es permet la superposició entre les partides del pressupost"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr "Si es marca, alguns missatges tenen un error de lliurament."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr "És seguidor"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr "Objecte"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr "KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr "Seqüència de KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr "Etiqueta"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Última modificació el"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Última actualització per"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Última actualització el"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr "Pressupost MIS (classe base abstracta)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr "Partida pressupostària MIS (classe base abstracta)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr "Element del pressupost de MIS (per compte)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr "Punt del pressupost de MIS (per KPI)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr "Partides del pressupost de MIS (per KPIs)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr "Partides pressupostàries MIS (per comptes)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr "Pressupost MIS per compte"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr "Pressupost de MIS per KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr "Pressupostos de MIS (per KPIs)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr "Pressupostos MIS (per comptes)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
msgid "MIS Report Instance"
|
||||
msgstr "Informe MIS Instància"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr "Informe MIS Període d’instància"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
msgid "MIS Report KPI"
|
||||
msgstr "Informe de MIS KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr "Expressió KPI Informe MIS"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr "Plantilla de pressupost MIS"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr "Adjunt principal"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr "Error de lliurament de missatges"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr "Missatges"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr "Nombre d’accions"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr "Nombre d’errors"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr "Nombre de missatges amb error de publicació"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr "Canviar a esborrany"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr "Font"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr "Estat"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr "Seqüència Sub-KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr "a"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr "Camp d’utilitat per expressar la quantitat de moneda"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr "Missatges del lloc web"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr "Historial de comunicacions de llocs web"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
"Valor de crèdit o dèbit incorrecte a la partida pressupostària. El crèdit i "
|
||||
"el dèbit han de ser positius."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
||||
"Valor de crèdit o de dèbit incorrecte a la partida pressupostària. El crèdit "
|
||||
"o el dèbit han de ser nuls."
|
||||
|
||||
#~ msgid "SMS Delivery error"
|
||||
#~ msgstr "Error de lliurament de SMS"
|
||||
|
||||
#~ msgid "Number of messages which requires an action"
|
||||
#~ msgstr "Nombre de missatges que requereixen una acció"
|
||||
|
||||
#, python-format
|
||||
#~ msgid "%s is not within budget %s date range."
|
||||
#~ msgstr "%s no és dins del rang de dates del pressupost %s."
|
||||
|
||||
#, python-format
|
||||
#~ msgid "%s overlaps %s in budget %s"
|
||||
#~ msgstr "%s superposa %s en el pressupost %s"
|
||||
|
||||
#~ msgid "Analytic Tags"
|
||||
#~ msgstr "Etiquetes analítiques"
|
||||
|
||||
#~ msgid "Analytic account"
|
||||
#~ msgstr "Compte analític"
|
||||
|
||||
#~ msgid "Followers (Channels)"
|
||||
#~ msgstr "Seguidors (canals)"
|
||||
|
||||
#~ msgid "Number of unread messages"
|
||||
#~ msgstr "Nombre de missatges sense llegir"
|
||||
|
||||
#~ msgid "Unread Messages"
|
||||
#~ msgstr "Missatges sense llegir"
|
||||
|
||||
#~ msgid "Unread Messages Counter"
|
||||
#~ msgstr "Contador de missatges sense llegir"
|
||||
|
||||
#~ msgid "MIS Budget"
|
||||
#~ msgstr "Pressupost MIS"
|
||||
|
||||
#~ msgid "MIS Budgets"
|
||||
#~ msgstr "Pressupostos MIS"
|
||||
|
||||
#~ msgid "mis.report.instance"
|
||||
#~ msgstr "mis.report.instance"
|
||||
|
||||
#~ msgid "mis.report.kpi"
|
||||
#~ msgstr "mis.report.kpi"
|
||||
|
||||
#~ msgid "mis.report.kpi.expression"
|
||||
#~ msgstr "mis.report.kpi.expression"
|
553
mis_builder_budget/i18n/de.po
Normal file
553
mis_builder_budget/i18n/de.po
Normal file
@ -0,0 +1,553 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
# Translators:
|
||||
# Rudolf Schnapka <rs@techno-flex.de>, 2018
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 11.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-02-05 01:43+0000\n"
|
||||
"PO-Revision-Date: 2018-02-05 01:43+0000\n"
|
||||
"Last-Translator: Rudolf Schnapka <rs@techno-flex.de>, 2018\n"
|
||||
"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr "%s (Kopie)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a "
|
||||
"database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
msgid "Balance"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
msgid "Budget Date From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
msgid "Budget Date To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
msgid "Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Company Currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
msgid "MIS Report Instance"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
msgid "MIS Report KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
618
mis_builder_budget/i18n/es.po
Normal file
618
mis_builder_budget/i18n/es.po
Normal file
@ -0,0 +1,618 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
# Translators:
|
||||
# OCA Transbot <transbot@odoo-community.org>, 2018
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 11.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-13 15:37+0000\n"
|
||||
"PO-Revision-Date: 2023-09-07 16:37+0000\n"
|
||||
"Last-Translator: Ivorra78 <informatica@totmaterial.es>\n"
|
||||
"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.17\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
"%(rec_name)s no se encuentra dentro del intervalo de fechas del presupuesto "
|
||||
"%(budget_name)s."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr ""
|
||||
"%(rec_name)s no se encuentra%(res_name)s dentro del intervalo de fechas del "
|
||||
"presupuesto %(budget_name)s"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr "%s (copia)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr "La fecha de inicio de %s no puede ser posterior a la fecha de fin"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
msgid "Account"
|
||||
msgstr "Cuenta"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr "Acción Necesaria"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a "
|
||||
"database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
"Datos reales: datos actuales, de contabilidad y otras consultas.\n"
|
||||
"Datos reales (alternativa): datos actuales de una fuente alternativa (por "
|
||||
"ejemplo, una vista de base de datos que proporciona líneas de movimiento de "
|
||||
"cuenta similares).\n"
|
||||
"Columnas de suma: (+/-) suma de otras columnas.\n"
|
||||
"Comparar con columna: comparar con otra columna.\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr "Permitir el solapamiento de elementos"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr "Importe"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr "Cuenta de archivos adjuntos"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
msgid "Balance"
|
||||
msgstr "Equilibrar"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr "Presupuesto"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
msgid "Budget Date From"
|
||||
msgstr "Fecha de presupuesto desde"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
msgid "Budget Date To"
|
||||
msgstr "Fecha de presupuesto hasta"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr "Presupuesto por cuenta"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
msgid "Budget by KPI"
|
||||
msgstr "Presupuesto por KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr "Elementos del presupuesto"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr "Presupuestable"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr "Cancelado"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr "Compañía"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Company Currency"
|
||||
msgstr "Moneda de la empresa"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmar"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr "Confirmado"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Creado por"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Creado en"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr "Crédito"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr "Fecha"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr "Rango de fecha"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr "Debe"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr "Descripción"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nombre mostrado"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr "Borrador"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
"Campo ficticio que adapta las búsquedas en fecha a búsquedas en date_from / "
|
||||
"date_to."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr "Seguidores"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr "Seguidores (Socios)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr "Desde"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr "Tienes un mensaje"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr "Si está marcado, los nuevos mensajes requieren su atención."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr ""
|
||||
"Si está marcada, se permite el solapamiento entre partidas presupuestarias"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr "Si está marcado, algunos mensajes tienen un error en la entrega."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr "Es seguidor"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr "Objeto"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr "KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr "KPI de Secuencia"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr "etiqueta"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Última modificación en"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Última actualización por"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Última actualización en"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr "Presupuesto MIS (Clase base abstracta)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr "Partida presupuestaria MIS (clase base abstracta)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr "Partida presupuestaria de MIS (por cuenta)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr "Partida presupuestaria MIS (por KPI)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr "Partidas presupuestarias de MIS (por KPI)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr "Partidas presupuestarias de MIS (por cuentas)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr "Presupuesto MIS por cuenta"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr "Presupuesto MIS por KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr "Presupuestos de MIS (por KPIs)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr "Presupuestos MIS (por cuentas)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
msgid "MIS Report Instance"
|
||||
msgstr "Instancia de informe MIS"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr "Período de instancia del informe MIS"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
msgid "MIS Report KPI"
|
||||
msgstr "KPI de informe MIS"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr "Informe MIS - KPI Expresión"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr "Plantilla de presupuesto MIS"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr "Adjunto principal"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr "Mensaje de error en la entrega"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr "Mensajes"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr "Número de acciones"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr "Número de errores"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr "Número de mensajes que requieren una acción"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr "Número de mensajes con error en la entrega"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr "Cambiar a borrador"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr "Origen"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr "Estado"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr "Sub-KPI Secuencia"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr "a"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr "Campo de utilidad para expresar la cantidad de moneda"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr "Mensajes del sitio web"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr "Historial de comunicación del sitio web"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
"¡Valor de crédito o débito incorrecto en la partida presupuestaria! El "
|
||||
"crédito y el débito deben ser positivos."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
||||
"¡Valor de crédito o débito incorrecto en la partida presupuestaria! El "
|
||||
"crédito o débito debe ser cero."
|
||||
|
||||
#~ msgid "SMS Delivery error"
|
||||
#~ msgstr "SMS de error en la entrega"
|
||||
|
||||
#~ msgid "Number of messages which requires an action"
|
||||
#~ msgstr "Número de mensajes que requieren una acción"
|
||||
|
||||
#, python-format
|
||||
#~ msgid "%s is not within budget %s date range."
|
||||
#~ msgstr "%s no está dentro del rango de fechas del presupuesto %s."
|
||||
|
||||
#, python-format
|
||||
#~ msgid "%s overlaps %s in budget %s"
|
||||
#~ msgstr "%s superpone %s en el presupuesto %s"
|
||||
|
||||
#~ msgid "Analytic Tags"
|
||||
#~ msgstr "Etiquetas analíticas"
|
||||
|
||||
#~ msgid "Analytic account"
|
||||
#~ msgstr "Cuenta analítica"
|
||||
|
||||
#~ msgid "Followers (Channels)"
|
||||
#~ msgstr "Seguidores (Canales)"
|
||||
|
||||
#~ msgid "Number of unread messages"
|
||||
#~ msgstr "Número de mensajes no leídos"
|
||||
|
||||
#~ msgid "Unread Messages"
|
||||
#~ msgstr "Mensajes no leídos"
|
||||
|
||||
#~ msgid "Unread Messages Counter"
|
||||
#~ msgstr "Contador de mensajes no leídos"
|
||||
|
||||
#~ msgid "MIS Budget"
|
||||
#~ msgstr "Presupuesto MIS"
|
||||
|
||||
#~ msgid "MIS Budgets"
|
||||
#~ msgstr "Presupuestos MIS"
|
||||
|
||||
#~ msgid "mis.report.instance"
|
||||
#~ msgstr "mis.report.instance"
|
||||
|
||||
#~ msgid "mis.report.kpi"
|
||||
#~ msgstr "mis.report.kpi"
|
||||
|
||||
#~ msgid "mis.report.kpi.expression"
|
||||
#~ msgstr "mis.report.kpi.expression"
|
603
mis_builder_budget/i18n/fr.po
Normal file
603
mis_builder_budget/i18n/fr.po
Normal file
@ -0,0 +1,603 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
# Translators:
|
||||
# OCA Transbot <transbot@odoo-community.org>, 2018
|
||||
# Nicolas JEUDY <njeudy@panda-chi.io>, 2018
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 11.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-02-10 07:59+0000\n"
|
||||
"PO-Revision-Date: 2023-05-26 16:09+0000\n"
|
||||
"Last-Translator: \"Sandrine (ACSONE)\" <sandrine.ravet@acsone.eu>\n"
|
||||
"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 4.17\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
"%(rec_name)s n'est pas compris dans la plage de dates du budget "
|
||||
"%(budget_name)s."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr "%(rec_name)s chevauche %(res_name)s dans le budget %(budget_name)s"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr "%s (copie)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr "la date de début de %s ne doit pas être après la date de fin"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
msgid "Account"
|
||||
msgstr "Compte"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr "Action nécessaire"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a "
|
||||
"database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
"Réel : données de la comptabilité et autres requêtes.\n"
|
||||
"Réel (alternatif) : données d'une source alternative (eg une vue de la base "
|
||||
"de données ressemblant aux écritures comptables).\n"
|
||||
"Additionner colonnes : addition (+/-) d'autres colonnes.\n"
|
||||
"Comparer colonnes : compare d'autres colonnes.\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr "Autoriser chevauchement de données"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr "Montant"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr "Nombre de pièces jointes"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
msgid "Balance"
|
||||
msgstr "Montant"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr "Budget"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
msgid "Budget Date From"
|
||||
msgstr "Date de début du budget"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
msgid "Budget Date To"
|
||||
msgstr "Date de fin du budget"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr "Budget par compte"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
msgid "Budget by KPI"
|
||||
msgstr "Budget par KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr "Lignes de budget"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr "Peut être associé à un budget"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr "Annulé"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr "Société"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Company Currency"
|
||||
msgstr "Devise de la Société"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmer"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr "Confirmé"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Créé par"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Créé le"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr "Crédit"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr "Date"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr "Période"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr "Débit"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nom affiché"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr "Brouillon"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
"Champ factice qui adapte les recherches sur les dates vers des recherches "
|
||||
"sur date_from/date_to."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr "Abonnés"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr "Abonnés (Partenaires)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr "De"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr "A un messsage"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr "Si coché, de nouveaux messages demandent votre attention."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr "Si coché, chevauchement entre des lignes de budget est autorisé"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr "Si coché, certains messages ont une erreur d'envoi."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr "Est abonné"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr "Element"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr "KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr "Séquence du KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr "Libellé"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Dernière modification le"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Dernière mise à jour par"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Dernière mise à jour le"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr "MIS Budget (Abstract Base Class)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr "MIS lignes de budget (Classe abstraite)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr "MIS ligne de budget (par compte)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr "MIS ligne de budget (par KPI)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr "MIS Budget (par KPI)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr "MIS Budget (par compte)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr "MIS budget par compte"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr "MIS budget par KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr "MIS Budget (par KPI)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr "MIS Budget (par compte)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
msgid "MIS Report Instance"
|
||||
msgstr "MIS Modèle de rapport"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr "Période du modèle de rapport MIS"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
msgid "MIS Report KPI"
|
||||
msgstr "KPI du rapport MIS"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr "Expression du KPI du rapport MIS"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr "MIS Modèle de rapport"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr "Pièce jointe principale"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr "Message d'erreur d'envoi"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr "Messages"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr "Nombre d'actions"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr "Nombre d'erreurs"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr "Nombre de messages avec une erreur d'envoi"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr "Passer en brouillon"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr "Source"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr "Etat"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr "Séquence du sous-KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr "À"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr "Champ pour exprimer le montant en devise"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr "Messages du site Web"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr "Historique de communication du site web"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
"Mauvaise valeur du débit ou crédit sur la ligne de budget ! Crédit et débit "
|
||||
"doivent être positifs."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
||||
"Mauvaise valeur au débit ou crédit sur la ligne de budget ! Crédit ou débit "
|
||||
"doit être égal à 0."
|
||||
|
||||
#~ msgid "SMS Delivery error"
|
||||
#~ msgstr "Erreur d'envoi du SMS"
|
||||
|
||||
#~ msgid "Number of messages which requires an action"
|
||||
#~ msgstr "Nombre de messages qui demande une action"
|
||||
|
||||
#, python-format
|
||||
#~ msgid "%s is not within budget %s date range."
|
||||
#~ msgstr "%s n'est pas dans les limites de la période budgétaire %s."
|
||||
|
||||
#, python-format
|
||||
#~ msgid "%s overlaps %s in budget %s"
|
||||
#~ msgstr "%s chevauche %s dans le budget %s"
|
||||
|
||||
#~ msgid "Analytic Tags"
|
||||
#~ msgstr "Étiquettes analytiques"
|
||||
|
||||
#~ msgid "Analytic account"
|
||||
#~ msgstr "Compte analytique"
|
||||
|
||||
#~ msgid "MIS Budget"
|
||||
#~ msgstr "MIS Budget"
|
||||
|
||||
#~ msgid "MIS Budgets"
|
||||
#~ msgstr "MIS Budgets"
|
||||
|
||||
#~ msgid "mis.report.instance"
|
||||
#~ msgstr "mis.report.instance"
|
||||
|
||||
#~ msgid "mis.report.kpi"
|
||||
#~ msgstr "mis.report.kpi"
|
||||
|
||||
#~ msgid "mis.report.kpi.expression"
|
||||
#~ msgstr "mis.report.kpi.expression"
|
550
mis_builder_budget/i18n/hr.po
Normal file
550
mis_builder_budget/i18n/hr.po
Normal file
@ -0,0 +1,550 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: hr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a "
|
||||
"database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
msgid "Balance"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
msgid "Budget Date From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
msgid "Budget Date To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
msgid "Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Company Currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
msgid "MIS Report Instance"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
msgid "MIS Report KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
557
mis_builder_budget/i18n/hr_HR.po
Normal file
557
mis_builder_budget/i18n/hr_HR.po
Normal file
@ -0,0 +1,557 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
# Translators:
|
||||
# OCA Transbot <transbot@odoo-community.org>, 2018
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 11.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-13 15:37+0000\n"
|
||||
"PO-Revision-Date: 2018-01-13 15:37+0000\n"
|
||||
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
|
||||
"Language-Team: Croatian (Croatia) (https://www.transifex.com/oca/teams/23907/"
|
||||
"hr_HR/)\n"
|
||||
"Language: hr_HR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a "
|
||||
"database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
#, fuzzy
|
||||
msgid "Balance"
|
||||
msgstr "Otkaži"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
msgid "Budget Date From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
msgid "Budget Date To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
msgid "Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr "Otkaži"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr "Tvrtka"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
#, fuzzy
|
||||
msgid "Company Currency"
|
||||
msgstr "Tvrtka"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Kreirao"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Kreirano"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Naziv "
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
msgid "MIS Report Instance"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
msgid "MIS Report KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr "Naziv"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
549
mis_builder_budget/i18n/it.po
Normal file
549
mis_builder_budget/i18n/it.po
Normal file
@ -0,0 +1,549 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 15.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a "
|
||||
"database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
msgid "Balance"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
msgid "Budget Date From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
msgid "Budget Date To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
msgid "Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Company Currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
msgid "MIS Report Instance"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
msgid "MIS Report KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
547
mis_builder_budget/i18n/mis_builder_budget.pot
Normal file
547
mis_builder_budget/i18n/mis_builder_budget.pot
Normal file
@ -0,0 +1,547 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
msgid "Balance"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
msgid "Budget Date From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
msgid "Budget Date To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
msgid "Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Company Currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
msgid "MIS Report Instance"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
msgid "MIS Report KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
566
mis_builder_budget/i18n/nl.po
Normal file
566
mis_builder_budget/i18n/nl.po
Normal file
@ -0,0 +1,566 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
# Translators:
|
||||
# Frank Schellenberg <opensource@schellenberg.nl>, 2018
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 11.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-13 15:37+0000\n"
|
||||
"PO-Revision-Date: 2018-01-13 15:37+0000\n"
|
||||
"Last-Translator: Frank Schellenberg <opensource@schellenberg.nl>, 2018\n"
|
||||
"Language-Team: Dutch (https://www.transifex.com/oca/teams/23907/nl/)\n"
|
||||
"Language: nl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr "%s (kopie)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a "
|
||||
"database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
#, fuzzy
|
||||
msgid "Balance"
|
||||
msgstr "Annuleer"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
msgid "Budget Date From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
msgid "Budget Date To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
msgid "Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr "Annuleer"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr "Bedrijf"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
#, fuzzy
|
||||
msgid "Company Currency"
|
||||
msgstr "Bedrijf"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Aangemaakt door"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Aangemaakt op"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr "Omschrijving"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Weergavenaam"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr "Van"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr "KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Voor het laatst aangepast op"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Voor het laatst geüpdatet door"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Voor het laatst geüpdatet op"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
#, fuzzy
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr "MIS Budgetten"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
#, fuzzy
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr "MIS Budgetten"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
#, fuzzy
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr "MIS Budgetten"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
#, fuzzy
|
||||
msgid "MIS Report Instance"
|
||||
msgstr "mis.report.instance"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
#, fuzzy
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr "mis.report.instance.period"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
msgid "MIS Report KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr "Naam"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr "Tot"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "mis.report.kpi"
|
||||
#~ msgstr "mis.report.kpi"
|
||||
|
||||
#~ msgid "mis.report.kpi.expression"
|
||||
#~ msgstr "mis.report.kpi.expression"
|
603
mis_builder_budget/i18n/nl_NL.po
Normal file
603
mis_builder_budget/i18n/nl_NL.po
Normal file
@ -0,0 +1,603 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
# Translators:
|
||||
# OCA Transbot <transbot@odoo-community.org>, 2018
|
||||
# Frank Schellenberg <opensource@schellenberg.nl>, 2018
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 11.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-13 15:37+0000\n"
|
||||
"PO-Revision-Date: 2018-01-13 15:37+0000\n"
|
||||
"Last-Translator: Frank Schellenberg <opensource@schellenberg.nl>, 2018\n"
|
||||
"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/"
|
||||
"teams/23907/nl_NL/)\n"
|
||||
"Language: nl_NL\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr "%s (kopie)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr "%s start datum moet voor de einddatum liggen"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
#, fuzzy
|
||||
msgid "Account"
|
||||
msgstr "Analytische rekening"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a "
|
||||
"database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
#, fuzzy
|
||||
msgid "Balance"
|
||||
msgstr "Annuleer"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr "Begroting"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
#, fuzzy
|
||||
msgid "Budget Date From"
|
||||
msgstr "Begrotingsitems"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
#, fuzzy
|
||||
msgid "Budget Date To"
|
||||
msgstr "Begrotingsitems"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
#, fuzzy
|
||||
msgid "Budget by KPI"
|
||||
msgstr "Begroting"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr "Begrotingsitems"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr "Begrootbaar"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr "Annuleer"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr "Geannuleerd"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr "Bedrijf"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
#, fuzzy
|
||||
msgid "Company Currency"
|
||||
msgstr "Bedrijf"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr "Bevestig"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr "Bevestigd"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Aangemaakt door"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Aangemaakt op"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr "Datumbereik"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr "Omschrijving"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Weergavenaam"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr "Concept"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr "Van"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr "Item"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr "KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Voor het laatst aangepast op"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Voor het laatst geüpdatet door"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Voor het laatst geüpdatet op"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
#, fuzzy
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr "MIS Begrotingsitems"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
#, fuzzy
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr "MIS Begrotingsitem"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
#, fuzzy
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr "MIS Begrotingsitem"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
#, fuzzy
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr "MIS Begrotingsitems"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
#, fuzzy
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr "MIS Begrotingsitems"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
#, fuzzy
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr "MIS Begrotingsitem"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
#, fuzzy
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr "MIS Begrotingsitem"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
#, fuzzy
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr "MIS Begrotingsitems"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
#, fuzzy
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr "MIS Begrotingsitems"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
#, fuzzy
|
||||
msgid "MIS Report Instance"
|
||||
msgstr "MIS Rapport Template"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
#, fuzzy
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr "mis.report.instance.period"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
#, fuzzy
|
||||
msgid "MIS Report KPI"
|
||||
msgstr "MIS Rapport Template"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr "MIS Rapport Template"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr "Naam"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr "Set concept in"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr "Status"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr "Tot"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
||||
|
||||
#, python-format
|
||||
#~ msgid "%s is not within budget %s date range."
|
||||
#~ msgstr "%s valt niet binnen het datumbereik van begroting %s."
|
||||
|
||||
#, python-format
|
||||
#~ msgid "%s overlaps %s in budget %s"
|
||||
#~ msgstr "%s overlapt %s in begroting %s"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Analytic Tags"
|
||||
#~ msgstr "Analytische rekening"
|
||||
|
||||
#~ msgid "Analytic account"
|
||||
#~ msgstr "Analytische rekening"
|
||||
|
||||
#~ msgid "MIS Budget"
|
||||
#~ msgstr "MIS Budgetten"
|
||||
|
||||
#~ msgid "MIS Budgets"
|
||||
#~ msgstr "MIS Begrotingen"
|
||||
|
||||
#~ msgid "mis.report.instance"
|
||||
#~ msgstr "mis.report.instance"
|
||||
|
||||
#~ msgid "mis.report.kpi"
|
||||
#~ msgstr "mis.report.kpi"
|
||||
|
||||
#~ msgid "mis.report.kpi.expression"
|
||||
#~ msgstr "mis.report.kpi.expression"
|
555
mis_builder_budget/i18n/pt.po
Normal file
555
mis_builder_budget/i18n/pt.po
Normal file
@ -0,0 +1,555 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
# Translators:
|
||||
# OCA Transbot <transbot@odoo-community.org>, 2018
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 11.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-13 15:37+0000\n"
|
||||
"PO-Revision-Date: 2018-01-13 15:37+0000\n"
|
||||
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
|
||||
"Language-Team: Portuguese (https://www.transifex.com/oca/teams/23907/pt/)\n"
|
||||
"Language: pt\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a "
|
||||
"database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
#, fuzzy
|
||||
msgid "Balance"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
msgid "Budget Date From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
msgid "Budget Date To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
msgid "Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr "Empresa"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
#, fuzzy
|
||||
msgid "Company Currency"
|
||||
msgstr "Empresa"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Criado por"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Criado em"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nome a exibir"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Última Modificação em"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Última atualização por"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Última atualização em"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
msgid "MIS Report Instance"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
msgid "MIS Report KPI"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
618
mis_builder_budget/i18n/pt_BR.po
Normal file
618
mis_builder_budget/i18n/pt_BR.po
Normal file
@ -0,0 +1,618 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * mis_builder_budget
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2023-10-30 21:38+0000\n"
|
||||
"Last-Translator: Adriano Prado <adrianojprado@gmail.com>\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 4.17\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s is not within budget %(budget_name)s date range."
|
||||
msgstr ""
|
||||
"%(rec_name)s não está dentro do intervalo de datas do orçamento "
|
||||
"%(budget_name)s."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%(rec_name)s overlaps %(res_name)s in budget %(budget_name)s"
|
||||
msgstr "%(rec_name)s se sobrepõe a %(res_name)s no orçamento %(budget_name)s"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s (copy)"
|
||||
msgstr "%s (cópia)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#. odoo-python
|
||||
#: code:addons/mis_builder_budget/models/mis_budget_item_abstract.py:0
|
||||
#, python-format
|
||||
msgid "%s start date must not be after end date"
|
||||
msgstr "%s data inicial não deve ser após a data final"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__account_id
|
||||
msgid "Account"
|
||||
msgstr "Conta"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "Action Needed"
|
||||
msgstr "Ação Necessária"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid ""
|
||||
"Actuals: current data, from accounting and other queries.\n"
|
||||
"Actuals (alternative): current data from an alternative source (eg a "
|
||||
"database view providing look-alike account move lines).\n"
|
||||
"Sum columns: summation (+/-) of other columns.\n"
|
||||
"Compare to column: compare to other column.\n"
|
||||
msgstr ""
|
||||
"Dados reais: dados atuais, provenientes de contabilidade e outras consultas."
|
||||
"\n"
|
||||
"Dados reais (alternativo): dados atuais de uma fonte alternativa (por "
|
||||
"exemplo, uma visualização de banco de dados que fornece linhas de "
|
||||
"movimentação de conta semelhantes).\n"
|
||||
"Colunas de soma: soma (+/-) de outras colunas.\n"
|
||||
"Compare com a coluna: compare com outra coluna.\n"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "Allow Items Overlap"
|
||||
msgstr "Permitir Sobreposição de Itens"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__amount
|
||||
msgid "Amount"
|
||||
msgstr "Montante"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_attachment_count
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_attachment_count
|
||||
msgid "Attachment Count"
|
||||
msgstr "Contagem de Anexos"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__balance
|
||||
msgid "Balance"
|
||||
msgstr "Saldo"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_id
|
||||
msgid "Budget"
|
||||
msgstr "Orçamento"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_from
|
||||
msgid "Budget Date From"
|
||||
msgstr "Data Inicial do Orçamento"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__budget_date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__budget_date_to
|
||||
msgid "Budget Date To"
|
||||
msgstr "Data Final do Orçamento"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_by_account_id
|
||||
msgid "Budget by Account"
|
||||
msgstr "Orçamento por Conta"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source_mis_budget_id
|
||||
msgid "Budget by KPI"
|
||||
msgstr "Orçamento por KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Budget items"
|
||||
msgstr "Itens do Orçamento"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_kpi__budgetable
|
||||
msgid "Budgetable"
|
||||
msgstr "Orçamentável"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__cancelled
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr "Cancelado"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__company_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_id
|
||||
msgid "Company"
|
||||
msgstr "Empresa"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Company Currency"
|
||||
msgstr "Moeda da Empresa"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmar"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__confirmed
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__confirmed
|
||||
msgid "Confirmed"
|
||||
msgstr "Confirmado"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Criado por"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__create_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Criado em"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__credit
|
||||
msgid "Credit"
|
||||
msgstr "Crédito"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid "Date"
|
||||
msgstr "Data"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_range_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_range_id
|
||||
msgid "Date range"
|
||||
msgstr "Período"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__debit
|
||||
msgid "Debit"
|
||||
msgstr "Débito"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__description
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__description
|
||||
msgid "Description"
|
||||
msgstr "Descrição"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__display_name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nome de Exibição"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_abstract__state__draft
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_budget_by_account__state__draft
|
||||
msgid "Draft"
|
||||
msgstr "Rascunho"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__date
|
||||
msgid ""
|
||||
"Dummy field that adapts searches on date to searches on date_from/date_to."
|
||||
msgstr ""
|
||||
"Campo fictício que adapta as buscas por data às buscas por date_from/date_to."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_follower_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_follower_ids
|
||||
msgid "Followers"
|
||||
msgstr "Seguidores"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_partner_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_partner_ids
|
||||
msgid "Followers (Partners)"
|
||||
msgstr "Seguidores (Parceiros)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_from
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_from
|
||||
msgid "From"
|
||||
msgstr "De"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__has_message
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__has_message
|
||||
msgid "Has Message"
|
||||
msgstr "Tem Mensagem"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr "Se selecionado, novas mensagens exigirão sua atenção."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__allow_items_overlap
|
||||
msgid "If checked, overlap between budget items is allowed"
|
||||
msgstr "Se marcado, a sobreposição entre itens do orçamento é permitida"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr "Se selecionado, algumas mensagens terão um erro de entrega."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_is_follower
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_is_follower
|
||||
msgid "Is Follower"
|
||||
msgstr "É Seguidor"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__item_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__item_ids
|
||||
msgid "Item"
|
||||
msgstr "Item"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__kpi_expression_id
|
||||
msgid "KPI"
|
||||
msgstr "KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq1
|
||||
msgid "KPI Sequence"
|
||||
msgstr "Sequência KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__name
|
||||
msgid "Label"
|
||||
msgstr "Rótulo"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item____last_update
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Última Modificação em"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_uid
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Última Atualização por"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__write_date
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Última Atualização em"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_abstract
|
||||
msgid "MIS Budget (Abstract Base Class)"
|
||||
msgstr "Orçamento SIG (Classe Base Abstrata)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item_abstract
|
||||
msgid "MIS Budget Item (Abstract Base Class)"
|
||||
msgstr "Item de Orçamento SIG (Classe Base Abstrata)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account_item
|
||||
msgid "MIS Budget Item (by Account)"
|
||||
msgstr "Item de orçamento SIG (por conta)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_item
|
||||
msgid "MIS Budget Item (by KPI)"
|
||||
msgstr "Item de orçamento SIG (por KPI)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_item_act_window
|
||||
msgid "MIS Budget Items (by KPIs)"
|
||||
msgstr "Itens de orçamento SIG (por KPIs)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_item_act_window
|
||||
msgid "MIS Budget Items (by accounts)"
|
||||
msgstr "Itens de orçamento SIG (por contas)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget_by_account
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget_by_account
|
||||
msgid "MIS Budget by Account"
|
||||
msgstr "Orçamento SIG por Conta"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_budget
|
||||
#: model:ir.model.fields.selection,name:mis_builder_budget.selection__mis_report_instance_period__source__mis_budget
|
||||
msgid "MIS Budget by KPI"
|
||||
msgstr "Orçamento SIG por KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_menu
|
||||
msgid "MIS Budgets (by KPIs)"
|
||||
msgstr "Orçamentos SIG (por KPIs)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.actions.act_window,name:mis_builder_budget.mis_budget_by_account_act_window
|
||||
#: model:ir.ui.menu,name:mis_builder_budget.mis_budget_by_account_menu
|
||||
msgid "MIS Budgets (by accounts)"
|
||||
msgstr "Orçamentos SIG (por contas)"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance
|
||||
msgid "MIS Report Instance"
|
||||
msgstr "Instância do Relatório SIG"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_instance_period
|
||||
msgid "MIS Report Instance Period"
|
||||
msgstr "Período da Instância do Relatório SIG"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi
|
||||
msgid "MIS Report KPI"
|
||||
msgstr "Relatório KPI SIG"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model,name:mis_builder_budget.model_mis_report_kpi_expression
|
||||
msgid "MIS Report KPI Expression"
|
||||
msgstr "Expressão de KPI do relatório SIG"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__report_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__report_id
|
||||
msgid "MIS Report Template"
|
||||
msgstr "Modelo do Relatório SIG"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_main_attachment_id
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_main_attachment_id
|
||||
msgid "Main Attachment"
|
||||
msgstr "Anexo Principal"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error
|
||||
msgid "Message Delivery error"
|
||||
msgstr "Erro de Entrega de Mensagem"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_ids
|
||||
msgid "Messages"
|
||||
msgstr "Mensagens"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__name
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__name
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of Actions"
|
||||
msgstr "Número de Ações"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of errors"
|
||||
msgstr "Número de erros"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_needaction_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_needaction_counter
|
||||
msgid "Number of messages requiring action"
|
||||
msgstr "Número de mensagens que exigem ação"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__message_has_error_counter
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__message_has_error_counter
|
||||
msgid "Number of messages with delivery error"
|
||||
msgstr "Número de mensagens com erro de entrega"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_by_account_form_view
|
||||
#: model_terms:ir.ui.view,arch_db:mis_builder_budget.mis_budget_form_view
|
||||
msgid "Set draft"
|
||||
msgstr "Definir como Rascunho"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_report_instance_period__source
|
||||
msgid "Source"
|
||||
msgstr "Fonte"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__state
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__state
|
||||
msgid "State"
|
||||
msgstr "Estado"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__seq2
|
||||
msgid "Sub-KPI Sequence"
|
||||
msgstr "Sequência Sub-KPI"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item__date_to
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_item_abstract__date_to
|
||||
msgid "To"
|
||||
msgstr "Para"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account_item__company_currency_id
|
||||
msgid "Utility field to express amount currency"
|
||||
msgstr "Campo útil para expressar a quantidade em moeda"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,field_description:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website Messages"
|
||||
msgstr "Mensagens do Site"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_abstract__website_message_ids
|
||||
#: model:ir.model.fields,help:mis_builder_budget.field_mis_budget_by_account__website_message_ids
|
||||
msgid "Website communication history"
|
||||
msgstr "Histórico de Comunicação do Site"
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit2
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit and debit should be "
|
||||
"positive."
|
||||
msgstr ""
|
||||
"Valor errado de crédito ou débito no item do orçamento! Crédito e débito "
|
||||
"devem ser positivos."
|
||||
|
||||
#. module: mis_builder_budget
|
||||
#: model:ir.model.constraint,message:mis_builder_budget.constraint_mis_budget_by_account_item_credit_debit1
|
||||
msgid ""
|
||||
"Wrong credit or debit value in budget item! Credit or debit should be zero."
|
||||
msgstr ""
|
||||
"Valor errado de crédito ou débito no item do orçamento! Crédito e débito "
|
||||
"devem ser zero."
|
||||
|
||||
#~ msgid "SMS Delivery error"
|
||||
#~ msgstr "Erro na Entrega de SMS"
|
||||
|
||||
#~ msgid "Number of messages which requires an action"
|
||||
#~ msgstr "Número de mensagens que exigem uma atenção"
|
||||
|
||||
#, python-format
|
||||
#~ msgid "%s is not within budget %s date range."
|
||||
#~ msgstr "%s não está dentro do período %s do orçamento."
|
||||
|
||||
#, python-format
|
||||
#~ msgid "%s overlaps %s in budget %s"
|
||||
#~ msgstr "%s sobreposto %s no orçamento %s"
|
||||
|
||||
#~ msgid "Analytic Tags"
|
||||
#~ msgstr "Marcadores Analíticos"
|
||||
|
||||
#~ msgid "Analytic account"
|
||||
#~ msgstr "Conta analítica"
|
||||
|
||||
#~ msgid "Followers (Channels)"
|
||||
#~ msgstr "Seguidores (Canais)"
|
||||
|
||||
#~ msgid "Number of unread messages"
|
||||
#~ msgstr "Número de mensagens não lidas"
|
||||
|
||||
#~ msgid "Unread Messages"
|
||||
#~ msgstr "Mensagens não lidas"
|
||||
|
||||
#~ msgid "Unread Messages Counter"
|
||||
#~ msgstr "Contagem de Mensagens Não Lidas"
|
||||
|
||||
#~ msgid "Actuals"
|
||||
#~ msgstr "Reais"
|
||||
|
||||
#~ msgid "Actuals (alternative)"
|
||||
#~ msgstr "Reais (alternativa)"
|
||||
|
||||
#~ msgid "Compare columns"
|
||||
#~ msgstr "Comparar colunas"
|
||||
|
||||
#~ msgid "If checked new messages require your attention."
|
||||
#~ msgstr "Se selecionado novas mensagens exigirão sua atenção."
|
||||
|
||||
#~ msgid "MIS Budget"
|
||||
#~ msgstr "Orçamento SIG"
|
||||
|
||||
#~ msgid "MIS Budgets"
|
||||
#~ msgstr "Orçamentos SIG"
|
||||
|
||||
#~ msgid "Sum columns"
|
||||
#~ msgstr "Somar colunas"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user