Initial commit

This commit is contained in:
Leszek Manicki 2019-05-06 11:40:59 +02:00
commit c0296ab2a8
107 changed files with 17570 additions and 0 deletions

661
COPYING Normal file
View File

@ -0,0 +1,661 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://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 <https://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
<https://www.gnu.org/licenses/>.

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from . import wizard
from . import models

View File

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': "ITIS HR Attendance Extend",
'summary': """ Module will extend HR Attendance""",
'description': """
Module to extend HR Attendance
""",
'author': "IT IS AG",
'website': "http://www.itis-odoo.de",
'category': 'base',
'version': '1.0.55.0',
'depends': ['hr_attendance', 'hr_timesheet', 'hr_timesheet_sheet'],
'data': [
'security/groups.xml',
'views/hr_timesheet_sheet_view.xml',
'views/itis_holiday_view.xml',
'views/templates.xml',
'views/hr_holiday_view.xml',
'wizard/sign_in_task_view.xml',
'wizard/hr_timesheet_overview_export.xml',
'security/ir.model.access.csv',
'data/cron.xml',
'data/data.xml',
],
'qweb': ['static/src/xml/templates.xml'],
'css': [],
'demo': [],

View File

@ -0,0 +1,80 @@
<openerp>
<data noupdate="1">
<record id="itis_close_timesheets_cron" model="ir.cron">
<field name="name">ITIS Timesheets Monat abschließen</field>
<field name="function">close_timesheet</field>
<field name="interval_type">months</field>
<field name="interval_number">1</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="(True)"/>
<field name="numbercall">-1</field>
<field name="model">hr_timesheet_sheet.sheet</field>
<field name="nextcall" eval="(datetime.strptime('2017-01-05 03:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>
</record>
<record id="itis_setting_cost_center_cron" model="ir.cron">
<field name="name">ITIS Setting Cost Center for Existing Records</field>
<field name="function">set_cost_center_existing_rec</field>
<field name="interval_type">days</field>
<field name="interval_number">1</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="(False)"/>
<field name="numbercall">-1</field>
<field name="model">hr.analytic.timesheet</field>
<field name="nextcall" eval="(datetime.strptime('2017-07-01 03:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>
</record>
<record id="itis_get_timesheet_overview_cron" model="ir.cron">
<field name="name">ITIS Get Monthly Timesheet Overview</field>
<field name="function">get_monthly_timesheet_overview</field>
<field name="interval_type">months</field>
<field name="interval_number">1</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="(True)"/>
<field name="numbercall">-1</field>
<field name="model">hr.analytic.timesheet</field>
<field name="nextcall" eval="(datetime.strptime('2017-07-01 03:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>
</record>
<!--scheduler to create a timesheet daily basis base upon the contract-->
<record id="itis_create_daily_timesheet_cron" model="ir.cron">
<field name="name">ITIS Create Daily Timesheet</field>
<field name="function">create_daily_timesheet</field>
<field name="interval_type">days</field>
<field name="interval_number">1</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="(True)"/>
<field name="numbercall">-1</field>
<field name="model">hr_timesheet_sheet.sheet</field>
<field name="nextcall" eval="(datetime.strptime('2017-05-31 02:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>
</record>
<!--scheduler to create a timesheet for the missing date base upon the contract-->
<record id="itis_create_missingdate_timesheet_cron" model="ir.cron">
<field name="name">ITIS Create Missing Date Timesheet</field>
<field name="function">create_missingdate_timesheet</field>
<field name="interval_type">months</field>
<field name="interval_number">1</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="(False)"/>
<field name="numbercall">-1</field>
<field name="model">hr_timesheet_sheet.sheet</field>
<field name="nextcall" eval="(datetime.strptime('2017-05-31 02:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>
</record>
<!--scheduler to automatically sign out the employee which are not log out-->
<record id="itis_automatic_sign_out_cron" model="ir.cron">
<field name="name">ITIS Employee Sign Out</field>
<field name="function">automatic_sign_out</field>
<field name="interval_type">days</field>
<field name="interval_number">1</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="(True)"/>
<field name="numbercall">-1</field>
<field name="model">hr_timesheet_sheet.sheet</field>
<field name="nextcall" eval="(datetime.strptime('2017-05-31 20:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>
</record>
</data>
</openerp>

View File

@ -0,0 +1,28 @@
<openerp>
<data noupdate="1">
<record id="itis_holiday_leave_type_new" model="hr.holidays.status">
<field name="name">Holiday</field>
<field name="limit">True</field>
<field name="is_holiday">True</field>
</record>
<record id="email_template_monthly_timesheet_overview" model="email.template">
<field name="name">Monthly Timesheet Overview</field>
<field name="model_id" ref="itis_hr_attendance_extend.model_hr_analytic_timesheet" />
<field name="auto_delete" eval="True" />
<field name="email_from">${(user.email or '') | safe}</field>
<field name="email_to">${(user.email or '') | safe}</field>
<field name="subject">Monthly Timesheet Overview Report</field>
<field name="body_html"><![CDATA[
<p>Sehr geehrte Kollegen,</p>
<br/>
<p>anbei erhalten Sie den aktuellen Report zur Kostenstellenübersicht nach Mitarbeiter.
</p><br/>
<p>Mit freundlichen Grüßen</p>
<p>Ihr HR-Team</p>
]]>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,624 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * itis_hr_attendance_extend
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-19 13:19+0000\n"
"PO-Revision-Date: 2017-09-19 15:22+0100\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.4\n"
#. module: itis_hr_attendance_extend
#: model:email.template,body_html:itis_hr_attendance_extend.email_template_monthly_timesheet_overview
msgid ""
"\n"
"\t\t\t<p>Sehr geehrte Kollegen,</p>\n"
"\t\t\t<br/>\n"
"\t\t\t<p>anbei erhalten Sie den aktuellen Report zur Kostenstellenübersicht "
"nach Mitarbeiter.\n"
"\t\t\t</p><br/>\n"
"\t\t\t<p>Mit freundlichen Grüßen</p>\n"
"\t\t\t<p>Ihr HR-Team</p>\n"
"\t\t\t\n"
"\t\t\t"
msgstr ""
"\n"
"\t\t\t<p>Sehr geehrte Kollegen,</p>\n"
"\t\t\t<br/>\n"
"\t\t\t<p>anbei erhalten Sie den aktuellen Report zur Kostenstellenübersicht "
"nach Mitarbeiter.\n"
"\t\t\t</p><br/>\n"
"\t\t\t<p>Mit freundlichen Grüßen</p>\n"
"\t\t\t<p>Ihr HR-Team</p>\n"
"\t\t\t\n"
"\t\t\t"
#. module: itis_hr_attendance_extend
#: field:account.analytic.account,account_code:0
msgid "Account Code"
msgstr "Kürzel Kostenstelle"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:453
#, python-format
msgid "Actual Overttime Count"
msgstr "Über-/Unterstunden"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:58
#, python-format
msgid "Add"
msgstr "Hinzufügen"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:64
#, python-format
msgid "Add a Line"
msgstr "Zeile hinzufügen"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/static/src/js/hr_extend.js:125
#, python-format
msgid "Add comment"
msgstr "Add comment"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_account_analytic_account
#: field:sign.in.task,analytic_account_id:0
msgid "Analytic Account"
msgstr "Kostenstelle"
#. module: itis_hr_attendance_extend
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.hr_timesheet_overview_search
msgid "Analytic account"
msgstr "Kostenstelle"
#. module: itis_hr_attendance_extend
#: field:hr.attendance,timesheet_id:0
msgid "Anlytic Timesheet"
msgstr "Zeiterfassung"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
msgid "Approve"
msgstr "Genehmige"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_attendance
msgid "Attendance"
msgstr "Anwesenheit"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
msgid "Attendances"
msgstr "Anwesenheitszeiten"
#. module: itis_hr_attendance_extend
#: view:sign.in.task:itis_hr_attendance_extend.sign_in_task_form_view
#: view:timesheet.overview.export:itis_hr_attendance_extend.timesheet_overview_export_form_view
msgid "Cancel"
msgstr "Abbrechen"
#. module: itis_hr_attendance_extend
#: view:timesheet.overview.export:itis_hr_attendance_extend.timesheet_overview_export_form_view
msgid "Click 'Export' button to export timesheet overview csv"
msgstr ""
"Auf 'Export' klicken um die Übersicht der Zeiterfassungen als CSV zu "
"exportieren"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,emp_comment:0 field:sign.in.task,emp_comment:0
msgid "Comment"
msgstr "Kommentar"
#. module: itis_hr_attendance_extend
#: model:ir.actions.act_window,name:itis_hr_attendance_extend.act_hr_timesheet_sheet
#: model:ir.ui.menu,name:itis_hr_attendance_extend.menu_act_hr_timesheet_sheet_form_my_current_editable
msgid "Create Timesheet"
msgstr "Timesheet anlegen"
#. module: itis_hr_attendance_extend
#: field:itis.holiday,create_uid:0 field:planned.hours,create_uid:0
#: field:service.description,create_uid:0 field:sign.in.task,create_uid:0
#: field:timesheet.overview.export,create_uid:0
msgid "Created by"
msgstr "Erstellt von"
#. module: itis_hr_attendance_extend
#: field:itis.holiday,create_date:0 field:planned.hours,create_date:0
#: field:service.description,create_date:0 field:sign.in.task,create_date:0
#: field:timesheet.overview.export,create_date:0
msgid "Created on"
msgstr "Erstellt am"
#. module: itis_hr_attendance_extend
#: field:itis.holiday,date:0 field:planned.hours,sheet_date:0
msgid "Date"
msgstr "Datum"
#. module: itis_hr_attendance_extend
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.hr_timesheet_overview_search
msgid "Date From"
msgstr "Von"
#. module: itis_hr_attendance_extend
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.hr_timesheet_overview_search
msgid "Date To"
msgstr "Bis"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:86
#, python-format
msgid "Date should be between timesheet date."
msgstr "Das Datum muss innerhalb des Datumsbereichs liegen."
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,dept_account_id:0
msgid "Dept. Analytic Account"
msgstr "Kostenstelle Bereich"
#. module: itis_hr_attendance_extend
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.hr_timesheet_overview_search
msgid "Dept. Analytic account"
msgstr "Kostenstelle Bereich"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
msgid "Details"
msgstr "Details"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
msgid "Differences"
msgstr "Differenzen"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_employee
msgid "Employee"
msgstr "Mitarbeiter/-in"
#. module: itis_hr_attendance_extend
#: model:ir.actions.act_window,name:itis_hr_attendance_extend.emp_service_description_action
msgid "Employee Service Description"
msgstr "Leistung"
#. module: itis_hr_attendance_extend
#: view:timesheet.overview.export:itis_hr_attendance_extend.timesheet_overview_export_form_view
msgid "Export"
msgstr "Export"
#. module: itis_hr_attendance_extend
#: view:timesheet.overview.export:itis_hr_attendance_extend.timesheet_overview_export_form_view
msgid "Export file:"
msgstr "Export Datei:"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/wizard/hr_timesheet_overview_export.py:97
#, python-format
msgid "Exported Timsheet Overview"
msgstr "exportierter Zeiterfassungsbericht"
#. module: itis_hr_attendance_extend
#: field:timesheet.overview.export,file_name:0
msgid "File"
msgstr "File"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "Geplante Stunden"
msgstr "Geplante Stunden"
#. module: itis_hr_attendance_extend
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.hr_timesheet_overview_search
msgid "Group By"
msgstr "Gruppierung"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Group by month of date"
msgstr "nach Monat gruppieren"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Group by week of date"
msgstr "nach Woche gruppieren"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Group by year of date"
msgstr "nach Jahr gruppieren"
#. module: itis_hr_attendance_extend
#: model:hr.holidays.status,name:itis_hr_attendance_extend.itis_holiday_leave_type_new
#: view:itis.holiday:itis_hr_attendance_extend.view_calendar_itis_holiday
msgid "Holiday"
msgstr "Urlaub"
#. module: itis_hr_attendance_extend
#: field:hr.holidays,holiday_name:0 field:itis.holiday,name:0
msgid "Holiday Name"
msgstr "Feiertag"
#. module: itis_hr_attendance_extend
#: model:ir.actions.act_window,name:itis_hr_attendance_extend.act_itis_holiday
#: model:ir.ui.menu,name:itis_hr_attendance_extend.menu_itis_holiday
msgid "Holidays"
msgstr "Feiertage"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
#: field:planned.hours,duration:0
msgid "Hours"
msgstr "Stunden"
#. module: itis_hr_attendance_extend
#: field:itis.holiday,id:0 field:planned.hours,id:0
#: field:service.description,id:0 field:sign.in.task,id:0
#: field:timesheet.overview.export,id:0
msgid "ID"
msgstr "ID"
#. module: itis_hr_attendance_extend
#: field:itis.holiday,write_uid:0 field:planned.hours,write_uid:0
#: field:service.description,write_uid:0 field:sign.in.task,write_uid:0
#: field:timesheet.overview.export,write_uid:0
msgid "Last Updated by"
msgstr "Aktualisiert von"
#. module: itis_hr_attendance_extend
#: field:itis.holiday,write_date:0 field:planned.hours,write_date:0
#: field:service.description,write_date:0 field:sign.in.task,write_date:0
#: field:timesheet.overview.export,write_date:0
msgid "Last Updated on"
msgstr "Aktualisiert am"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_holidays
msgid "Leave"
msgstr "Urlaub"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_holiday.py:90
#, python-format
msgid "Leave Request"
msgstr "Leave Request"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Month"
msgstr "Monat"
#. module: itis_hr_attendance_extend
#: model:email.template,subject:itis_hr_attendance_extend.email_template_monthly_timesheet_overview
msgid "Monthly Timesheet Overview Report"
msgstr "Monatlicher Bericht der Zeiterfassungen"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_payroll.py:58
#, python-format
msgid "Normal Working Days paid at 100%"
msgstr "Normaler Arbeitstag bezahlt zu 100%"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:458
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:101
#, python-format
msgid "Overtime Hours"
msgstr "Überstunden"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_payslip
msgid "Pay Slip"
msgstr "Mitarbeitervergütung"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
msgid "Period"
msgstr "Periode"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:452
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:456
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:88
#: field:hr_timesheet_sheet.sheet,planned_ids:0
#, python-format
msgid "Planned Hours"
msgstr "Geplante Stunden"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/wizard/sign_in_task.py:55
#, python-format
msgid "Please define cost unit for this employee."
msgstr "Bitte tragen Sie die Kostenstelle für den Mitarbeiter ein."
#. module: itis_hr_attendance_extend
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.hr_timesheet_overview_search
msgid "Product"
msgstr "Produkt"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Refresh"
msgstr "Aktualisieren"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Refuse"
msgstr "Zurücksetzen"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/static/src/js/hr_extend.js:117
#, python-format
msgid "Select Service Description"
msgstr "Leistung auswählen"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,service_desc_id:0
#: field:sign.in.task,service_desc_id:0
msgid "Service Desc"
msgstr "Leistung"
#. module: itis_hr_attendance_extend
#: model:ir.ui.menu,name:itis_hr_attendance_extend.menu_emp_service_description
#: view:service.description:itis_hr_attendance_extend.itis_service_description_form
#: view:service.description:itis_hr_attendance_extend.itis_service_description_tree
#: field:service.description,name:0
msgid "Service Description"
msgstr "Leistung"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
msgid "Set to Draft"
msgstr "Setze auf Entwurf"
#. module: itis_hr_attendance_extend
#: field:planned.hours,sheet_id:0
msgid "Sheet"
msgstr "Tabelle"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Sign In"
msgstr "Anmelden"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Sign Out"
msgstr "Abmelden"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:297
#, python-format
msgid "Start date and end date have to be the same day."
msgstr "Start und Enddatum müssen derselbe Tag sein."
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
msgid "Submit to Manager"
msgstr "Dem Manager vorlegen"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
msgid "Summary"
msgstr "Zusammenfassung"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "Summe Stunden"
msgstr "Summe Stunden"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_holiday.py:38
#, python-format
msgid "The start date must be anterior to the end date."
msgstr "Das startdatum muss vor dem Enddatum liegen."
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:451
#, python-format
msgid "Time Diffrence"
msgstr "Zeit Differenz"
#. module: itis_hr_attendance_extend
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.hr_timesheet_overview_search
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
#: field:hr_timesheet_sheet.sheet,timesheet_ids2:0
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_timesheet_sheet_sheet
msgid "Timesheet"
msgstr "Stundenzettel"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Timesheet Activities"
msgstr "Zeiterfassungsaktivitäten"
#. module: itis_hr_attendance_extend
#: model:ir.actions.server,name:itis_hr_attendance_extend.ir_actions_server_hr_timesheet_overview_manager
#: model:ir.ui.menu,name:itis_hr_attendance_extend.menu_hr_timesheet_overview_manager
msgid "Timesheet Activities Manager"
msgstr "Zeiterfassung Übersicht"
#. module: itis_hr_attendance_extend
#: model:ir.actions.act_window,name:itis_hr_attendance_extend.act_hr_timesheet_overview
#: model:ir.ui.menu,name:itis_hr_attendance_extend.menu_hr_timesheet_overview
msgid "Timesheet Activities Overview"
msgstr "Bericht Zeiterfassung"
#. module: itis_hr_attendance_extend
#: field:timesheet.overview.export,name:0
msgid "Timesheet CSV"
msgstr "Timesheet CSV"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_analytic_timesheet
msgid "Timesheet Line"
msgstr "Zeiterfassung Positionen"
#. module: itis_hr_attendance_extend
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.hr_timesheet_overview_search
msgid "Timesheet Month"
msgstr "monatliche Zeiterfassung"
#. module: itis_hr_attendance_extend
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.view_timehseet_activity_overview_tree
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.view_timehseet_activity_overview_tree_manager
msgid "Timesheet Overview"
msgstr "Zeiterfassung Übersicht"
#. module: itis_hr_attendance_extend
#: model:ir.actions.act_window,name:itis_hr_attendance_extend.launch_timesheet_overview_export_wizard
#: model:ir.actions.act_window,name:itis_hr_attendance_extend.timehseet_overview_export_action
msgid "Timesheet Overview Export"
msgstr "Zeiterfassung Übersicht Export"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
msgid "Timesheet Period"
msgstr "Zeiterfassungsperiode"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Timesheet Summary"
msgstr "Zusammenfassung"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Timesheet abschließen"
msgstr "Timesheet abschließen"
#. module: itis_hr_attendance_extend
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.hr_timesheet_overview_search
msgid "Timesheet by Month"
msgstr "Zeiterfassung nach Monat"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
msgid "Timesheets"
msgstr "Zeiterfassung"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:31
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:65
#, python-format
msgid "Total"
msgstr "Total"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:457
#, python-format
msgid "Total Hours"
msgstr "Summe Stunden"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:450
#, python-format
msgid "Total Planned Hours"
msgstr "Arbeitszeit-Soll"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "Total time"
msgstr "Total time"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "True"
msgstr "True"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/wizard/sign_in_task.py:55
#, python-format
msgid "User Error!"
msgstr "Benutzerfehler!"
#. module: itis_hr_attendance_extend
#: view:hr.analytic.timesheet:itis_hr_attendance_extend.hr_timesheet_overview_search
msgid "Users"
msgstr "Benutzer"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_holiday.py:38
#, python-format
msgid "Warning!"
msgstr "Warning!"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Week"
msgstr "Woche"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Year"
msgstr "Jahr"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:299
#, python-format
msgid "You can only create one timesheet each day."
msgstr "Es darf pro Tag nur eine Zeiterfassung existieren."
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:305
#, python-format
msgid "You do not have pemission to create timesheets!"
msgstr "Sie haben keine Berechtigung Timesheets anzulegen!"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "[('date_from', '>=',self)]"
msgstr "[('date_from', '>=',self)]"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "false"
msgstr "false"
#. module: itis_hr_attendance_extend
#: view:sign.in.task:itis_hr_attendance_extend.sign_in_task_form_view
#: view:timesheet.overview.export:itis_hr_attendance_extend.timesheet_overview_export_form_view
msgid "or"
msgstr "oder"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_form_editable_itis_new
msgid "to"
msgstr "to"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "total_contract_time"
msgstr "total_contract_time"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "total_overtime_time"
msgstr "total_overtime_time"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "Überstunden"
msgstr "Überstunden"

View File

@ -0,0 +1,530 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * itis_hr_attendance_extend
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-23 07:26+0000\n"
"PO-Revision-Date: 2017-06-23 09:29+0100\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.4\n"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,currency_id:0
msgid "Account Currency"
msgstr "Account Currency"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:320
#: field:hr_timesheet_sheet.sheet,actual_ot:0
#, python-format
msgid "Actual Overttime Count"
msgstr "Actual Overttime Count"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:58
#, python-format
msgid "Add"
msgstr "Add"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:64
#, python-format
msgid "Add a Line"
msgstr "Add a Line"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/static/src/js/hr_extend.js:125
#, python-format
msgid "Add comment"
msgstr "Add comment"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,amount:0
msgid "Amount"
msgstr "Amount"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,amount_currency:0
msgid "Amount Currency"
msgstr "Amount Currency"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,account_id:0
#: field:sign.in.task,analytic_account_id:0
msgid "Analytic Account"
msgstr "Analytic Account"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,journal_id:0
msgid "Analytic Journal"
msgstr "Analytic Journal"
#. module: itis_hr_attendance_extend
#: field:hr.attendance,timesheet_id:0
msgid "Anlytic Timesheet"
msgstr "Anlytic Timesheet"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_attendance
msgid "Attendance"
msgstr "Attendance"
#. module: itis_hr_attendance_extend
#: help:hr.analytic.timesheet,amount:0
msgid ""
"Calculated by multiplying the quantity and the price given in the Product's "
"cost price. Always expressed in the company main currency."
msgstr ""
"Calculated by multiplying the quantity and the price given in the Product's "
"cost price. Always expressed in the company main currency."
#. module: itis_hr_attendance_extend
#: view:sign.in.task:itis_hr_attendance_extend.sign_in_task_form_view
msgid "Cancel"
msgstr "Cancel"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,code:0
msgid "Code"
msgstr "Code"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,emp_comment:0 field:sign.in.task,emp_comment:0
msgid "Comment"
msgstr "Comment"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,company_id:0
msgid "Company"
msgstr "Company"
#. module: itis_hr_attendance_extend
#: field:itis.holiday,create_uid:0 field:planned.hours,create_uid:0
#: field:service.description,create_uid:0 field:sign.in.task,create_uid:0
msgid "Created by"
msgstr "Created by"
#. module: itis_hr_attendance_extend
#: field:itis.holiday,create_date:0 field:planned.hours,create_date:0
#: field:service.description,create_date:0 field:sign.in.task,create_date:0
msgid "Created on"
msgstr "Created on"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,date:0 field:itis.holiday,date:0
#: field:planned.hours,sheet_date:0
msgid "Date"
msgstr "Date"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:51
#, python-format
msgid "Date should be between timesheet date."
msgstr "Date should be between timesheet date."
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,name:0
msgid "Description"
msgstr "Description"
#. module: itis_hr_attendance_extend
#: field:calendar.event,display_name:0
#: field:hr.analytic.timesheet,display_name:0
#: field:hr.attendance,display_name:0 field:itis.holiday,display_name:0
#: field:planned.hours,display_name:0 field:service.description,display_name:0
#: field:sign.in.task,display_name:0
msgid "Display Name"
msgstr "Display Name"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_employee
msgid "Employee"
msgstr "Employee"
#. module: itis_hr_attendance_extend
#: model:ir.actions.act_window,name:itis_hr_attendance_extend.emp_service_description_action
msgid "Employee Service Description"
msgstr "Employee Service Description"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_calendar_event
msgid "Event"
msgstr "Event"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,general_account_id:0
msgid "General Account"
msgstr "General Account"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "Geplante Stunden"
msgstr "Planned Hour"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Group by month of date"
msgstr "Group by month of date"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Group by week of date"
msgstr "Group by week of date"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Group by year of date"
msgstr "Group by year of date"
#. module: itis_hr_attendance_extend
#: model:hr.holidays.status,name:itis_hr_attendance_extend.itis_holiday_leave_type_new
#: view:itis.holiday:itis_hr_attendance_extend.view_calendar_itis_holiday
msgid "Holiday"
msgstr "Holiday"
#. module: itis_hr_attendance_extend
#: field:hr.holidays,holiday_name:0 field:itis.holiday,name:0
msgid "Holiday Name"
msgstr "Holiday Name"
#. module: itis_hr_attendance_extend
#: model:ir.actions.act_window,name:itis_hr_attendance_extend.act_itis_holiday
#: model:ir.ui.menu,name:itis_hr_attendance_extend.menu_itis_holiday
msgid "Holidays"
msgstr "Holidays"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
#: field:planned.hours,duration:0
msgid "Hours"
msgstr "Hours"
#. module: itis_hr_attendance_extend
#: field:itis.holiday,id:0 field:planned.hours,id:0
#: field:service.description,id:0 field:sign.in.task,id:0
msgid "ID"
msgstr "ID"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,invoice_id:0
msgid "Invoice"
msgstr "Invoice"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,to_invoice:0
msgid "Invoiceable"
msgstr "Invoiceable"
#. module: itis_hr_attendance_extend
#: help:hr.analytic.timesheet,to_invoice:0
msgid ""
"It allows to set the discount while making invoice, keep empty if the "
"activities should not be invoiced."
msgstr ""
"It allows to set the discount while making invoice, keep empty if the "
"activities should not be invoiced."
#. module: itis_hr_attendance_extend
#: field:calendar.event,__last_update:0
#: field:hr.analytic.timesheet,__last_update:0
#: field:hr.attendance,__last_update:0 field:itis.holiday,__last_update:0
#: field:planned.hours,__last_update:0
#: field:service.description,__last_update:0
#: field:sign.in.task,__last_update:0
msgid "Last Modified on"
msgstr "Last Modified on"
#. module: itis_hr_attendance_extend
#: field:itis.holiday,write_uid:0 field:planned.hours,write_uid:0
#: field:service.description,write_uid:0 field:sign.in.task,write_uid:0
msgid "Last Updated by"
msgstr "Last Updated by"
#. module: itis_hr_attendance_extend
#: field:itis.holiday,write_date:0 field:planned.hours,write_date:0
#: field:service.description,write_date:0 field:sign.in.task,write_date:0
msgid "Last Updated on"
msgstr "Last Updated on"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_holidays
msgid "Leave"
msgstr "Leave"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_holiday.py:86
#, python-format
msgid "Leave Request"
msgstr "Leave Request"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Month"
msgstr "Month"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,move_id:0
msgid "Move Line"
msgstr "Move Line"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_payroll.py:57
#, python-format
msgid "Normal Working Days paid at 100%"
msgstr "Normal Working Days paid at 100%"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:325
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:101
#: field:hr_timesheet_sheet.sheet,overtime_hours:0
#, python-format
msgid "Overtime Hours"
msgstr "Overtime Hours"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_payslip
msgid "Pay Slip"
msgstr "Pay Slip"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:319
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:323
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:88
#: field:hr_timesheet_sheet.sheet,planned_ids:0
#: field:hr_timesheet_sheet.sheet,total_planned_hours:0
#, python-format
msgid "Planned Hours"
msgstr "Planned Hours"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/wizard/sign_in_task.py:55
#, python-format
msgid "Please define cost unit for this employee."
msgstr "Please define cost unit for this employee."
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,product_id:0
msgid "Product"
msgstr "Product"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,unit_amount:0
msgid "Quantity"
msgstr "Quantity"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,ref:0
msgid "Ref."
msgstr "Ref."
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Refresh"
msgstr "Refresh"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Refuse"
msgstr "Refuse"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/static/src/js/hr_extend.js:117
#, python-format
msgid "Select Service Description"
msgstr "Select Service Description"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,service_desc_id:0
#: field:sign.in.task,service_desc_id:0
msgid "Service Desc"
msgstr "Service Desc"
#. module: itis_hr_attendance_extend
#: model:ir.ui.menu,name:itis_hr_attendance_extend.menu_emp_service_description
#: view:service.description:itis_hr_attendance_extend.itis_service_description_form
#: view:service.description:itis_hr_attendance_extend.itis_service_description_tree
#: field:service.description,name:0
msgid "Service Description"
msgstr "Service Description"
#. module: itis_hr_attendance_extend
#: field:planned.hours,sheet_id:0
msgid "Sheet"
msgstr "Sheet"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Sign In"
msgstr "Sign In"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Sign Out"
msgstr "Sign Out"
#. module: itis_hr_attendance_extend
#: help:hr.analytic.timesheet,unit_amount:0
msgid "Specifies the amount of quantity to count."
msgstr "Specifies the amount of quantity to count."
#. module: itis_hr_attendance_extend
#: field:hr.holidays,state_value:0
msgid "State value"
msgstr "State value"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "Summe Stunden"
msgstr "Total Hour"
#. module: itis_hr_attendance_extend
#: help:hr.analytic.timesheet,amount_currency:0
msgid ""
"The amount expressed in the related account currency if not equal to the "
"company one."
msgstr ""
"The amount expressed in the related account currency if not equal to the "
"company one."
#. module: itis_hr_attendance_extend
#: help:hr.analytic.timesheet,currency_id:0
msgid "The related account currency if not equal to the company one."
msgstr "The related account currency if not equal to the company one."
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_holiday.py:34
#, python-format
msgid "The start date must be anterior to the end date."
msgstr "The start date must be anterior to the end date."
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:318
#: field:hr_timesheet_sheet.sheet,time_diff:0
#, python-format
msgid "Time Diffrence"
msgstr "Time Diffrence"
#. module: itis_hr_attendance_extend
#: field:hr_timesheet_sheet.sheet,timesheet_ids2:0
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_timesheet_sheet_sheet
msgid "Timesheet"
msgstr "Timesheet"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Timesheet Activities"
msgstr "Timesheet Activities"
#. module: itis_hr_attendance_extend
#: model:ir.model,name:itis_hr_attendance_extend.model_hr_analytic_timesheet
msgid "Timesheet Line"
msgstr "Timesheet Line"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Timesheet Summary"
msgstr "Timesheet Summary"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
msgid "Timesheet abschließen"
msgstr "Timesheet abschließen"
#. module: itis_hr_attendance_extend
#. openerp-web
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:31
#: code:addons/itis_hr_attendance_extend/static/src/xml/templates.xml:65
#, python-format
msgid "Total"
msgstr "Total"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:324
#: field:hr_timesheet_sheet.sheet,total_timesheet_hours:0
#, python-format
msgid "Total Hours"
msgstr "Total Hours"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_timesheet_sheet.py:317
#: field:hr_timesheet_sheet.sheet,total_contract_time:0
#, python-format
msgid "Total Planned Hours"
msgstr "Total Planned Hours"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "Total time"
msgstr "Total time"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,product_uom_id:0
msgid "Unit of Measure"
msgstr "Unit of Measure"
#. module: itis_hr_attendance_extend
#: field:hr.analytic.timesheet,user_id:0
msgid "User"
msgstr "User"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/wizard/sign_in_task.py:55
#, python-format
msgid "User Error!"
msgstr "User Error!"
#. module: itis_hr_attendance_extend
#: code:addons/itis_hr_attendance_extend/models/hr_holiday.py:34
#, python-format
msgid "Warning!"
msgstr "Warning!"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Week"
msgstr "Week"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.view_hr_timesheet_sheet_filter_inherit
msgid "Year"
msgstr "Year"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_sheet_form_inherited
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "false"
msgstr "false"
#. module: itis_hr_attendance_extend
#: view:sign.in.task:itis_hr_attendance_extend.sign_in_task_form_view
msgid "or"
msgstr "or"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "total_contract_time"
msgstr "total_contract_time"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "total_overtime_time"
msgstr "total_overtime_time"
#. module: itis_hr_attendance_extend
#: view:hr_timesheet_sheet.sheet:itis_hr_attendance_extend.hr_timesheet_sheet_tree_simplified_inherit_itis
msgid "Überstunden"
msgstr "Overtime"

View File

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from . import hr_attendance
from . import hr_timesheet_sheet
from . import itis_holiday
from . import hr_payroll
from . import hr_holiday

View File

@ -0,0 +1,200 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
from datetime import datetime
from dateutil.relativedelta import relativedelta
import csv
import os
import logging
logger = logging.getLogger(__name__)
class AnalyticAccount(models.Model):
_inherit = "account.analytic.account"
account_code = fields.Char("Account Code")
class HRAttendance(models.Model):
_inherit = "hr.attendance"
timesheet_id = fields.Many2one("hr.analytic.timesheet", "Anlytic Timesheet")
@api.model
def create(self, values):
t_id = self.env.context.get('timesheet_id', False)
if t_id:
values.update({
'timesheet_id': t_id,
})
res = super(HRAttendance, self).create(values)
if 'action' in values and values['action'] == 'sign_out':
timesheet_obj = self.env['hr.analytic.timesheet']
sign_in = self.search([('employee_id', '=', values['employee_id']), ('name', '<', res.name), ('action', '=', ('sign_in'))], limit=1, order='name DESC')
if sign_in and sign_in.timesheet_id:
timesheet_obj.browse(sign_in.timesheet_id.id).unit_amount = res.worked_hours
return res
class HRAnalyticTimesheet(models.Model):
_inherit = "hr.analytic.timesheet"
service_desc_id = fields.Many2one('service.description',string="Service Desc")
emp_comment = fields.Char("Comment")
dept_account_id = fields.Many2one('account.analytic.account',string="Dept. Analytic Account")
analytic_account_code = fields.Char(related='account_id.account_code',string="Analytic Account")
dept_account_code = fields.Char(related='dept_account_id.account_code',string='Dept. Analytic Account')
identification_id = fields.Char(string="Personal-Nr", compute="get_employee_data")
@api.model
def open_analytic_timesheet_tree(self):
"""This function is called from IR.ACTION.SERVER, use to open the analytic timesheet tree view wih required filter"""
filter_user_ids = []
hr_employee_recs = self.env['hr.employee'].search([('user_id','!=',False),('parent_id','!=',False)])
if hr_employee_recs: # to check the condition, current user employee is manager of the record present in the hr.analytic.timesheet
for hr_employee_rec in hr_employee_recs:
if hr_employee_rec.parent_id.user_id and hr_employee_rec.parent_id.user_id.id == self._uid:
filter_user_ids.append(hr_employee_rec.user_id.id)
domain = "[('user_id', 'in', " + str(filter_user_ids) + ")]"
tree_view_id = self.env.ref('itis_hr_attendance_extend.view_timehseet_activity_overview_tree_manager').id
value = {
'domain': domain,
'name': 'Timesheet',
'view_type': 'form',
'view_mode': 'tree',
'res_model': 'hr.analytic.timesheet',
'view_id': tree_view_id,
'type': 'ir.actions.act_window'
}
return value
@api.one
def get_employee_data(self):
"""Computed function to get the required data from the hr.employee"""
hr_employee_rec = self.env['hr.employee'].search([('user_id','=',self.user_id.id)],limit=1)
if hr_employee_rec:
self.identification_id = hr_employee_rec.identification_id
@api.model
def set_cost_center_existing_rec(self):
"""Call from Scheduler, Use to update dept_account_is for old records"""
# print"---In set_cost_center_existing_rec-----"
analytic_timesheet_records = self.search([('dept_account_id','=',False),('sheet_id','!=',False)])
for analytic_timesheet_brw in analytic_timesheet_records:
employee_id = analytic_timesheet_brw.sheet_id.employee_id
if employee_id.bereich and employee_id.bereich.account_id:dept_account_id=employee_id.bereich.account_id.id
elif employee_id.department_id and employee_id.department_id.account_id:dept_account_id=employee_id.department_id.account_id.id
else:dept_account_id = False
if dept_account_id:
self._cr.execute('update hr_analytic_timesheet set dept_account_id=%s where id =%s',(dept_account_id,analytic_timesheet_brw.id))
@api.model
# @api.multi
def get_monthly_timesheet_overview(self):
"""Call from Scheduler, Use to generate monthly timesheet overview report and send it via email"""
logger.info("---In the get_monthly_timesheet_overview cron--")
timesheet_overview_export = self.env['timesheet.overview.export']
today_date = datetime.today().date()
last_month_date = today_date - relativedelta(months= 1)
# print"today_date----last_month_date--",today_date,last_month_date
analytic_timesheet_records = self.search([('date','<',today_date),('date','>=',last_month_date)],order='account_id')
if analytic_timesheet_records:
logger.info("---Records to get %s" %analytic_timesheet_records)
# call the subfunction to generate the .csv report
context = timesheet_overview_export.export_csv_subfunction(analytic_timesheet_records,False)
if context:
# create attachement record of the related csv file
ir_attachment = self.env['ir.attachment']
file_name ='timesheet_overview_'+str(last_month_date)+'_'+str(today_date)+'.csv'
attachment_data = {
'name': file_name,
'datas_fname':file_name,
'datas':context.get('default_name'),
'res_model': 'email.template',
}
ir_attachment_brw = ir_attachment.create(attachment_data)
#template = self.env.ref('itis_hr_attendance_extend.email_template_monthly_timesheet_overview', False)
template = False #Added by IT IS to disable email sending.
if ir_attachment_brw and template:
logger.info("---Template found and send a mail")
template.write({'attachment_ids': [(6, 0, [ir_attachment_brw.id])]}) # link a attachment to email template
template.send_mail(analytic_timesheet_records[0].id)# send a mail with attachment
template.write({'attachment_ids': [(3, ir_attachment_brw.id)]})# to unlink the attachment from template after sending a email
@api.model
def create(self, values):
if values.get('sheet_id'):
dept_account_id = False
timesheet_brw = self.env['hr_timesheet_sheet.sheet'].browse(values['sheet_id'])
if timesheet_brw and timesheet_brw.employee_id:
employee_id = timesheet_brw.employee_id
if employee_id.bereich and employee_id.bereich.account_id:dept_account_id=employee_id.bereich.account_id.id
elif employee_id.department_id and employee_id.department_id.account_id:dept_account_id=employee_id.department_id.account_id.id
if dept_account_id:
values.update({'dept_account_id':dept_account_id})
if not values.get('name'):
values.update({'name':'/'})
return super(HRAnalyticTimesheet, self).create(values)
@api.one
def update_hours(self, last_sign_in):
return True
lst_dt = datetime.strptime(last_sign_in, DEFAULT_SERVER_DATETIME_FORMAT)
nw_dt = datetime.today()
scn = (nw_dt - lst_dt).total_seconds()
for tm in self:
unit_amount = scn/360
tm.write({'unit_amount': unit_amount})
return True
class hr_employee(models.Model):
_inherit = 'hr.employee'
@api.model
def create(self, values):
res = super(hr_employee, self).create(values)
# to create holiday for the related employee
today_date = datetime.today()
itis_holiday = self.env['itis.holiday'].search([('date','>',today_date)])
if itis_holiday:
hr_holidays_status_brw = self.env['hr.holidays.status'].search([('is_holiday','=',True)],limit=1)
if hr_holidays_status_brw:
for hr_employee_brw in res:
for itis_holiday_brw in itis_holiday:
holiday_created = self.env['hr.holidays'].create({'employee_id':hr_employee_brw.id, 'date_from':itis_holiday_brw.date,'date_to':itis_holiday_brw.date,'holiday_name':itis_holiday_brw.name,'holiday_status_id':hr_holidays_status_brw.id})
self._cr.execute("update hr_holidays set state = 'validate' where id = %s",(holiday_created.id,))
return res

View File

@ -0,0 +1,177 @@
from openerp import models, api, fields, _
from openerp.osv import osv
from datetime import datetime
class HRHoliday(models.Model):
_inherit = "hr.holidays"
holiday_name = fields.Char(string ='Holiday Name')
state_value = fields.Char(compute='_compute_state_value')
@api.one
def _compute_state_value(self):
self.state_value = dict(self.fields_get(allfields=['state'])['state']['selection'])[self.state]
return
def create(self, cr, uid, values, context=None):
"""
To create holiday list entry calender of leave request
"""
# following condition is use to give a warning and to calculate no of day leave
if values.get('date_from') and values.get('date_to'):
date_from,date_to= values['date_from'],values['date_to']
# print"Date from----Date to------",len(date_from),len(date_to)
# print"Date from----Date to------",date_from,date_to
if len(date_from) == 10:
date_from = date_from+' 09:00:00'
values.update({'date_from':date_from})
if len(date_to) == 10:
date_to = date_to+' 18:00:00'
values.update({'date_to':date_to})
elif len(date_to) == 19:
date_to = date_to[0:11] + '18:00:00'
values.update({'date_to':date_to})
# print"Values-----",values
if date_from > date_to:
raise osv.except_osv(_('Warning!'),_('The start date must be anterior to the end date.'))
# start_date = date_from
# # stop_date = date_to
# office_leave_time = self.pool.get('leave.time')
# office_leave_time_record = office_leave_time.search(cr,uid,[('active','=',True)],limit=1)
# if office_leave_time_record:
# office_leave_time_brw = office_leave_time.browse(cr,uid,office_leave_time_record[0])
# if values.get('leave_selection') == 'full_day':
# start_time = str(office_leave_time_brw.fullday_start_time)+':00:00'
# start_date = datetime.strptime(date_from, "%Y-%m-%d %H:%M:%S").strftime('%Y-%m-%d ')+start_time
# # end_time = str(office_leave_time_brw.fullday_end_time)+':00:00'
# #stop_date = datetime.strptime(date_to, "%Y-%m-%d %H:%M:%S").strftime('%Y-%m-%d ')+end_time
# elif values.get('leave_selection') == 'half_day':
# if values.get('half_day_type') == 'morning':
# start_time = str(office_leave_time_brw.halfday_morning_start_time)+':00:00'
# start_date = datetime.strptime(date_from, "%Y-%m-%d %H:%M:%S").strftime('%Y-%m-%d ')+start_time
# # end_time = str(office_leave_time_brw.halfday_morning_end_time)+':00:00'
# # stop_date = datetime.strptime(date_to, "%Y-%m-%d %H:%M:%S").strftime('%Y-%m-%d ')+end_time
#
# else:
# start_time = str(office_leave_time_brw.halfday_afternoon_start_time)+':00:00'
# start_date = datetime.strptime(date_from, "%Y-%m-%d %H:%M:%S").strftime('%Y-%m-%d ')+start_time
# # end_time = str(office_leave_time_brw.halfday_afternoon_end_time)+':00:00'
# # stop_date = datetime.strptime(date_to, "%Y-%m-%d %H:%M:%S").strftime('%Y-%m-%d ')+end_time
#
# values.update({'date_from':start_date})
# print"START date----end date-----",start_date,stop_date
# if values.get('leave_selection') and values.get('leave_selection') == 'half_day':
# if date_from == date_to:
# values.update({'number_of_days_temp':0.5})
# else:
# print"DATE---From-----",date_from
# print"DATE---T-----",date_to
# date_from = datetime.datetime.strptime(date_from,'%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d')+' 00:00:00'
# date_to = datetime.datetime.strptime(date_to,'%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d')+' 00:00:00'
# diff_day = self._get_number_of_days(date_from, date_to)
# diff_day = round(math.floor(diff_day))
# values.update({'number_of_days_temp':diff_day})
res = super(HRHoliday, self).create(cr, uid, values, context)
for hr_holidays_brw in self.browse(cr,uid,res):
if hr_holidays_brw.state == 'confirm' and hr_holidays_brw.holiday_type == 'employee' and hr_holidays_brw.type == 'remove':
notes = ''
if notes:
notes = hr_holidays_brw.notes
meeting_obj = self.pool.get('calendar.event')
if hr_holidays_brw.holiday_name:
name = hr_holidays_brw.holiday_name
else:
name = (hr_holidays_brw.name or _('Leave Request')) +' -To Approve'
start_date = hr_holidays_brw.date_from
stop_date = hr_holidays_brw.date_to
meeting_vals = {
'name': name,
'categ_ids': hr_holidays_brw.holiday_status_id.categ_id and [(6,0,[hr_holidays_brw.holiday_status_id.categ_id.id])] or [],
'duration': hr_holidays_brw.number_of_days_temp * 8,
'description': notes,
'user_id': hr_holidays_brw.user_id.id,
'start':start_date,
'stop': stop_date,
'allday': False,
'state': 'open', # to block that meeting date in the calendar
'class': 'confidential',
# 'leave_status':'To Be Approve'
}
#Add the partner_id (if exist) as an attendee
if hr_holidays_brw.user_id and hr_holidays_brw.user_id.partner_id:
meeting_vals['partner_ids'] = [(4,hr_holidays_brw.user_id.partner_id.id)]
ctx_no_email = dict(context or {}, no_email=True)
meeting_id = meeting_obj.create(cr, uid, meeting_vals, context=ctx_no_email)
self.write(cr, uid, hr_holidays_brw.id, {'meeting_id': meeting_id})
return res
# def holidays_validate(self, cr, uid, ids, context=None):
# obj_emp = self.pool.get('hr.employee')
# ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)])
# manager = ids2 and ids2[0] or False
# self.write(cr, uid, ids, {'state':'validate'})
# data_holiday = self.browse(cr, uid, ids)
# for record in data_holiday:
# if record.double_validation:
# self.write(cr, uid, [record.id], {'manager_id2': manager})
# else:
# self.write(cr, uid, [record.id], {'manager_id': manager})
# if record.holiday_type == 'employee' and record.type == 'remove':
# meeting_obj = self.pool.get('calendar.event')
#
# # to check for the existing calender events for this type
# if record.meeting_id:
# self._create_resource_leave(cr, uid, [record], context=context)
# meeting_obj.write(cr, uid, record.meeting_id, {'name': record.name or _('Leave Request'),})
# else:
# meeting_vals = {
# 'name': record.name or _('Leave Request'),
# 'categ_ids': record.holiday_status_id.categ_id and [(6,0,[record.holiday_status_id.categ_id.id])] or [],
# 'duration': record.number_of_days_temp * 8,
# 'description': record.notes,
# 'user_id': record.user_id.id,
# 'start': record.date_from,
# 'stop': record.date_to,
# 'allday': False,
# 'state': 'open', # to block that meeting date in the calendar
# 'class': 'confidential'
# }
# #Add the partner_id (if exist) as an attendee
# if record.user_id and record.user_id.partner_id:
# meeting_vals['partner_ids'] = [(4,record.user_id.partner_id.id)]
#
# ctx_no_email = dict(context or {}, no_email=True)
# meeting_id = meeting_obj.create(cr, uid, meeting_vals, context=ctx_no_email)
# self._create_resource_leave(cr, uid, [record], context=context)
# self.write(cr, uid, ids, {'meeting_id': meeting_id})
# elif record.holiday_type == 'category':
# emp_ids = obj_emp.search(cr, uid, [('category_ids', 'child_of', [record.category_id.id])])
# leave_ids = []
# batch_context = dict(context, mail_notify_force_send=False)
# for emp in obj_emp.browse(cr, uid, emp_ids, context=context):
# vals = {
# 'name': record.name,
# 'type': record.type,
# 'holiday_type': 'employee',
# 'holiday_status_id': record.holiday_status_id.id,
# 'date_from': record.date_from,
# 'date_to': record.date_to,
# 'notes': record.notes,
# 'number_of_days_temp': record.number_of_days_temp,
# 'parent_id': record.id,
# 'employee_id': emp.id
# }
# leave_ids.append(self.create(cr, uid, vals, context=batch_context))
# for leave_id in leave_ids:
# # TODO is it necessary to interleave the calls?
# for sig in ('confirm', 'validate', 'second_validate'):
# self.signal_workflow(cr, uid, [leave_id], sig)
# return True

View File

@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
from datetime import datetime, timedelta
class HRPayslip(models.Model):
_inherit = 'hr.payslip'
def get_worked_day_lines(self, cr, uid, contract_ids, date_from, date_to, context=None):
"""
@param contract_ids: list of contract id
@return: returns a list of dict containing the input that should be applied for the given contract between date_from and date_to
"""
def was_on_leave(employee_id, datetime_day, context=None):
res = False
day = datetime_day.strftime("%Y-%m-%d")
holiday_ids = self.pool.get('hr.holidays').search(cr, uid, [('state','=','validate'),('employee_id','=',employee_id),('type','=','remove'),('date_from','<=',day),('date_to','>=',day)])
if holiday_ids:
res = self.pool.get('hr.holidays').browse(cr, uid, holiday_ids, context=context)[0].holiday_status_id.name
return res
res = []
for contract in self.pool.get('hr.contract').browse(cr, uid, contract_ids, context=context):
if not contract.working_hours:
#fill only if the contract as a working schedule linked
continue
attendances = {
'name': _("Normal Working Days paid at 100%"),
'sequence': 1,
'code': 'WORK100',
'number_of_days': 0.0,
'number_of_hours': 0.0,
'contract_id': contract.id,
}
leaves = {}
day_from = datetime.strptime(date_from,"%Y-%m-%d")
day_to = datetime.strptime(date_to,"%Y-%m-%d")
contract_day_start = datetime.strptime(contract.date_start,"%Y-%m-%d")
if day_from < contract_day_start:
day_from = contract_day_start
if contract.date_end:
contract_day_end = datetime.strptime(contract.date_end,"%Y-%m-%d")
if day_to > contract_day_end:
day_to = contract_day_end
nb_of_days = (day_to - day_from).days + 1
for day in range(0, nb_of_days):
working_hours_on_day = self.pool.get('resource.calendar').working_hours_on_day(cr, uid, contract.working_hours, day_from + timedelta(days=day), context)
is_holiday = self.is_holiday(cr,uid,day_from + timedelta(days=day), context)
if is_holiday:
continue
if working_hours_on_day:
#the employee had to work
leave_type = was_on_leave(contract.employee_id.id, day_from + timedelta(days=day), context=context)
if leave_type:
#if he was on leave, fill the leaves dict
if leave_type in leaves:
leaves[leave_type]['number_of_days'] += 1.0
leaves[leave_type]['number_of_hours'] += working_hours_on_day
else:
leaves[leave_type] = {
'name': leave_type,
'sequence': 5,
'code': leave_type,
'number_of_days': 1.0,
'number_of_hours': working_hours_on_day,
'contract_id': contract.id,
}
else:
#add the input vals to tmp (increment if existing)
attendances['number_of_days'] += 1.0
attendances['number_of_hours'] += working_hours_on_day
leaves = [value for key,value in leaves.items()]
res += [attendances] + leaves
return res
def is_holiday(self,cr,uid,day,context):
search_id = self.pool.get('itis.holiday').search(cr,uid,[('date','=',day)])
if search_id:
return True
else:
return False

View File

@ -0,0 +1,466 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
from openerp.osv import osv
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from openerp import SUPERUSER_ID
from openerp.exceptions import Warning
from openerp.http import request
import logging
logger = logging.getLogger(__name__)
class HRTimesheetSheet(models.Model):
_inherit = "hr_timesheet_sheet.sheet"
@api.model
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
"""To display the functional field value in the group by"""
res = super(HRTimesheetSheet, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
if 'total_timesheet' in fields:
for line in res:
if '__domain' in line:
lines = self.search(line['__domain'])
inv_value = 0.0
for line2 in lines:
inv_value += line2.total_timesheet
line['total_timesheet'] = inv_value
if 'total_contract_time' in fields:
for line in res:
if '__domain' in line:
lines = self.search(line['__domain'])
inv_value = 0.0
for line2 in lines:
inv_value += line2.total_contract_time
line['total_contract_time'] = inv_value
if 'time_diff' in fields:
for line in res:
if '__domain' in line:
lines = self.search(line['__domain'])
inv_value = 0.0
for line2 in lines:
inv_value += line2.time_diff
line['time_diff'] = inv_value
return res
@api.multi
def write(self, vals):
res = super(HRTimesheetSheet, self).write(vals)
if 'timesheet_ids2' in vals:
for timesheet_value in vals['timesheet_ids2']:
if timesheet_value[2]:
date = timesheet_value[2].get('date')
if not date or (date>=self.date_from and date<=self.date_to):
pass
else:
raise Warning(_("Date should be between timesheet date."))
return res
def name_get(self, cr, uid, ids, context=None):
if not ids:
return []
if isinstance(ids, (long, int)):
ids = [ids]
return [(r['id'], datetime.strptime(r['date_from'], '%Y-%m-%d').strftime('%d-%m-%Y')) \
for r in self.read(cr, uid, ids, ['date_from'],
context=context, load='_classic_write')]
@api.multi
def get_analytic_timesheet_data(self):
"""
This function is call from the Javascript
"""
data_dict = {}
data_list_new =[]
if self and self.timesheet_ids:
for timesheet_record in self.timesheet_ids:
data_list =[]
data_list_new.append(timesheet_record)
data_list.append(timesheet_record.service_desc_id and timesheet_record.service_desc_id.name or False)
data_list.append(timesheet_record.emp_comment)
data_dict[timesheet_record.account_id.id] =data_list
return data_dict
@api.model
def create_daily_timesheet(self):
"""
Scheduler, use to create daily timesheet for the all employee
"""
# print"In daily timesheet create scheduler---"
today_date = datetime.now()
for employee_brw in self.env['hr.employee'].search([('user_id','!=',False)]):
emp_contract_record =self.env['hr.contract'].search([("employee_id", '=', employee_brw.id),("date_start", '<=', today_date),'|',("date_end", '>=', today_date),("date_end", '=', False)])
if emp_contract_record:
timesheets = self.search([("employee_id", '=', employee_brw.id),("date_from", '<=', today_date),("date_to", '>=', today_date)])
if not timesheets:
values = {'employee_id':employee_brw.id,
'date_from':today_date,
'date_to':today_date
}
try:
self.create(values)
except:
#Todo Error handling
pass
@api.model
def create_missingdate_timesheet(self):
"""
Scheduler, use to create missing date timesheet for the all employee
DATE NEED TO PROVIDED HERE.
"""
print"In create_missingdate_timesheet---"
# today_date = datetime.now()
provided_dates = [datetime.strptime("2017-09-09 00:00:00",'%Y-%m-%d %H:%M:%S'),datetime.strptime("2017-09-10 00:00:00",'%Y-%m-%d %H:%M:%S')]
for date in provided_dates:
for employee_brw in self.env['hr.employee'].search([('user_id','!=',False)]):
emp_contract_record =self.env['hr.contract'].search([("employee_id", '=', employee_brw.id),("date_start", '<=', date),'|',("date_end", '>=', date),("date_end", '=', False)])
if emp_contract_record:
timesheets = self.search([("employee_id", '=', employee_brw.id),("date_from", '<=', date),("date_to", '>=', date)])
if not timesheets:
values = {'employee_id':employee_brw.id,
'date_from':date,
'date_to':date
}
try:
print"timesheet create----",employee_brw
self.create(values)
except:
#Todo Error handling
pass
def check_employee_attendance_state(self, cr, uid, sheet_id, context=None):
ids_signin = self.pool.get('hr.attendance').search(cr,uid,[('sheet_id', '=', sheet_id),('action','=','sign_in')])
ids_signout = self.pool.get('hr.attendance').search(cr,uid,[('sheet_id', '=', sheet_id),('action','=','sign_out')])
if len(ids_signin) != len(ids_signout):
logger.info("--Sign in, Sign out not equal timesheet ids--%s" %sheet_id)
# raise osv.except_osv(('Warning!'),_('The timesheet cannot be validated as it does not contain an equal number of sign ins and sign outs.'))
return True
@api.model
def automatic_sign_out(self):
"""
Scheduler, Use to sign out the employee which are not sign out
"""
logger.info("--In automatic_sign_out scheduler--")
today_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
cron_record = self.env['ir.cron'].search([('function','=','automatic_sign_out')],limit=1)
if cron_record:
cron_date = datetime.strptime(cron_record.nextcall,'%Y-%m-%d %H:%M:%S').date()
else:
cron_date = datetime.now().date()
logger.info("--Date of the scheduler--%s"%(cron_date))
hr_attendance = self.env['hr.attendance']
for employee_brw in self.env['hr.employee'].search([('user_id','!=',False)]):
# timesheets = self.search([("employee_id", '=', employee_brw.id),("date_from", '<=', today_date),("date_to", '>=', today_date)],limit=1)
timesheets = self.search([("employee_id", '=', employee_brw.id),("date_from", '=', cron_date)],limit=1)
today_hr_attendance_ids = []
if timesheets:
today_hr_attendance_ids = [x.id for x in timesheets.attendances_ids]
# today_date = datetime.now().date().strftime('%Y-%m-%d')
# hr_attendance_records = hr_attendance.search([("employee_id", '=', employee_brw.id),('sheet_id','=',timesheets[0].id)])
# for hr_attendance_record in hr_attendance_records:
# date_new = datetime.strptime(hr_attendance_record.name,'%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d')
# if date_new == today_date:
# today_hr_attendance_ids.append(hr_attendance_record.id)
if today_hr_attendance_ids:
today_hr_attendance_ids.sort(reverse=True)
if hr_attendance.browse(today_hr_attendance_ids[0]).action=='sign_in':
logger.info("--Automatically sign out employee %s" %employee_brw)
hr_attendance.create({'employee_id':employee_brw.id,'sheet_id':timesheets[0].id,'action':'sign_out','name':today_date})
self.send_sign_out_email(employee_brw)
def send_sign_out_email(self,employee_brw):
"""
This function is use to send a email to the user for automatic sign out
"""
if employee_brw and employee_brw.user_id:
email_to = False
if employee_brw.work_email:
email_to = employee_brw.work_email
elif employee_brw.user_id.partner_id and employee_brw.user_id.partner_id.email:
email_to = employee_brw.user_id.partner_id.email
if email_to:
ir_mail_env = self.env['ir.mail_server']
active_outgoing_mail_server = ir_mail_env.search([('id','!=',False)], limit=1)
email_vals = { }
body_html= """
<p>
Hallo """+str(employee_brw.name) +""",
</p>
<p>
Sie wurden automatisch von TicTac abgemeldet. Bitte passen Sie ihr Timesheet an.
</p>
<p>
Vielen Dank ihr HR Team.
</p>
"""
email_vals['email_from'] = employee_brw.company_id and employee_brw.company_id.email or 'info@yourcompany.example.com'
email_vals['email_to'] = email_to
email_vals['subject'] = 'Automatic Sign Out'
email_vals['body_html'] = body_html
# if active_outgoing_mail_server:
# email_vals['mail_server_id'] = active_outgoing_mail_server.id
mail = self.env['mail.mail'].create(email_vals)
mail.send()
logger.info("--Sign out email send.")
@api.multi
def action_set_to_draft(self):
res = super(HRTimesheetSheet, self).action_set_to_draft()
#newovertime
overtime_count = self.employee_id.employee_overtime_id.emp_overtime_count - self.time_diff
self.employee_id.employee_overtime_id.write({'emp_overtime_count': overtime_count})
# overtime_count = self.employee_id.overtime_count - self.time_diff
# self.employee_id.write({'overtime_count': overtime_count})
return res
@api.one
def action_cancel(self):
#newovertime
overtime_count = self.employee_id.employee_overtime_id.emp_overtime_count - self.time_diff
self.employee_id.employee_overtime_id.write({'emp_overtime_count': overtime_count})
# overtime_count = self.employee_id.overtime_count - self.time_diff
# self.employee_id.write({'overtime_count': overtime_count})
self.write({'state': 'draft'})
return True
@api.multi
def button_confirm(self):
res = super(HRTimesheetSheet, self).button_confirm()
#newovertime
new_overtime = self.employee_id.employee_overtime_id.emp_overtime_count + self.time_diff
self.employee_id.employee_overtime_id.write({'emp_overtime_count': new_overtime})
# new_overtime = self.employee_id.overtime_count + self.time_diff
# self.pool.get('hr.employee').write(self._cr,SUPERUSER_ID,self.employee_id.id,{'overtime_count': new_overtime})
#self.employee_id.write({'overtime_count': new_overtime})
self.write({'state': 'confirm'})
return res
@api.model
def create(self, values):
#cr, uid, context = self.env.cr, self.env.uid, self.env.context
res_users_obj = self.env["res.users"]
ir_model_obj = self.env["ir.model.data"]
res_user_data = res_users_obj.browse([self.env.uid])
xml_list = []
group_ids = []
for group in res_user_data.groups_id:
group_ids.append(group.id)
model_data = ir_model_obj.search([['model','=','res.groups'],['res_id','in',group_ids]])
#model_data = ir_model_obj.browse(cr,uid,model_ids,context)
for value in model_data:
xml_list.append(value.name)
if "group_hr_manager" in xml_list or "group_hr_payroll_manager" in xml_list or "group_hr_user" in xml_list or self.env.uid == 1:
if 'date_from' in values and 'date_to' in values and values['date_from'] != values['date_to']:
raise Warning(_("Start date and end date have to be the same day."))
if 'date_from' in values and 'date_to' in values and 'employee_id' in values and self.search([('employee_id','=',values['employee_id']),('date_from','<=',values['date_from']),('date_to','>=',values['date_from'])]):
raise Warning(_("You can only create one timesheet each day."))
res = super(HRTimesheetSheet, self).create(values)
res.calc_planned_hours()
res.calc_leave_hours()
return res
else:
raise Warning(_("You do not have pemission to create timesheets!"))
@api.one
def cal_tot_cont_time(self):
total_duration = 0.0
for pln_hrs in self.planned_ids:
total_duration += pln_hrs.duration
self.total_contract_time = total_duration
self.time_diff = self.total_timesheet - self.total_contract_time
return True
@api.one
def cal_total_hours(self):
total_duration = 0.0
for pln_hrs in self.planned_ids:
total_duration += pln_hrs.duration
self.total_timesheet_hours = self.total_timesheet
self.total_planned_hours = total_duration
self.overtime_hours = self.total_timesheet_hours - self.total_planned_hours
@api.multi
def fetch_holiday_list(self):
res = []
for hld in self.env["itis.holiday"].search([]):
res.append(hld.date)
return res
@api.model
def close_timesheet(self):
for timesheet in self.search([('date_to','<',datetime.today().date().replace(day=1)),('state','=','draft')]):
timesheet.button_confirm()
return
@api.one
def calc_planned_hours(self):
res = {}
hld_list = self.fetch_holiday_list()
date_from = datetime.strptime(self.date_from, DEFAULT_SERVER_DATE_FORMAT)
date_to = datetime.strptime(self.date_to, DEFAULT_SERVER_DATE_FORMAT)
temp_date = date_from
while temp_date <= date_to:
weekday = temp_date.weekday()
day_hours = 0.0
if datetime.strftime(temp_date, DEFAULT_SERVER_DATE_FORMAT) in hld_list:
res.update({temp_date:day_hours})
temp_date += timedelta(days=1)
continue
# contract_ids = self.pool.get('hr.contract').search(self._cr, SUPERUSER_ID, [('employee_id','=',self.id)])
# contract_ids = self.pool.get('hr.contract').browse(self._cr, SUPERUSER_ID,contract_ids)
# for contract in contract_ids:
for contract in self.employee_id.contract_ids:
cont_start_date = datetime.strptime(contract.date_start, DEFAULT_SERVER_DATE_FORMAT)
cont_end_date = False
if not contract.date_end:
if cont_start_date <= temp_date:
day_hours += self.get_hours(weekday, contract.working_hours.attendance_ids)
else:
cont_end_date = datetime.strptime(contract.date_end, DEFAULT_SERVER_DATE_FORMAT)
if cont_start_date <= temp_date and cont_end_date >= temp_date:
day_hours += self.get_hours(weekday, contract.working_hours.attendance_ids)
res.update({temp_date:day_hours})
temp_date += timedelta(days=1)
plan_hr_obj = self.env['planned.hours']
dts = res.keys()
for plan_hrs in self.planned_ids:
sheet_date = datetime.strptime(plan_hrs.sheet_date, DEFAULT_SERVER_DATE_FORMAT)
if sheet_date not in dts:
sheet_date.unlink()
for dt, hrs in res.iteritems():
dt_exist = False
for plan_hrs in self.planned_ids:
sheet_date = datetime.strptime(plan_hrs.sheet_date, DEFAULT_SERVER_DATE_FORMAT)
if sheet_date == dt:
dt_exist = True
if plan_hrs.duration != hrs:
plan_hrs.write({'duration': hrs})
if not dt_exist:
vals = {
'sheet_date': datetime.strftime(dt, DEFAULT_SERVER_DATE_FORMAT),
'duration': hrs,
'sheet_id': self.id,
}
plan_hr_obj.create(vals)
def get_hours(self, weekday, atten_ids):
res = 0.0
for atten in atten_ids:
if int(atten.dayofweek) == weekday:
res += atten.hour_to - atten.hour_from
return res
@api.depends("timesheet_ids.unit_amount")
@api.one
def calc_actual_ot(self):
if self.state not in ['new', 'draft']:
# self.actual_ot = self.employee_id.overtime_count
# newovertime
self.actual_ot = self.employee_id.employee_overtime_id.emp_overtime_count
return True
act_wk_dict = {}
act_working = 0.0
for timesheet in self.timesheet_ids:
tm = act_wk_dict.get(timesheet.date, 0.0) + timesheet.unit_amount
act_wk_dict.update({timesheet.date: tm})
act_working += timesheet.unit_amount
wk_dts = act_wk_dict.keys()
pln_wk_dict = {}
pl_working = 0.0
for pln_hr in self.planned_ids:
pln_wk_dict.update({pln_hr.sheet_date: pln_hr.duration})
is_cur_sheet = False
cur_date = datetime.today()
date_from = datetime.strptime(self.date_from, DEFAULT_SERVER_DATE_FORMAT)
date_to = datetime.strptime(self.date_to, DEFAULT_SERVER_DATE_FORMAT)
if date_from <= cur_date and date_to >= cur_date:
is_cur_sheet = True
tot_time = 0.0
while date_from <= date_to:
if is_cur_sheet and date_from > cur_date:
date_from += timedelta(days=1)
continue
dt_str = datetime.strftime(date_from, DEFAULT_SERVER_DATE_FORMAT)
tot_time += act_wk_dict.get(dt_str, 0.0) - pln_wk_dict.get(dt_str, 0.0)
date_from += timedelta(days=1)
# print"emp overtime----",self.employee_id.overtime_count
# print"tot_time--------",tot_time
# add a logic to add all the overtime hr for the current month
date_from = datetime.strptime(self.date_from, DEFAULT_SERVER_DATE_FORMAT)
first_date = (date_from + relativedelta(months=-1)).replace(day=1)
monthly_overtime = 0.0
while first_date <= date_from:
timesheet_record = self.search([('date_from','=',first_date),('employee_id','=',self.employee_id.id),('state','in',['new','draft'])],limit=1)
if timesheet_record:
# print"timesheet_record.time_diff----",timesheet_record.time_diff
monthly_overtime += timesheet_record.time_diff
first_date += timedelta(days=1)
# print"monthly_overtime-----",monthly_overtime
# self.actual_ot = self.employee_id.overtime_count + monthly_overtime
# newovertime
self.actual_ot = self.employee_id.employee_overtime_id.emp_overtime_count + monthly_overtime
return True
total_contract_time = fields.Float(_("Total Planned Hours"), compute="cal_tot_cont_time", multi="cal_tot_cont_time")
time_diff = fields.Float(_("Time Diffrence"), compute="cal_tot_cont_time", multi="cal_tot_cont_time")
planned_ids = fields.One2many("planned.hours", "sheet_id", _("Planned Hours"))
actual_ot = fields.Float(_("Actual Overttime Count"), compute="calc_actual_ot")
timesheet_ids2 = fields.One2many("hr.analytic.timesheet","sheet_id",string="Timesheet")
total_planned_hours = fields.Float(_("Planned Hours"), compute="cal_total_hours", multi="total_hours")
total_timesheet_hours =fields.Float(_("Total Hours"), compute="cal_total_hours", multi="total_hours")
overtime_hours =fields.Float(_("Overtime Hours"), compute="cal_total_hours", multi="total_hours")
class PlannedHours(models.Model):
_name = 'planned.hours'
sheet_date = fields.Date("Date")
duration = fields.Float("Hours")
sheet_id = fields.Many2one("hr_timesheet_sheet.sheet", 'Sheet')
class ServiceDescription(models.Model):
_name = 'service.description'
name = fields.Char("Service Description")
# sheet_id = fields.Many2one("hr_timesheet_sheet.sheet", 'Sheet')

View File

@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
from datetime import datetime
class ITISHoliday(models.Model):
_name = "itis.holiday"
name = fields.Char("Holiday Name")
date = fields.Date("Date")
@api.model
def get_holiday_date(self):
"""
function call from the js, use to return the holiday dates
"""
holiday_dates = []
for holiday_brw in self.search([]):
holiday_dates.append(holiday_brw.date)
return holiday_dates
@api.model
def create(self, values):
"""
To create holiday list entry calender of leave request
"""
res = super(ITISHoliday, self).create(values)
if values:
holiday_date = values.get('date')
holiday_name = values.get('name')
if holiday_date and holiday_name:
hr_holidays_status_brw = self.env['hr.holidays.status'].search([('is_holiday','=',True)],limit=1)
hr_holidays_env = self.env['hr.holidays']
if hr_holidays_status_brw:
hr_emp_records = self.env['hr.employee'].search([('user_id','!=',None)])
for hr_emp_brw in hr_emp_records:
try:
hr_holiday_brw = hr_holidays_env.with_context(mail_notify_force_send=False,holiday_create=True,mail_create_nosubscribe=False,mail_create_nolog=False).\
create({'employee_id':hr_emp_brw.id, 'date_from':holiday_date,'date_to':holiday_date,
'holiday_name':holiday_name,'holiday_status_id':hr_holidays_status_brw.id,
'holiday_type':'employee','leave_selection':'full_day','leave_selection_date_to':'full_day',})
# msg = _("Holiday %s created.") %(holiday_name)
# hr_holiday_brw.message_post(body=msg)
self._cr.execute("update hr_holidays set state = 'validate' where id = %s",(hr_holiday_brw.id,))
except:
#Todo Error handling
pass
return res
@api.multi
def unlink(self):
"""
To delete the related holiday from the leave request
"""
for itis_holiday_brw in self:
hr_holidays_env = self.env['hr.holidays']
hr_holidays_records = hr_holidays_env.search([('date_from','=',itis_holiday_brw.date),('holiday_name','=',itis_holiday_brw.name)])
for hr_holiday_brw in hr_holidays_records:
self._cr.execute("delete from hr_holidays where id = %s",(hr_holiday_brw.id,))
return super(ITISHoliday, self).unlink()
@api.multi
def write(self, vals):
"""
To write on the leave request holiday base upon the conditions
"""
hr_holidays_status_brw = self.env['hr.holidays.status'].search([('is_holiday','=',True)],limit=1)
hr_holidays_env = self.env['hr.holidays']
if vals.get('date'):
hr_holidays_records = hr_holidays_env.search([('date_from','=',self.date),('holiday_name','=',self.name)])
for hr_holiday_brw in hr_holidays_records:
self._cr.execute("delete from hr_holidays where id = %s",(hr_holiday_brw.id,))
if vals.get('name'):
name = vals.get('name')
else:
name = self.name
if hr_holidays_status_brw:
hr_emp_records = self.env['hr.employee'].search([('user_id','!=',None)])
for hr_emp_brw in hr_emp_records:
hr_holiday_brw = hr_holidays_env.create({'employee_id':hr_emp_brw.id,'date_from':vals.get('date'),'date_to':vals.get('date'),'holiday_name':name,'holiday_status_id':hr_holidays_status_brw.id})
# msg = _("Holiday %s created.") %(name)
# hr_holiday_brw.message_post(body=msg)
self._cr.execute("update hr_holidays set state = 'validate' where id = %s",(hr_holiday_brw.id,))
elif vals.get('name') and not vals.get('date'):
hr_holidays_records = hr_holidays_env.search([('date_from','=',self.date),('holiday_name','=',self.name)])
for hr_holidays_brw in hr_holidays_records:
self._cr.execute("update hr_holidays set holiday_name = %s where id = %s" , (vals.get('name'),hr_holidays_brw.id))
res = super(ITISHoliday, self).write(vals)
return res

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="0">
<record id="group_hr_supervisor" model="res.groups">
<field name="name">Vorgesetzter</field>
<field name="comment">the user will have the additional right to see timesheet overview manager view.</field>
<field name="category_id" ref="base.module_category_hidden"/>
</record>
</data>
</openerp>

View File

@ -0,0 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_planned_hours,access_planned_hours,model_planned_hours,,1,1,1,1
access_itis_holiday,access_itis_holiday,model_itis_holiday,base.group_user,1,0,0,0
access_itis_holiday_officer,access_itis_holiday_officer,model_itis_holiday,base.group_hr_user,1,1,1,1
access_service_des_read,access_service_desc_read,model_service_description,base.group_user,1,0,0,0
access_service_des_officer,access_service_des_officer,model_service_description,base.group_hr_user,1,1,1,1
access_service_des_manager,access_service_des_manager,model_service_description,base.group_hr_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_planned_hours access_planned_hours model_planned_hours 1 1 1 1
3 access_itis_holiday access_itis_holiday model_itis_holiday base.group_user 1 0 0 0
4 access_itis_holiday_officer access_itis_holiday_officer model_itis_holiday base.group_hr_user 1 1 1 1
5 access_service_des_read access_service_desc_read model_service_description base.group_user 1 0 0 0
6 access_service_des_officer access_service_des_officer model_service_description base.group_hr_user 1 1 1 1
7 access_service_des_manager access_service_des_manager model_service_description base.group_hr_manager 1 1 1 1

View File

@ -0,0 +1,59 @@
.led-green {
float: left;
margin: 0 auto;
width: 24px;
height: 24px;
background-color: #ABFF00;
border-radius: 50%;
box-shadow: rgba(0,0,0,0.2) 0 -1px 7px 1px, inset #304701 0 -1px 9px, #89FF00 0 2px 12px;
}
.led-green-off {
float: left;
margin: 0 auto;
width: 24px;
height: 24px;
background-color: #304701;
border-radius: 50%;
}
.led-yellow {
float: left;
margin: 0 auto;
width: 24px;
height: 24px;
background-color: #FF0;
border-radius: 50%;
box-shadow: rgba(0,0,0,0.2) 0 -1px 7px 1px, inset #808002 0 -1px 9px, #FF0 0 2px 12px;
}
.led-yellow-off {
float: left;
margin: 0 auto;
width: 24px;
height: 24px;
background-color: #808002;
border-radius: 50%;
}
.led-red {
float: left;
margin: 0 auto;
width: 24px;
height: 24px;
background-color: #F00;
border-radius: 50%;
box-shadow: rgba(0,0,0,0.2) 0 -1px 7px 1px, inset #441313 0 -1px 9px, rgba(255, 0, 0, 0.5) 0 2px 12px;
}
.led-red-off {
float: left;
margin: 0 auto;
width: 24px;
height: 24px;
background-color: #441313;
border-radius: 50%;
}
.itis_traffic_light{
position: absolute;
margin-left: 10px;
}
.openerp .oe_timesheet_weekly .oe_timesheet_weekend {
background: #ffff00;
}

View File

@ -0,0 +1,261 @@
openerp.itis_hr_attendance_extend = function (instance) {
var QWeb = instance.web.qweb;
var _t = instance.web._t;
var _lt = instance.web._lt;
var actionManager = instance.web.ActionManager;
instance.hr_attendance.AttendanceSlider.include({
do_update_attendance: function() {
var self = this;
this.$el.hide();
var employee = new instance.web.DataSetSearch(self, 'hr.employee', self.session.user_context, [
['user_id', '=', self.session.uid]
]);
employee.read_slice(['id', 'name', 'state', 'last_sign', 'attendance_access']).then(function (res) {
if (_.isEmpty(res) )
return;
if (res[0].attendance_access === false){
return;
}
self.$el.show();
self.employee = res[0];
self.last_sign = instance.web.str_to_datetime(self.employee.last_sign);
self.set({"signed_in": self.employee.state !== "absent"});
if(self.employee.state !== "absent"){
self.do_sign_out();
}else{
self.do_sign_in();
}
});
},
do_sign_in: function () {
var self = this;
var sign_in_obj = new instance.web.DataSet(self, 'sign.in.task');
sign_in_obj.call('create', [{
'analytic_account_id': false
}]).done(function(result){
console.log("idddd',",result);
self.temp_wizard_id = result;
var action = {
type: 'ir.actions.act_window',
res_model: 'sign.in.task',
view_mode: 'form',
view_type: 'form',
res_id: result,
views: [[false, 'form']],
target: 'new',
}
var act_ = new actionManager().do_action(action, {
on_close: function() {
self.read_values();
},
});
});
},
read_values: function (){
var self = this;
console.log('thssiss',this.temp_wizard_id);
var sign_in_obj = new instance.web.DataSet(self, 'sign.in.task');
sign_in_obj.call("do_entry_timesheet", [[this.temp_wizard_id]]).done(function(result){
console.log('reeeeee',result);
if(result){
self.super_do_update_attendance(result);
}
});
},
super_do_update_attendance: function (timesheet_id) {
var self = this;
var context = new instance.web.CompoundContext();
context.add({'timesheet_id': timesheet_id})
var hr_employee = new instance.web.DataSet(self, 'hr.employee');
hr_employee.call('attendance_action_change', [
[self.employee.id],
context
]).done(function (result) {
self.last_sign = new Date();
self.set({"timesheet_id": timesheet_id})
self.set({"signed_in": ! self.get("signed_in")});
});
},
do_sign_out: function(){
var self = this;
var ts_obj = new instance.web.DataSet(self, "hr.analytic.timesheet");
var timesheet_id = self.get("timesheet_id");
console.log("self.last_sign",self.last_sign);
ts_obj.call("update_hours", [[timesheet_id], self.last_sign]).done(function (result){
console.log("rrrrr",result);
if(result){
self.super_do_update_attendance(timesheet_id);
}
});
},
});
instance.hr_timesheet_sheet.WeeklyTimesheet.include({
init_add_account: function() {
var self = this;
if (self.dfm)
return;
console.log("In my customize-------")
self.$(".oe_timesheet_weekly_add_row").show();
self.dfm = new instance.web.form.DefaultFieldManager(self);
self.dfm.extend_field_desc({
account: {
relation: "account.analytic.account",
},
service_desc:{
relation: "service.description",
},
});
// Add a logic to add comment and service description fields
self.service_desc_m2o = new instance.web.form.FieldMany2One(self.dfm, {
attrs: {
name: "service_desc",
type: "many2one",
placeholder: _t("Select Service Description"),
},
});
self.service_desc_m2o.prependTo(self.$(".oe_timesheet_weekly_add_row_service"));
self.comment_char = new instance.web.form.FieldText(self.dfm, {
attrs: {
name: "emp_comment",
type: "char",
placeholder: _t("Add comment"),
},
});
self.comment_char.prependTo(self.$(".oe_timesheet_weekly_add_row_comment"));
// END
self.account_m2o = new instance.web.form.FieldMany2One(self.dfm, {
attrs: {
name: "account",
type: "many2one",
domain: [
['type','in',['normal', 'contract']],
['state', '<>', 'close'],
['use_timesheets','=',1],
['id', 'not in', _.pluck(self.accounts, "account")],
],
context: {
default_use_timesheets: 1,
default_type: "contract",
},
modifiers: '{"required": true}',
},
});
self.account_m2o.prependTo(self.$(".oe_timesheet_weekly_add_row_account"));
self.$(".oe_timesheet_weekly_add_row button").click(function() {
var id = self.account_m2o.get_value();
var service_desc_id = self.service_desc_m2o.get_value();
var comment = self.comment_char.get_value();
if (id === false) {
self.dfm.set({display_invalid_fields: true});
return;
}
var ops = self.generate_o2m_value();
new instance.web.Model("hr.analytic.timesheet").call("multi_on_change_account_id", [[], [id],
new instance.web.CompoundContext({'user_id': self.get('user_id')})]).then(function(res) {
res = res[id];
var def = _.extend({}, self.default_get, res.value, {
name: self.description_line,
unit_amount: 0,
date: instance.web.date_to_str(self.dates[0]),
account_id: id,
emp_comment: comment,
service_desc_id : service_desc_id,
});
ops.push(def);
self.set({"sheets": ops});
});
});
},
initialize_content: function(){
var self = this;
var sheet_id = this.field_manager.datarecord.id;
// Add a logic to get the holiday dates from the python function
new instance.web.Model("itis.holiday").call("get_holiday_date").then(function(results){
self.holiday = results;
});
if(sheet_id){
new instance.web.Model("planned.hours").call("search_read", [[['sheet_id', '=', sheet_id]], ['sheet_date', 'duration']]).then(function(results){
results.sort(self.dynamicSort("sheet_date"));
self.planned_hours = results;
});
}else{
self.planned_hours = [];
}
this._super();
// new instance.web.Model("hr_timesheet_sheet.sheet").call("get_analytic_timesheet_data",[[sheet_id]]).then(function(results){
// console.log("RESULT-------",results)
// self.analytic_timesheet_data = results;
// });
},
dynamicSort: function(property){
var sortOrder = 1;
if(property[0] === "-"){
sortOrder = -1;
property = property.substr(1);
}
return function(a,b){
var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
return result * sortOrder;
}
},
display_data: function(){
var self = this;
this._super();
var tot = 0.0;
var self = this;
var day_tots = _.map(_.range(self.dates.length), function() { return 0 });
var super_tot = 0;
_.each(self.accounts, function(account) {
var acc_tot = 0;
_.each(_.range(self.dates.length), function(day_count) {
var sum = self.sum_box(account, day_count);
acc_tot += sum;
day_tots[day_count] += sum;
super_tot += sum;
});
});
var count = 0;
_.each(this.planned_hours, function(pln_hrs){
var overtime = day_tots[count]-pln_hrs.duration;
tot += pln_hrs.duration;
self.$('[data-pln-dt="' + pln_hrs.sheet_date + '"]').html(self.format_client(pln_hrs.duration));
self.$('[data-ovr-tm="' + pln_hrs.sheet_date + '"]').html(self.format_client(overtime));
count += 1;
});
var tot_ovr_tm = super_tot - tot;
self.$('.oe_ph_hrs_total').html(self.format_client(tot));
self.$('.oe_ovr_tm_total').html(self.format_client(tot_ovr_tm));
}
});
instance.web.form.FieldFloat.include({
render_value: function(){
if(this.options.from_itis){
cur_val = this.get_value();
var trf_lgt = this.$el.find(".itis_traffic_light");
if(trf_lgt.length === 0){
this.$el.append("<span class='itis_traffic_light'></span>")
}
if(cur_val <= 20.0 && cur_val >= -20.0){
this.$el.find(".itis_traffic_light").html("<div class='led-green'>&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='led-yellow-off'>&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='led-red-off'>&nbsp;&nbsp;&nbsp;&nbsp;</div>");
}
if((cur_val > 20.0 && cur_val < 39.99) || (cur_val >= -39.99 && cur_val < -20.0)){
this.$el.find(".itis_traffic_light").html("<div class='led-green-off'>&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='led-yellow'>&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='led-red-off'>&nbsp;&nbsp;&nbsp;&nbsp;</div>");
}
if(cur_val > 39.99 || cur_val < -39.99){
this.$el.find(".itis_traffic_light").html("<div class='led-green-off'>&nbsp;&nbsp;&nbsp;&nbsp;</div></div><div class='led-yellow-off'>&nbsp;&nbsp;&nbsp;&nbsp;</div></div><div class='led-red'>&nbsp;&nbsp;&nbsp;&nbsp;</div>");
}
}
this._super();
}
});
};

View File

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- vim:fdl=1: -->
<templates id="template" xml:space="preserve">
<t t-extend="hr_timesheet_sheet.WeeklyTimesheet">
<t t-jquery=".oe_timesheet_weekly table" t-operation="replace">
<table>
<tr>
<th class="oe_timesheet_first_col"> </th>
<t t-foreach="widget.dates" t-as="date">
<t t-set="holiday_condition" t-value="0"/><!--Add a logic to check the holiday list and compare with the dates and base upon that add a class-->
<t t-foreach="widget.holiday" t-as="holiday_date">
<t t-if="date.toString('yyyy-MM-dd') == holiday_date" t-set="holiday_condition" t-value="1"/>
</t>
<th t-att-class="'oe_timesheet_weekly_date_head' + (Date.compare(date, Date.today()) === 0 ? ' oe_timesheet_weekly_today' : '')
+ (date.toString('ddd') =='Sat' ? ' oe_timesheet_weekend' : '')+ (date.toString('ddd') =='Sun' ? ' oe_timesheet_weekend' : '')
+ (date.toString('ddd') =='Sa' ? ' oe_timesheet_weekend' : '')+ (date.toString('ddd') =='So' ? ' oe_timesheet_weekend' : '')
+ (holiday_condition == 1 ? ' oe_timesheet_weekend' : '')">
<t t-esc="date.toString('ddd')" class ="oe_timesheet_weekend" /><br />
<t t-esc="date.toString('MMM d')"/>
</th>
</t>
<th class="oe_timesheet_weekly_date_head">Total</th>
</tr>
<tr t-foreach="widget.accounts" t-as="account">
<td class="oe_timesheet_weekly_account"><a href="javascript:void(0)" t-att-data-id="JSON.stringify(account.account)"><t t-esc="widget.account_names[account.account]"/></a></td>
<t t-set="day_count" t-value="0"/>
<t t-foreach="account.days" t-as="day">
<td t-att-class="(Date.compare(day.day, Date.today()) === 0 ? 'oe_timesheet_weekly_today' : '')">
<input t-if="!widget.get('effective_readonly')" class="oe_timesheet_weekly_input" t-att-data-account="account.account"
t-att-data-day-count="day_count" type="text"/>
<span t-if="widget.get('effective_readonly')" t-att-data-account="account.account"
t-att-data-day-count="day_count" class="oe_timesheet_weekly_box"/>
<t t-set="day_count" t-value="day_count + 1"/>
</td>
</t>
<td t-att-data-account-total="account.account" class="oe_timesheet_total"> </td>
</tr>
<tr class="oe_timesheet_weekly_add_row" style="display: none">
<td class = "oe_timesheet_weekly_add_row_account">
</td>
<td class = "oe_timesheet_weekly_add_row_service">
</td>
<td class = "oe_timesheet_weekly_add_row_comment">
</td>
<td t-att-colspan="widget.dates.length + 4">
<button class="oe_highlight">Add</button>
</td>
</tr>
<tr class="oe_timesheet_total">
<td>
<div class="oe_timesheet_weekly_adding_tot">
<div t-if="!widget.get('effective_readonly')" class="oe_timesheet_weekly_adding"><button class="oe_timesheet_button_add">Add a Line</button></div>
<div class="oe_timesheet_weekly_tottot"><span>Total</span></div>
</div>
</td>
<t t-set="day_count" t-value="0"/>
<t t-foreach="widget.dates" t-as="date">
<td class="oe_timesheet_total">
<span class="oe_timesheet_weekly_box" t-att-data-day-total="day_count">
</span>
<t t-set="day_count" t-value="day_count + 1"/>
</td>
</t>
<td class="oe_timesheet_weekly_supertotal oe_timesheet_total"> </td>
</tr>
</table>
</t>
</t>
<t t-extend="hr_timesheet_sheet.WeeklyTimesheet">
<t t-jquery=".oe_timesheet_weekly table" t-operation="append">
<tr class="oe_timesheet_total">
<td>
<div class="oe_timesheet_weekly_adding_tot">
<div class="oe_timesheet_weekly_tottot"><span>Planned Hours</span></div>
</div>
</td>
<t t-foreach="widget.planned_hours" t-as="pl_hrs">
<td class="oe_timesheet_total">
<span t-att-data-pln-dt="pl_hrs.sheet_date"/>
</td>
</t>
<td class="oe_ph_hrs_total oe_timesheet_total"></td>
</tr>
<tr class="oe_timesheet_total">
<td>
<div class="oe_timesheet_weekly_adding_tot">
<div class="oe_timesheet_weekly_tottot"><span>Overtime Hours</span></div>
</div>
</td>
<t t-foreach="widget.planned_hours" t-as="pl_hrs">
<td class="oe_timesheet_total">
<span t-att-data-ovr-tm="pl_hrs.sheet_date"/>
</td>
</t>
<td class="oe_ovr_tm_total oe_timesheet_total"></td>
</tr>
</t>
</t>
</templates>

View File

@ -0,0 +1 @@
from . import test_hr_attendance_extend

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from openerp.tests.common import TransactionCase
from datetime import datetime
import logging
_logger = logging.getLogger(__name__)
class TestHrAttendanceExtend(TransactionCase):
def test_itis_holiday_create(self):
"""test case to test creation of the hr holidays"""
itis_holiday = self.env['itis.holiday']
today_date = datetime.now().date().strftime('%Y-%m-%d')
itis_holiday_rec = itis_holiday.create({'name':'Holiday','date':today_date})
if itis_holiday_rec:
_logger.info('-----Holiday is successfully created.')
else:
self.assertEqual(0,1,'Odoo-Alfresco:- Holiday test case is failed.')

View File

@ -0,0 +1,21 @@
<?xml version='1.0' encoding='UTF-8' ?>
<openerp>
<data>
<!-- hr holidays form view -->
<record id="view_holiday_new_calendar_inherit_itis" model="ir.ui.view">
<field name="name">Leave Request Inherit</field>
<field name="model">hr.holidays</field>
<field name="inherit_id" ref="hr_holidays.view_holiday_new_calendar"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='holiday_status_id']" position="after">
<field name="holiday_name" readonly="1"/>
</xpath>
<field name="employee_id" position="before">
<field name="state_value"/>
</field>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,519 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- vim:fdn=3:
-->
<openerp>
<data>
<record id="hr_timesheet_sheet_sheet_form_inherited" model="ir.ui.view">
<field name="name">hr_timesheet_sheet_sheet_form_inherited</field>
<field name="model">hr_timesheet_sheet.sheet</field>
<field name="inherit_id" ref="hr_timesheet_sheet.hr_timesheet_sheet_form"/>
<field name="arch" type="xml">
<xpath expr="//form" position="attributes">
<attribute name="create">false</attribute>
</xpath>
<button name="cancel" position="replace">
<button name="action_cancel" states="confirm" string="Refuse" type="object" groups="base.group_hr_user"/>
</button>
<field name='employee_id' position="attributes">
<attribute name="readonly">True</attribute>
</field>
<field name='name' position="before">
<label for="actual_ot" />
<div>
<b><field name='actual_ot' widget="float_time" options="{'from_itis':True}"/></b>
</div>
</field>
<field name="total_attendance" position="attributes">
<attribute name="invisible">1</attribute>
</field>
<xpath expr="//field[@name='date_from']/parent::div" position="replace">
<div><field name="date_from" class="oe_inline" readonly="1"/> <field name="date_to" class="oe_inline" invisible="1"/></div>
</xpath>
<field name="total_attendance" position="after">
<label for="total_contract_time"/>
<div>
<field name="total_contract_time" widget="float_time" class='oe_inline'/>
<button name="calc_planned_hours" type="object" string='Refresh' class='oe_link'/>
</div>
</field>
<field name="total_timesheet" position="after">
<field name="time_diff" widget="float_time"/>
</field>
<field name="total_difference" position='attributes'>
<attribute name="invisible">1</attribute>
</field>
<field name="total_difference" position='after'>
<field name="planned_ids" invisible="1">
<tree>
<field name="sheet_date"/>
<field name="duration"/>
</tree>
</field>
</field>
<xpath expr="//button[@name='%(hr_timesheet_sheet.act_hr_timesheet_sheet_sheet_2_hr_analytic_timesheet)d']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//button[@name='%(hr_timesheet_sheet.act_hr_timesheet_sheet_sheet_2_hr_attendance)d']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//page[@string='Attendances']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<button name="button_confirm" position="attributes">
<attribute name="string">Timesheet abschließen</attribute>
<attribute name="invisible">True</attribute>
</button>
<button string="Sign In" position="replace"/>
<button string="Sign Out" position="replace"/>
<xpath expr="//field[@name='timesheet_ids']/tree/field[@name='account_id']" position="after">
<field name="service_desc_id" widget="selection"/>
<field name="emp_comment"/>
</xpath>
<!--hide the timesheet js view -->
<xpath expr="//page[@string='Summary']" position="replace"/>
<!--Add a view which is same as the detial view with same many2one-->
<xpath expr="//page[@string='Details']" position="before">
<page string="Timesheet Summary">
<field context="{'employee_id': employee_id, 'user_id':user_id, 'timesheet_date_from': date_from, 'timesheet_date_to': date_to}"
name="timesheet_ids2" nolabel="1" attrs="{'readonly': [('state', 'not in', ['draft','new'])]}" >
<tree editable="bottom" string="Timesheet Activities" delete="false">
<field name="date" required="1"/>
<field options='{"no_open":1,"no_create":1,"no_create_edit":1}' domain="[('type','in',['normal', 'contract']), ('state', '&lt;&gt;', 'close'),('use_timesheets','=',1)]" name="account_id" on_change="on_change_account_id(account_id, user_id)" context="{'default_use_timesheets': 1}"/>
<field name="service_desc_id" options='{"no_create":1,"no_create_edit":1,"no_open":1}'/>
<field name="emp_comment"/>
<field name="name" required="0" invisible="1"/>
<field name="unit_amount" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)" widget="float_time" string="Hours" sum="Hours"/>
<field name="to_invoice" widget="selection" invisible="1"/>
<field invisible="1" name="journal_id"/>
<field invisible="1" name="product_id" domain="[('type','=','service')]" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)"/>
<field invisible="1" name="product_uom_id" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)"/>
<field invisible="1" name="amount"/>
<field invisible="1" name="general_account_id"/>
<field invisible="1" name="user_id" required="1"/>
</tree>
</field>
<group>
<div class="oe_right" style="text-align: right;" name="tot_hours">
<group class="oe_right" style="text-align: right;" name="tot_hours">
<field name="total_timesheet_hours" widget="float_time"/>
<field name="total_planned_hours" widget="float_time"/>
<field name="overtime_hours" widget="float_time"/>
</group>
</div>
</group>
</page>
</xpath>
</field>
</record>
<!-- hr anlaytic tree view editable-->
<record model="ir.ui.view" id="hr_timesheet_line_tree_inherit_itis">
<field name="name">hr.analytic.timesheet.tree.itis</field>
<field name="model">hr.analytic.timesheet</field>
<field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_tree"/>
<field name="arch" type="xml">
<xpath expr="/tree/field[@name='account_id']" position="after">
<field name="dept_account_id"/>
<!--<button name = "get_monthly_timesheet_overview" type="object" string="Get"/>-->
<field name="service_desc_id" widget="selection"/>
<field name="emp_comment"/>
</xpath>
</field>
</record>
<!--timesheet tree view-->
<record model="ir.ui.view" id="hr_timesheet_sheet_tree_simplified_inherit_itis">
<field name="name">hr.timesheet.sheet.tree.simplified.itis</field>
<field name="model">hr_timesheet_sheet.sheet</field>
<field name="inherit_id" ref="hr_timesheet_sheet.hr_timesheet_sheet_tree_simplified"/>
<field eval="12" name="priority"/>
<field name="arch" type="xml">
<xpath expr="//tree" position="attributes">
<attribute name="create">false</attribute>
</xpath>
<xpath expr="//field[@name='total_attendance']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='total_timesheet']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='total_difference']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='department_id']" position="after">
<field name="total_timesheet" sum="Total time" widget="float_time" string="Summe Stunden"/>
<field name="total_contract_time" widget="float_time" string="Geplante Stunden" sum="total_contract_time"/>
<field name="time_diff" widget="float_time" string="Überstunden" sum="total_overtime_time"/>
</xpath>
</field>
</record>
<!--timesheet search view-->
<record id="view_hr_timesheet_sheet_filter_inherit" model="ir.ui.view">
<field name="name">hr_timesheet_sheet.sheet.filter,inherit</field>
<field name="model">hr_timesheet_sheet.sheet</field>
<field name="inherit_id" ref="hr_timesheet_sheet.view_hr_timesheet_sheet_filter"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='date_from']" position="after">
<field name="date_to" filter_domain ="[('date_to', '&lt;=',self)]"/>
</xpath>
<xpath expr="//field[@name='date_from']" position="attributes">
<attribute name="filter_domain">[('date_from', '&gt;=',self)]</attribute>
</xpath>
<xpath expr="//filter[@string='Department']" position="after">
<filter string="Week" domain="[]" context="{'group_by':'date_to:week'}" help="Group by week of date"/>
<filter string="Month" domain="[]" context="{'group_by':'date_to:month'}" help="Group by month of date"/>
<filter string="Year" domain="[]" context="{'group_by':'date_to:year'}" help="Group by year of date"/>
</xpath>
</field>
</record>
<!--another view for the timesheet edited and create for HR and admin-->
<!--timesheet tree view-->
<!--<record model="ir.ui.view" id="hr_timesheet_sheet_tree_editable">-->
<!--<field name="name">hr.timesheet.sheet.tree.editalbe.itis</field>-->
<!--<field name="model">hr_timesheet_sheet.sheet</field>-->
<!--<field eval="15" name="priority"/>-->
<!--<field name="arch" type="xml">-->
<!--<tree colors="blue:state == 'draft';black:state in ('confirm','new');gray:state == 'done'" string="Timesheets">-->
<!--<field name="employee_id"/>-->
<!--<field name="date_from"/>-->
<!--<field name="date_to"/>-->
<!--<field name="department_id" invisible="1"/>-->
<!--<field name="total_timesheet" sum="Total time" widget="float_time" string="Summe Stunden"/>-->
<!--<field name="total_contract_time" widget="float_time" string="Geplante Stunden" sum="total_contract_time"/>-->
<!--<field name="time_diff" widget="float_time" string="Überstunden" sum="total_overtime_time"/>-->
<!--<field name="state"/>-->
<!--</tree>-->
<!--</field>-->
<!--</record>-->
<!--timesheet new editalble and create form view-->
<record id="hr_timesheet_sheet_form_editable_itis_new" model="ir.ui.view">
<field name="name">hr.timesheet.sheet.form.editable.itis.new</field>
<field name="model">hr_timesheet_sheet.sheet</field>
<field name="arch" type="xml">
<form string="Timesheet">
<header>
<button name="button_confirm" states="draft" string="Submit to Manager" type="object" class="oe_highlight" invisible="1"/>
<button name="done" states="confirm" string="Approve" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button name="action_set_to_draft" states="done" string="Set to Draft" type="object" />
<button name="action_cancel" states="confirm" string="Refuse" type="object" groups="base.group_hr_user"/>
<button name="cancel" states="confirm" string="Refuse" type="workflow" groups="base.group_hr_user" invisible="1" />
<field name="state" widget="statusbar" statusbar_visible="new,confirm,done"/>
</header>
<sheet>
<div class="oe_title">
<label for="employee_id" class="oe_edit_only"/>
<h1><field name="employee_id" on_change="onchange_employee_id(employee_id)" class="oe_inline"/></h1>
<field name="user_id" invisible="1"/>
</div>
<group>
<group>
<label for="date_from" string="Timesheet Period"/>
<div><field name="date_from" class="oe_inline"/> to <field name="date_to" class="oe_inline"/></div>
<label for="actual_ot" />
<div>
<b><field name='actual_ot' widget="float_time" options="{'from_itis':True}"/></b>
</div>
<field name="name" invisible="1"/>
<field name="department_id" invisible="1"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group groups="base.group_hr_attendance">
<field name="total_attendance" widget="float_time" invisible="1"/>
<label for="total_contract_time"/>
<div>
<field name="total_contract_time" widget="float_time" class='oe_inline'/>
<button name="calc_planned_hours" type="object" string='Refresh' class='oe_link'/>
</div>
<field name="total_timesheet" widget="float_time"/>
<field name="time_diff" widget="float_time"/>
<field name="total_difference" widget="float_time" invisible="1"/>
<field name="planned_ids" invisible="1">
<tree>
<field name="sheet_date"/>
<field name="duration"/>
</tree>
</field>
</group>
</group>
<notebook>
<page string="Summary" invisible="1">
<widget type="weekly_timesheet" attrs="{'readonly': [['state', 'not in', ['new', 'draft']]]}">
</widget>
</page>
<page string="Timesheet Summary">
<field context="{'employee_id': employee_id, 'user_id':user_id, 'timesheet_date_from': date_from, 'timesheet_date_to': date_to}"
name="timesheet_ids2" nolabel="1" attrs="{'readonly': [('state', 'not in', ['draft','new'])]}" >
<tree editable="bottom" string="Timesheet Activities" delete="false">
<field name="date" required="1"/>
<field options='{"no_open":1,"no_create":1,"no_create_edit":1}' domain="[('type','in',['normal', 'contract']), ('state', '&lt;&gt;', 'close'),('use_timesheets','=',1)]" name="account_id" on_change="on_change_account_id(account_id, user_id)" context="{'default_use_timesheets': 1}"/>
<field name="service_desc_id" options='{"no_create":1,"no_create_edit":1}'/>
<field name="emp_comment"/>
<field name="name" required="0" invisible="1"/>
<field name="unit_amount" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)" widget="float_time" string="Hours" sum="Hours"/>
<field name="to_invoice" widget="selection" invisible="1"/>
<field invisible="1" name="journal_id"/>
<field invisible="1" name="product_id" domain="[('type','=','service')]" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)"/>
<field invisible="1" name="product_uom_id" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)"/>
<field invisible="1" name="amount"/>
<field invisible="1" name="general_account_id"/>
<field invisible="1" name="user_id" required="1"/>
</tree>
</field>
<group>
<div class="oe_right" style="text-align: right;" name="tot_hours">
<group class="oe_right" style="text-align: right;" name="tot_hours">
<field name="total_timesheet_hours" widget="float_time"/>
<field name="total_planned_hours" widget="float_time"/>
<field name="overtime_hours" widget="float_time"/>
</group>
</div>
</group>
</page>
<page string="Details">
<field context="{'employee_id': employee_id, 'user_id':user_id, 'timesheet_date_from': date_from, 'timesheet_date_to': date_to}" name="timesheet_ids" nolabel="1">
<tree editable="bottom" string="Timesheet Activities">
<field name="date"/>
<field domain="[('type','in',['normal', 'contract']), ('state', '&lt;&gt;', 'close'),('use_timesheets','=',1)]" name="account_id" on_change="on_change_account_id(account_id, user_id)" context="{'default_use_timesheets': 1}"/>
<field name="service_desc_id" widget="selection"/>
<field name="emp_comment"/>
<field name="name"/>
<field name="unit_amount" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)" widget="float_time" string="Hours" sum="Hours"/>
<field name="to_invoice" widget="selection"/>
<field invisible="1" name="journal_id"/>
<field invisible="1" name="product_id" domain="[('type','=','service')]" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)"/>
<field invisible="1" name="product_uom_id" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)"/>
<field invisible="1" name="amount"/>
<field invisible="1" name="general_account_id"/>
<field invisible="1" name="user_id" required="1"/>
</tree>
</field>
</page>
<page string="Attendances" groups="base.group_hr_attendance" invisible="1">
<group>
<field context="{'default_employee_id': employee_id, 'user_id':user_id}" name="attendances_ids" nolabel="1">
<tree string="Attendances" editable="bottom">
<field name="name"/>
<field name="action"/>
<field invisible="1" name="employee_id"/>
</tree>
</field>
<group>
<label for="state_attendance"/>
<div>
<field name="state_attendance"/>
<button name="attendance_action_change" attrs="{'invisible': [('state_attendance', '=', 'present')]}" type="object" string="Sign In" class="oe_link"/>
<button name="attendance_action_change" attrs="{'invisible': ['|', ('state_attendance','=',False), ('state_attendance', '=', 'absent')]}" type="object" string="Sign Out" class="oe_link"/>
</div>
</group>
</group>
<field name="period_ids">
<tree colors="red:total_difference&lt;0.1;blue:total_difference&gt;=0.1" string="Period">
<field name="name"/>
<field name="total_attendance" widget="float_time" sum="Attendances"/>
<field name="total_timesheet" widget="float_time" sum="Timesheets"/>
<field name="total_difference" widget="float_time" sum="Differences"/>
</tree>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!--another view for the timesheet edited and create for HR and admin-->
<record id="act_hr_timesheet_sheet" model="ir.actions.act_window">
<field name="name">Create Timesheet</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hr_timesheet_sheet.sheet</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<!--<record id="act_hr_timesheet_sheet_tree_new" model="ir.actions.act_window.view">-->
<!--<field eval="1" name="sequence"/>-->
<!--<field name="view_mode">tree</field>-->
<!--<field name="view_id" ref="hr_timesheet_sheet_tree_editable"/>-->
<!--<field name="act_window_id" ref="act_hr_timesheet_sheet"/>-->
<!--</record>-->
<record id="act_hr_timesheet_sheet_form_new" model="ir.actions.act_window.view">
<field eval="3" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="hr_timesheet_sheet_form_editable_itis_new"/>
<field name="act_window_id" ref="act_hr_timesheet_sheet"/>
</record>
<!--another view for the timesheet edited and create for HR and admin-->
<menuitem name="Create Timesheet" id="menu_act_hr_timesheet_sheet_form_my_current_editable" parent="hr_attendance.menu_hr_time_tracking" action="act_hr_timesheet_sheet" sequence="1" groups='base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user'/>
<!-- Inherited Analytic Account form -->
<record id="account_analytic_account_form_form_inherit" model="ir.ui.view">
<field name="name">account.analytic.account.invoice.form.inherit.itis</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
<field eval="40" name="priority"/>
<field name="arch" type="xml">
<xpath expr='//field[@name="currency_id"]' position="after">
<field name="account_code"/>
</xpath>
</field>
</record>
<!--add tree view for the timesheet activity overview-->
<record id="view_timehseet_activity_overview_tree" model="ir.ui.view">
<field name="name">timesheet.activity.overview.tree</field>
<field name="model">hr.analytic.timesheet</field>
<field name="arch" type="xml">
<tree string="Timesheet Overview" create="false" readonly="1">
<field name="identification_id"/>
<field name="dept_account_code"/>
<field name="name"/>
<field name="analytic_account_code"/>
<field name="date"/>
<field name="user_id"/>
<field name="unit_amount" widget="float_time"/>
</tree>
</field>
</record>
<!--add search for the timesheet activity overview-->
<record id="hr_timesheet_overview_search" model="ir.ui.view">
<field name="name">hr.analytic.timesheet.overview.search</field>
<field name="model">hr.analytic.timesheet</field>
<field name="arch" type="xml">
<search string="Timesheet">
<field name="date" filter_domain ="[('date', '&gt;=',self)]" string="Date From"/>
<field name="date" filter_domain ="[('date', '&lt;=',self)]" string="Date To"/>
<field name="user_id"/>
<field name="account_id"/>
<field name="dept_account_id"/>
<group expand="0" string="Group By">
<filter string="Users" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Analytic account" icon="terp-folder-green" domain="[]" context="{'group_by':'account_id'}"/>
<filter string="Dept. Analytic account" icon="terp-folder-green" domain="[]" context="{'group_by':'dept_account_id'}"/>
<filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_id'}"/>
<filter string="Timesheet Month" icon="terp-go-month" domain="[]" context="{'group_by':'date'}" help="Timesheet by Month"/>
</group>
</search>
</field>
</record>
<!--add action for the timesheet activity overview-->
<record id="act_hr_timesheet_overview" model="ir.actions.act_window">
<field name="name">Timesheet Activities Overview</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hr.analytic.timesheet</field>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="context">{"search_default_today":1}</field>
<field name="view_id" ref="view_timehseet_activity_overview_tree"/>
<field name="search_view_id" ref="hr_timesheet_overview_search"/>
</record>
<!--add menuitem for the timesheet activity overview-->
<menuitem id="menu_hr_timesheet_overview" parent="hr_attendance.menu_hr_time_tracking" action="act_hr_timesheet_overview" />
<!--add tree view for the timesheet activity overview for manager-->
<record id="view_timehseet_activity_overview_tree_manager" model="ir.ui.view">
<field name="name">timesheet.activity.overview.tree.manager</field>
<field name="model">hr.analytic.timesheet</field>
<field name="arch" type="xml">
<tree string="Timesheet Overview" create="false" readonly="1">
<!--<field name="user_id"/>-->
<field name="dept_account_code"/>
<field name="analytic_account_code"/>
<field name="unit_amount" widget="float_time"/>
<!--<field name="name"/>-->
<field name="emp_comment"/>
</tree>
</field>
</record>
<!--add action for the timesheet activity overview for manager, I have user ir.server action to filter the records-->
<record id="ir_actions_server_hr_timesheet_overview_manager" model="ir.actions.server">
<field name="state">code</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_hr_analytic_timesheet"/>
<field name="code">action = model.open_analytic_timesheet_tree()</field>
<field name="condition">True</field>
<field name="name">Timesheet Activities Manager</field>
</record>
<!--add menuitem for the timesheet activity overview for manager-->
<menuitem id="menu_hr_timesheet_overview_manager" parent="hr_attendance.menu_hr_time_tracking" action="ir_actions_server_hr_timesheet_overview_manager"
groups='itis_hr_attendance_extend.group_hr_supervisor'/>
<!--Add menu and action for the service description-->
<record id="itis_service_description_form" model='ir.ui.view'>
<field name="name">emp.service.description.form</field>
<field name="model">service.description</field>
<field name="arch" type="xml">
<form string="Service Description">
<sheet>
<group>
<field name="name"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="itis_service_description_tree" model='ir.ui.view'>
<field name="name">emp.service.description.tree</field>
<field name="model">service.description</field>
<field name="arch" type="xml">
<tree string="Service Description" editable="bottom">
<field name="name"/>
</tree>
</field>
</record>
<record id="emp_service_description_action" model="ir.actions.act_window">
<field name="name">Employee Service Description</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">service.description</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Service Description" parent="hr.menu_hr_configuration" action="emp_service_description_action"
id="menu_emp_service_description" groups='base.group_hr_payroll_manager,base.group_hr_manager'/>
<menuitem id="hr_timesheet.menu_hr_working_hours" parent="hr_attendance.menu_hr_time_tracking" action="hr_timesheet.act_hr_timesheet_line_evry1_all_form" groups='base.group_hr_payroll_manager,base.group_hr_manager'/>
<menuitem id="hr_timesheet.menu_create_time_sheets" name="Zeiterfassung erstellen"
parent="menu_hr_timesheet_overview"
action="act_hr_timesheet_overview"
groups='base.group_hr_payroll_manager,base.group_hr_manager'/>
</data>
</openerp>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- vim:fdn=3:
-->
<openerp>
<data>
<record id="itis_holiday_form_view" model="ir.ui.view">
<field name="name">itis_holiday_form_view</field>
<field name="model">itis.holiday</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="name" required="1"/>
<field name="date" required="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="itis_holiday_tree_view" model="ir.ui.view">
<field name="name">itis_holiday_tree_view</field>
<field name="model">itis.holiday</field>
<field name="arch" type="xml">
<tree>
<field name="name" required="1"/>
<field name="date" required="1"/>
</tree>
</field>
</record>
<record id="view_calendar_itis_holiday" model="ir.ui.view">
<field name="name">Holiday</field>
<field name="model">itis.holiday</field>
<field name="arch" type="xml">
<calendar string="Holiday" color="name"
date_start="date" date_stop="date"
quick_add="False" >
<field name="name"/>
</calendar>
</field>
</record>
<record id="act_itis_holiday" model="ir.actions.act_window">
<field name="name">Holidays</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">itis.holiday</field>
<field name="view_type">form</field>
<field name="view_mode">calendar,tree,form</field>
</record>
<menuitem name="Holidays" action="act_itis_holiday" parent="hr_holidays.menu_open_ask_holidays" id="menu_itis_holiday" sequence="1"/>
</data>
</openerp>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- vim:fdn=3:
-->
<openerp>
<data>
<template id="assets_backend" name="hr_extend assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<link rel="stylesheet" href="/itis_hr_attendance_extend/static/src/css/traffic_light.css"/>
<script type="text/javascript" src="/itis_hr_attendance_extend/static/src/js/hr_extend.js"></script>
</xpath>
</template>
</data>
</openerp>

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from . import sign_in_task
from . import hr_timesheet_overview_export

View File

@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields, api, _
from openerp.exceptions import Warning
import csv
from datetime import datetime
import base64
import os
class timesheet_overview_export(models.TransientModel):
_name = 'timesheet.overview.export'
name = fields.Binary('Timesheet CSV')
file_name = fields.Char('File')
def export_csv_subfunction(self,analytic_timesheet_records,active_domain):
data_list = []
csv_header = ['Personalnummer','Mitarbeitername', "Mitarbeiter Vorname",'Dept. Cost Center','Cost Center', "Dauer(metrisch)",'Description']
time_csv = datetime.now().strftime('%Y-%m-%d_%H%M%S') + '.csv'
csv_path = "/tmp/" + time_csv
for timesheet_overview_brw in analytic_timesheet_records:
emp_name, emp_first_name,emp_personal_no = '','',''
if timesheet_overview_brw.sheet_id:
emp_name = timesheet_overview_brw.sheet_id.employee_id.second_name
emp_first_name = timesheet_overview_brw.sheet_id.employee_id.surname
emp_personal_no = timesheet_overview_brw.sheet_id.employee_id.identification_id
vals = {
'Personalnummer': (emp_personal_no or '').encode('utf-8'),
'Dept. Cost Center': (timesheet_overview_brw.dept_account_id.account_code or '').encode('utf-8'),
'Description': (timesheet_overview_brw.emp_comment or '').encode('utf-8'),
"Cost Center": (timesheet_overview_brw.account_id.account_code or '').encode('utf-8'),
'Mitarbeitername': (emp_name or '').encode('utf-8'),
'Mitarbeiter Vorname': (emp_first_name or '').encode('utf-8'),
'Dauer(metrisch)': ("%.2f" % timesheet_overview_brw.unit_amount).replace('.',':'),
# 'Dauer(metrisch)': timesheet_overview_brw.unit_amount,
}
data_list.append(vals)
with open(csv_path, 'wb') as csvfile:
if active_domain:
w = csv.DictWriter(csvfile, fieldnames=['Filter'])
w.writeheader()
w.writerows([{'Filter':active_domain},{'Filter':' '}])
w = csv.DictWriter(csvfile, fieldnames=csv_header, delimiter=';')
w.writeheader()
w.writerows(data_list)
csvfile.close()
data = ''
with open(csv_path, 'rb') as csvfile:
data = csvfile.read()
data = data.encode('base64')
csvfile.close()
context = self._context.copy()
context.update({'default_name': data, 'default_file_name': 'timesheet_overview_export' + time_csv})
os.remove(csv_path)
return context
@api.multi
def export_csv(self):
"""
This function is use to export the timesheet overview records selected base on the filters
"""
analytic_timesheet,active_domain = self.env['hr.analytic.timesheet'],False
if self._context and 'active_model' in self._context and self._context['active_model'] == 'hr.analytic.timesheet':
context = self._context.copy()
active_domain = context.get('active_domain','')
if active_domain:
analytic_timesheet_records = analytic_timesheet.search(eval(str(active_domain)),order='account_id')
else:
analytic_timesheet_records = analytic_timesheet.browse(self._context['active_ids'])
# print"analytic_timesheet_records----",analytic_timesheet_records
context = self.export_csv_subfunction(analytic_timesheet_records,active_domain)
return {
'name': _('Exported Timsheet Overview'),
'view_type': 'form',
"view_mode": 'form',
'res_model': 'timesheet.overview.export',
'type': 'ir.actions.act_window',
'context': context,
'target':'new',
}

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="timesheet_overview_export_form_view" model='ir.ui.view'>
<field name="name">timesheet.overview.export.form.view</field>
<field name="model">timesheet.overview.export</field>
<field name="arch" type="xml">
<form>
<label string="Click 'Export' button to export timesheet overview csv" />
<div attrs="{'invisible': [('name', '=', False)]}">
<p>Export file: <field name="name" readonly="1" filename="file_name"/></p>
</div>
<field name='file_name' invisible="1"/>
<footer>
<button name='export_csv' type='object' string="Export" />
or
<button special="cancel" string="Cancel" class='oe_link' />
</footer>
</form>
</field>
</record>
<record id="timehseet_overview_export_action" model="ir.actions.act_window">
<field name="name">Timesheet Overview Export</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">timesheet.overview.export</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<act_window id="launch_timesheet_overview_export_wizard"
name="Timesheet Overview Export"
src_model="hr.analytic.timesheet"
res_model="timesheet.overview.export"
view_mode="form,tree"
target="new"
key2="client_action_multi"
groups='base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user'/>
</data>
</openerp>

View File

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _, osv
class SignInTask(models.TransientModel):
_name = "sign.in.task"
analytic_account_id = fields.Many2one("account.analytic.account", "Analytic Account")
service_desc_id = fields.Many2one('service.description',string="Service Desc")
emp_comment = fields.Text("Comment")
@api.multi
def set_task(self):
return True
@api.multi
def do_entry_timesheet(self):
timesheet_id = False
if self.analytic_account_id.id:
timesheet_obj = self.pool.get('hr.analytic.timesheet')
cr = self.env.cr
uid = self.env.uid
emp_obj = self.env['hr.employee']
hour = 0.0
res = timesheet_obj.default_get(cr, uid, ['product_id','product_uom_id'])
if not res['product_uom_id']:
raise osv.except_osv(_('User Error!'), _('Please define cost unit for this employee.'))
up = timesheet_obj.on_change_unit_amount(cr, uid, False, res['product_id'], hour,False, res['product_uom_id'])['value']
res['name'] = "From Time Tracker"
res['account_id'] = self.analytic_account_id.id
res['unit_amount'] = hour
res['service_desc_id'] = self.service_desc_id.id
res['emp_comment'] = self.emp_comment
emp_journal = emp_obj.search([('user_id', '=', self.env.uid)]).journal_id
res['journal_id'] = emp_journal and emp_journal.id or False
res.update(up)
up = timesheet_obj.on_change_account_id(cr, uid, [], res['account_id']).get('value', {})
res.update(up)
timesheet_id = timesheet_obj.create(cr, uid, res)
return timesheet_id

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- vim:fdn=3:
-->
<openerp>
<data>
<record id="sign_in_task_form_view" model='ir.ui.view'>
<field name="name">sign_in_task_form_view</field>
<field name="model">sign.in.task</field>
<field name="arch" type="xml">
<form>
<group>
<field name="analytic_account_id" domain="[('type', 'in', ['normal', 'contract']), ('state', '!=', 'close'), ('use_timesheets', '=', 1)]" options="{'no_open': True, 'no_create': True}" class="oe_inline" required="1"/>
<field name="service_desc_id" options="{'no_open': True, 'no_create': True}" class="oe_inline" widget="'selection"/>
<field name="emp_comment" class="oe_inline" />
</group>
<footer>
<button name="set_task" string="OK" type="object" class='oe_highlight'/>
or
<button special="cancel" string="Cancel" class='oe_link' />
</footer>
</form>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from . import models
from . import wizard

View File

@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': "ITIS HR Extend",
'summary': """ Module will extend Human Ressources""",
'description': """
Module to extend the functionalities of the HR module.
Employee new fields and views
Timesheet extensions
Day Off Workflow
Reporting
""",
'author': "IT IS AG",
'website': "http://www.itis-odoo.de",
'category': 'base',
'version': '1.0.55.0',
'depends': ['hr','hr_contract', 'hr_holidays', 'hr_payroll', 'resource'],
'data': [
'security/groups.xml',
'static/data.xml',
'views/employee_meeting_view.xml',
'views/hr_employee_view.xml',
'views/hr_holiday_view.xml',
'views/fte_report_view.xml',
'views/employee_report_view.xml',
'views/employee_payroll_report_view.xml',
'wizard/ot_change_view.xml',
'wizard/fte_wizard_view.xml',
'wizard/emp_payroll_wizard_view.xml',
'wizard/emp_data_wizard_view.xml',
'security/ir.model.access.csv',
'data/cron.xml',
'data/data.xml',
],
'css': [],
'demo': [],

View File

@ -0,0 +1,68 @@
<openerp>
<data noupdate="1">
<record id="itis_get_monthly_employee_data_cron" model="ir.cron">
<field name="name">ITIS Get Monthly Employee Data</field>
<field name="function">get_monthly_employee_data</field>
<field name="interval_type">months</field>
<field name="interval_number">1</field>
<field name="user_id" ref="base.user_root"/>
<!--<field name="active" eval="(True)"/>-->
<field name="numbercall">-1</field>
<field name="model">hr.employee</field>
<field name="nextcall" eval="(datetime.strptime('2018-02-01 03:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>
</record>
<!--scheduler added for the 1st june-->
<record id="itis_june_day_cal_cron" model="ir.cron">
<field name="name">ITIS June Year Change</field>
<field name="function">june_year_change_calc_days</field>
<field name="interval_type">months</field>
<field name="interval_number">12</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="(True)"/>
<field name="numbercall">-1</field>
<field name="model">hr.employee</field>
<field name="nextcall" eval="(datetime.strptime('2019-06-01 02:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>
</record>
<!--Imp Note :: This scheduler should run in Dec month.-->
<record id="itis_year_change_cron" model="ir.cron">
<field name="name">ITIS Jahreswechsel Urlaubsberechnung</field>
<field name="function">year_change_calc_days</field>
<field name="interval_type">months</field>
<field name="interval_number">12</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="(True)"/>
<field name="numbercall">-1</field>
<field name="model">hr.employee</field>
<field name="nextcall" eval="(datetime.strptime('2019-12-31 19:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>
</record>
<!--Imp Note :: This scheduler should run in Dec month.-->
<record id="itis_end_march_cron" model="ir.cron">
<field name="name">ITIS Verfall Resturlaub</field>
<field name="function">delete_last_year_leave_days</field>
<field name="interval_type">months</field>
<field name="interval_number">12</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="(True)"/>
<field name="numbercall">-1</field>
<field name="model">hr.employee</field>
<field name="nextcall" eval="(datetime.strptime('2019-12-31 16:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>
</record>
<!--scheduler to update new overtime count field for the 1st time-->
<record id="itis_update_new_overtime" model="ir.cron">
<field name="name">ITIS New overtime field update</field>
<field name="function">update_new_overtime_field</field>
<field name="interval_type">days</field>
<field name="interval_number">1</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="(False)"/>
<field name="numbercall">-1</field>
<field name="model">hr.employee</field>
<!--<field name="nextcall" eval="(datetime.strptime('2016-12-31 21:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>-->
</record>
</data>
</openerp>

126
itis_hr_extend/data/data.xml Executable file
View File

@ -0,0 +1,126 @@
<openerp>
<data>
<record id="email_template_monthly_employee_data" model="email.template">
<field name="name">Monthly Employee Data</field>
<field name="model_id" ref="itis_hr_extend.model_hr_employee" />
<field name="auto_delete" eval="True" />
<field name="email_from">${(user.email or '') | safe}</field>
<field name="email_to">${(user.email or '') | safe}</field>
<field name="subject">Monthly Employee Data Report</field>
<field name="body_html"><![CDATA[
<p>Sehr geehrte Kollegen,</p>
<br/>
<p>anbei erhalten Sie den aktuellen Report zur Kostenstellenübersicht nach Mitarbeiter.
</p><br/>
<p>Mit freundlichen Grüßen</p>
<p>Ihr HR-Team</p>
]]>
</field>
</record>
<record id="email_template_draft_leave_cancel" model="email.template">
<field name="name">Urlaub im Status Entwurf abgebrochen</field>
<field name="model_id" ref="itis_hr_extend.model_hr_holidays" />
<field name="auto_delete" eval="True" />
<field name="email_from">tictac@wikimedia.de</field>
<field name="email_to">${( object.employee_id.work_email or object.user_id != False and object.user_id.email )|safe},${( object.employee_id.parent_id.work_email)|safe},Personal@wikimedia.de</field>
<!--<field name="email_cc">${( object.employee_id.parent_id != False and object.employee_id.parent_id.work_email)|safe}</field>-->
<field name="email_cc"></field>
<field name="subject">Dein geplanter Urlaubsantrag (aus 2018) im Status Entwurf/Your planned holiday</field>
<field name="body_html"><![CDATA[
Liebe/r ${object.employee_id.surname},
<br><br>
wir informieren dich darüber, dass dein geplanter Urlaubsantrag für den ${ctx['date_from']} bis zum ${ctx['date_to']} automatisch aufgrund des Jahreswechsels
vom Status “Zu Bestätigen” (Entwurf) in den Status “Abgebrochen” geändert wurde.
<br><br>
Solltest du weitere Fragen haben, wende dich an das Team Personal.
<br>
Viele Grüße
<br>
Dein TicTac Team
<br><br>----------------<br><br>
Dear ${object.employee_id.surname},
<br><br>
we kindly inform you that your planned holiday from ${ctx['date_from']} until ${ctx['date_to']} was automatically changed from Status ”To Submit” (Draft)
into Status “Refused” due to year change.
<br><br>
For any questions please contact Team Personal.
<br>
Best Regards
<br>
Your TicTac Team
]]></field>
</record>
<record id="email_template_toapprove_leave_approve" model="email.template">
<field name="name">Urlaub im Status zu genehmigen genehmigt</field>
<field name="model_id" ref="itis_hr_extend.model_hr_holidays" />
<field name="auto_delete" eval="True" />
<field name="email_from">tictac@wikimedia.de</field>
<field name="email_to">${( object.employee_id.work_email or object.user_id != False and object.user_id.email )|safe},${( object.employee_id.parent_id.work_email)|safe},Personal@wikimedia.de</field>
<!--<field name="email_cc">${( object.employee_id.parent_id != False and object.employee_id.parent_id.work_email)|safe}</field>-->
<field name="email_cc"></field>
<field name="subject">Dein beantragter Urlaubsantrag (aus 2018) wurde genehmigt/Your requested holiday</field>
<field name="body_html"><![CDATA[
Liebe/r ${object.employee_id.surname},
<br><br>
wir informieren dich darüber, dass dein offener Urlaubsantrag für den ${ctx['date_from']} bis zum ${ctx['date_to']} automatisch aufgrund des Jahreswechsels
vom Status “Zu genehmigen” in den Status “Genehmigt” geändert wurde und der Urlaub damit freigegeben ist.
<br><br>
Viele Grüße
<br>
Dein TicTac Team
<br><br>---------<br><br>
Dear ${object.employee_id.surname},
<br><br>we kindly inform you that your pending holiday request from ${ctx['date_from']} until ${ctx['date_to']} was automatically changed
from “To Approve” in Status “Approved” due to year change.
<br><br>
For any questions please contact Team Personal.
<br>
Best Regards
<br>
Your TicTac Team
<br><br>
]]></field>
</record>
<record id="email_template_remaining_leave_notification" model="email.template">
<field name="name">Remaining Leave end Notification</field>
<field name="model_id" ref="itis_hr_extend.model_hr_employee" />
<field name="auto_delete" eval="True" />
<field name="email_from">tictac@wikimedia.de</field>
<field name="email_to">${( object.work_email or object.user_id != False and object.user_id.email )|safe},${( object.parent_id.work_email)|safe},Personal@wikimedia.de</field>
<!--<field name="email_cc">${( object.parent_id != False and object.parent_id.work_email)|safe}</field>-->
<field name="email_cc"></field>
<field name="subject">Benachrichtung über deinen Resturlaub/Information about your carried over holiday</field>
<field name="body_html"><![CDATA[
Liebe/r ${object.surname},
<br><br>
du hast ${ctx['remaining_leaves']} Tage Resturlaub aus dem Vorjahr ins neue Jahr übertragen.
<br>
Der Resturlaub muss bis 31. März genommen worden sein, ansonsten verfällt dieser zum 01. April.
<br><br>
Solltest du weitere Fragen haben, wende dich an das Team Personal.
<br>
Viele Grüße
<br>
Dein TicTac Team
<br><br>-------------------<br><br>
Dear ${object.surname},
<br><br>
we kindly inform you have transferred ${ctx['remaining_leaves']} days rest leave from the previous year into the new year.
<br>
These carried over days must have been taken until March 31st, otherwise it expires on the 1st of April.
<br><br>
For any questions please contact Team Personal.
<br>
Best Regards
<br>
Your TicTac Team
]]></field>
</record>
</data>
</openerp>

2024
itis_hr_extend/i18n/de.po Normal file

File diff suppressed because it is too large Load Diff

2023
itis_hr_extend/i18n/en_US.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from . import hr_employee
from . import hr_holiday
from . import fte_report
from . import hr_leave
from . import employee_report
from . import mail_message
from . import employee_meeting
from . import employee_payroll_report

View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
class employee_meeting(models.Model):
_name = 'employee.meeting'
_rec_name = 'meeting_date'
name = fields.Char(string="Name")
meeting_date = fields.Date(string="Meeting Date")
employee_id = fields.Many2one('hr.employee',string="Employee")
supervisor_id = fields.Many2one('hr.employee',string="Supervisor")
note = fields.Char(string="Meeting Notes")
class employee_instruction(models.Model):
_name = 'employee.instruction'
_rec_name = 'meeting_date'
name = fields.Char(string="Name")
meeting_date = fields.Date(string="Meeting Date")
employee_id = fields.Many2one('hr.employee',string="Employee")
supervisor_id = fields.Many2one('hr.employee',string="Supervisor")
note = fields.Char(string="Meeting Notes")

View File

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
from openerp.exceptions import Warning
class employee_payroll_report(models.TransientModel):
_name = 'employee.payroll.report'
@api.one
def _get_address(self):
if self.address_home:
self.address_home_id = unicode(self.address_home.name)
if self.address_home.street:
self.address_home_id += ' ' + unicode(self.address_home.street)
if self.address_home.zip:
self.address_home_id += ' ' + unicode(self.address_home.zip)
if self.address_home.city:
self.address_home_id += ' ' + unicode(self.address_home.city)
else:
self.address_home_id = ''
return
record_change = fields.Selection([('N','No Change'),('ST','Change Employee'),('V','Change Contract'),('SV','Change Employee Contract')],default='N',string='Change Record')
sick_days = fields.Float(string='Krankheitstage')
gross_salary = fields.Float(string='Brattogehalt')
address_home_id = fields.Char(string="Privatanschrift", compute="_get_address")
employee_id = fields.Many2one('hr.employee', string="Employee")
contract_id = fields.Many2one('hr.contract', string='Contract')
identification_id = fields.Char(related='employee_id.identification_id',string="Personal-Nr")
name = fields.Char(related='employee_id.second_name',string="Name")
surname = fields.Char(related='employee_id.surname',string="Vorname")
birthday = fields.Date(related='employee_id.birthday',string="Geburtsdatum")
address_home = fields.Many2one(related='employee_id.address_home_id',string="Privatanschrift")
address_id = fields.Many2one(related='employee_id.address_id',string="Arbeitgeber")
bank_account_id = fields.Many2one(related='employee_id.bank_account_id',string="Bankverbindung")
health_insurance = fields.Many2one(related='employee_id.health_insurance',string="Krankenkasse")
disability = fields.Selection(related='employee_id.disability',string="Schwerbehinderung")
disability_limited_until = fields.Date(related='employee_id.disability_limited_until',string="Schwerbehinderung Gültigkeit")
family_status = fields.Many2one(related='employee_id.family_status',string="Familienstand")
children = fields.Integer(related='employee_id.children',string="Anzahl Kinder")
contract_name = fields.Char(related='contract_id.name',string="Vertragsreferenz")
contract_start_date = fields.Date(related='contract_id.date_start',string="Vertragsbeginn")
contract_end_date = fields.Date(related='contract_id.date_end',string="Vertragsende")
working_hours = fields.Many2one(related='contract_id.working_hours',string="Arbeitszeit")
struct_id = fields.Many2one(related='contract_id.struct_id',string="Vergütungsmodell")
notes = fields.Text(related='contract_id.notes',string="Bemerkung Vertragsinformationen")
wage = fields.Float(string='Wage')

View File

@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
from openerp.exceptions import Warning
class employee_report(models.TransientModel):
_name = 'employee.report'
def _get_employee(self):
user_env = self.env['res.users']
emp_env = self.env['hr.employee']
emp_rec = emp_env.search([('user_id', '=', self._uid)])
if not len(emp_rec):
raise Warning(_("No associated employee found with user"))
if len(emp_rec) > 1:
raise Warning(_("User is associated with multiple employee"))
emp_rec = emp_rec[0]
emp_list = []
for emp in emp_env.search(['|', ('parent_id', '=', emp_rec.id), ('id', '=', emp_rec.id)]):
emp_val = {
'employee_id': emp.id,
'overtime_count':emp.employee_overtime_id.emp_overtime_count,
# 'overtime_count':emp.overtime_count,
'sum_leaves': emp.sum_leaves,
'sum_leaves_ny':emp.sum_leaves_ny #for SOW17
}
if emp_val['overtime_count'] <= 20 and emp_val['overtime_count'] >= -20:
color = "green"
elif emp_val['overtime_count'] <= 40 and emp_val['overtime_count'] >= -40:
color = "yellow"
else:
color = "red"
emp_val['color'] = color
emp_list.append((0, 0, emp_val))
return emp_list
name= fields.Date(string="Date", default=fields.Date.context_today)
employee_ids = fields.One2many('employee.report.data', 'employee_report_id', string='Employees', default=_get_employee)
class employee_report_data(models.TransientModel):
_name = 'employee.report.data'
employee_id = fields.Many2one('hr.employee', string='Employee')
overtime_count = fields.Float(string='Overtime Count')
sum_leaves = fields.Float(string='Gesamtanspruch')
sum_leaves_ny = fields.Float(string='Next Year Remaining Leaves')#for SOW17
employee_report_id = fields.Many2one('employee.report', string='Employee Report')
color = fields.Char()

View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
class fte_records(models.Model):
_name = 'fte.records'
department_id = fields.Many2one('hr.department', string="Department")
planned_fte = fields.Float(string='Planned FTE')
fte = fields.Float(string='FTE', digits=(5, 3))
diff_fte = fields.Float(string='Difference FTE', digits=(5, 3))
fte_id = fields.Many2one('fte.report', string="FTE Report")
class fte_report(models.Model):
_name = 'fte.report'
_order = 'id desc'
name = fields.Date(string="Date", default=fields.Date.context_today)
fte_ids = fields.One2many('fte.records', 'fte_id', string='FTE Records')
class res_company(models.Model):
_inherit = "res.company"
for_sow17 = fields.Boolean(string='Simulate date for leave calc')
next_year_date = fields.Date('Next Year Date')

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,662 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
from datetime import datetime, timedelta
from openerp.exceptions import Warning
from openerp import SUPERUSER_ID
from openerp import tools
from openerp.osv import osv
import math
class HRHoliday(models.Model):
_inherit = "hr.holidays"
is_ot_leave = fields.Boolean(string="Is OT Leave")
leave_hours = fields.Float(string="Leave Hours", compute='calc_leave_hours')
ot_hours = fields.Float(string="Overtime Count", compute="calc_ot_count")
sum_leaves = fields.Float(string="Gesamtanspruch", compute='calc_sum_leaves')
# for SOW17
sum_leaves_ny = fields.Float(string="Next Year Remaining Leaves", compute='calc_ny_sum_leaves')
number_of_days_temp_ny = fields.Float(string="Next Year Days", compute='calc_number_of_days_temp_ny')
approved_by = fields.Many2one("res.users", string='Approved/Refuse By')
approved_at = fields.Datetime(string="Approved/Refuse At")
ljournal_ids = fields.One2many("hr.leave.journal", "leave_id")
leave_selection = fields.Selection([('full_day','Full Day'),('half_day','Half Day')], string="Leave Selection",default="full_day")
leave_selection_date_to = fields.Selection([('full_day','Full Day'),('half_day','Half Day')], string="Leave Selection",default="full_day")
half_day_type = fields.Selection([('morning','Morning'),('afternoon','Afternoon')], string="Half Day Type")
half_day_type_date_to = fields.Selection([('morning','Morning'),('afternoon','Afternoon')], string="Half Day Type")
leave_sele_dateto_flag = fields.Boolean(string='Date to Flag')
def onchange_date_from(self, cr, uid, ids, date_to, date_from):
"""
If there are no date set for date_to, automatically set one 8 hours later than
the date_from.
"""
# date_to has to be greater than date_from
# if (date_from and date_to) and (date_from > date_to):
# raise osv.except_osv(_('Warning!'),_('The start date must be anterior to the end date.111'))
result = {'value': {}}
# No date_to set so far: automatically compute one 8 hours later
if date_from and not date_to:
date_to_with_delta = datetime.strptime(date_from, tools.DEFAULT_SERVER_DATETIME_FORMAT) + timedelta(hours=8)
result['value']['date_to'] = str(date_to_with_delta)
if date_from and date_to:
DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
from_dt = datetime.strptime(date_from, DATETIME_FORMAT).date()
to_dt = datetime.strptime(date_to, DATETIME_FORMAT).date()
if from_dt == to_dt:
result['value']['leave_sele_dateto_flag'] =True
else:
result['value']['leave_sele_dateto_flag'] =False
date_from = datetime.strptime(date_from,'%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d')+' 09:00:00'
date_to = datetime.strptime(date_to,'%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d')+' 18:00:00'
# Compute and update the number of days
if date_from <= date_to:
diff_day = self._get_number_of_days(date_from, date_to)
result['value']['number_of_days_temp'] = round(math.floor(diff_day))+1
else:
result['value']['number_of_days_temp'] = 0
else:
result['value']['number_of_days_temp'] = 0
return result
def onchange_date_to(self, cr, uid, ids, date_to, date_from):
"""
Update the number_of_days.
"""
# date_to has to be greater than date_from
# if (date_from and date_to) and (date_from > date_to):
# raise osv.except_osv(_('Warning!'),_('The start date must be anterior to the end date.'))
result = {'value': {}}
if date_from and date_to:
DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
from_dt = datetime.strptime(date_from, DATETIME_FORMAT).date()
to_dt = datetime.strptime(date_to, DATETIME_FORMAT).date()
if from_dt == to_dt:
result['value']['leave_sele_dateto_flag'] =True
else:
result['value']['leave_sele_dateto_flag'] =False
date_from = datetime.strptime(date_from,'%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d')+' 09:00:00'
date_to = datetime.strptime(date_to,'%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d')+' 18:00:00'
# Compute and update the number of days
if date_from <= date_to:
diff_day = self._get_number_of_days(date_from, date_to)
result['value']['number_of_days_temp'] = round(math.floor(diff_day))+1
else:
result['value']['number_of_days_temp'] = 0
else:
result['value']['number_of_days_temp'] = 0
return result
def check_holidays(self, cr, uid, ids, context=None):
return True
def check_holidays2(self, cr, uid, ids, context=None):
for record in self.browse(cr, uid, ids, context=context):
if record.holiday_type != 'employee' or record.type != 'remove' or not record.employee_id or record.holiday_status_id.limit:
continue
if record.is_ot_leave:
continue
# if record.sum_leaves < record.number_of_days_temp:
# for SOW17
year = datetime.today().year
#for SOW17 testing
for_sow17 = self.pool.get('res.company').search(cr, uid,[('for_sow17','=',True)],limit=1)
if for_sow17:
for_sow17 = self.pool.get('res.company').browse(cr,uid,for_sow17)
year = datetime.strptime(for_sow17.next_year_date,DEFAULT_SERVER_DATE_FORMAT).date().year
next_year = year+1
date_from_year = datetime.strptime(record.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year
date_to_year = datetime.strptime(record.date_to.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year
#warning for the same year leave
if date_from_year != date_to_year:
raise Warning(_("Please create a leave request for every year."))
if date_from_year == next_year+1:
raise Warning(_('You are not allow to apply leave for the year after next'))
#warning when user didn't have next year contact or next year vacation
if date_from_year == next_year and record.sum_leaves_ny==0.0:
raise Warning(_('The number of next year remaining leaves is not sufficient for this leave type.\n'
'Please verify also the leaves waiting for validation.'))
if record.number_of_days_temp_ny==0.0:#for current year warning
if record.sum_leaves < record.number_of_days_temp:
# Raising a warning gives a more user-friendly feedback than the default constraint error
raise Warning(_('The number of remaining leaves is not sufficient for this leave type.\n'
'Please verify also the leaves waiting for validation.'))
else:#next year warning
if record.sum_leaves_ny < record.number_of_days_temp_ny:
raise Warning(_('The number of next year remaining leaves is not sufficient for this leave type.\n'
'Please verify also the leaves waiting for validation.'))
return True
def _check_date(self, cr, uid, ids, context=None):
for holiday in self.browse(cr, uid, ids, context=context):
domain = [
('date_from', '<=', holiday.date_to),
('date_to', '>=', holiday.date_from),
('employee_id', '=', holiday.employee_id.id),
('id', '!=', holiday.id),
('state', 'not in', ['cancel', 'refuse']),
('holiday_status_id','!=','Holiday')
]
nholidays = self.search_count(cr, uid, domain, context=context)
if nholidays:
return False
return True
_constraints = [
(_check_date, 'You can not have 2 leaves that overlaps on same day!', ['date_from','date_to'])
]
def write(self, cr, uid, ids, values, context=None):
if not context: context = {}
grp_hr_rec = self.pool.get("ir.model.data").xmlid_to_object(cr, SUPERUSER_ID, "base.group_hr_user")
hr_usr_id = False
if 'date_from' in values or 'date_to' in values:
self.check_holidays2(cr,uid,ids,context=context)
for usr in grp_hr_rec.users:
hr_usr_id = usr.id
break
if not hr_usr_id:
hr_usr_id = SUPERUSER_ID
context.update({'hr_uid':uid})
return super(HRHoliday, self).write(cr, hr_usr_id, ids, values, context=context)
@api.multi
@api.onchange("employee_id")
@api.depends("employee_id")
def calc_sum_leaves(self):
for record in self:
record.sum_leaves = record.employee_id.sum_leaves
# for SOW17
@api.multi
@api.onchange("employee_id")
@api.depends("employee_id")
def calc_ny_sum_leaves(self):
for record in self:
record.sum_leaves_ny = record.employee_id.sum_leaves_ny
return {}
@api.onchange("number_of_days_temp")
@api.depends("number_of_days_temp")
def calc_number_of_days_temp_ny(self):
for record in self:
res = 0
if not record.date_from or not record.date_to:
return {}
date_from = datetime.strptime(record.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
date_to = datetime.strptime(record.date_to.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
today_date = datetime.today().date()
# for sow17 testing
for_sow17 = self.env['res.company'].sudo().search([('for_sow17','=',True)],limit=1)
if for_sow17:
today_date = datetime.strptime(for_sow17.next_year_date,DEFAULT_SERVER_DATE_FORMAT).date()
temp_date = date_from
while temp_date <= date_to:
holiday = None
holiday = self.env['itis.holiday'].search([('date', '=', temp_date)])
if holiday:
temp_date += timedelta(days=1)
continue
if today_date.year == temp_date.year:
temp_date += timedelta(days=1)
continue
weekday = temp_date.weekday()
for contract in record.employee_id.contract_ids:
cont_start_date = datetime.strptime(contract.date_start, DEFAULT_SERVER_DATE_FORMAT)
cont_end_date = False
if not contract.date_end:
if cont_start_date <= temp_date:
if record.get_hours(weekday, contract.working_hours.attendance_ids) > 0.0:
if temp_date == date_from and record.leave_selection =='half_day':
res += 0.5
break
if temp_date == date_to and record.leave_selection_date_to =='half_day':
res += 0.5
break
res += 1
else:
cont_end_date = datetime.strptime(contract.date_end, DEFAULT_SERVER_DATE_FORMAT)
# cont_end_date += timedelta(days=1)
if cont_start_date <= temp_date and cont_end_date >= temp_date:
if record.get_hours(weekday, contract.working_hours.attendance_ids) > 0.0:
if temp_date == date_from and record.leave_selection =='half_day':
res += 0.5
break
if temp_date == date_to and record.leave_selection_date_to =='half_day':
res += 0.5
break
res += 1
temp_date += timedelta(days=1)
record.number_of_days_temp_ny = res
#END
@api.multi
@api.onchange("employee_id")
@api.depends("employee_id")
def calc_ot_count(self):
for record in self:
# self.ot_hours = self.employee_id.overtime_count
record.ot_hours = record.employee_id.employee_overtime_id.emp_overtime_count
return {}
@api.multi
def holidays_refuse(self):
if self.env.user.id != self.employee_id.parent_id.user_id.id:
raise Warning(_('Only the Manager of this employee can approve this leave request.'))
if self.is_ot_leave:
if self.state in ['validate', 'validate1']:
new_ot = self.ot_hours + self.leave_hours
# self.employee_id.sudo().write({'overtime_count': new_ot})
self.employee_id.sudo().employee_overtime_id.write({'emp_overtime_count': new_ot})
self.write({"approved_by": self.env.user.id, 'approved_at': datetime.strftime(datetime.today(), DEFAULT_SERVER_DATETIME_FORMAT)})
for leave_journal_entry in self.ljournal_ids:
leave_journal_entry.unlink()
nextyear_leave_data = self.env['hr.leave.nextyear'].search([('holiday_id','=',self.id),('employee_id','=',self.employee_id.id)])
print'nextyear_leave_data------',nextyear_leave_data
if nextyear_leave_data:
nextyear_leave_data.unlink()
return super(HRHoliday, self).holidays_refuse()
def holidays_validate_old(self, cr, uid, ids, context=None):
obj_emp = self.pool.get('hr.employee')
ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)])
manager = ids2 and ids2[0] or False
self.write(cr, uid, ids, {'state':'validate'})
data_holiday = self.browse(cr, uid, ids)
for record in data_holiday:
if record.double_validation:
self.write(cr, uid, [record.id], {'manager_id2': manager})
else:
self.write(cr, uid, [record.id], {'manager_id': manager})
if record.holiday_type == 'employee' and record.type == 'remove':
meeting_obj = self.pool.get('calendar.event')
# to check for the existing calender events for this type
if record.meeting_id:
self._create_resource_leave(cr, uid, [record], context=context)
meeting_obj.write(cr, uid, record.meeting_id, {'name': record.name or _('Leave Request'),})
else:
meeting_vals = {
'name': record.name or _('Leave Request'),
'categ_ids': record.holiday_status_id.categ_id and [(6,0,[record.holiday_status_id.categ_id.id])] or [],
'duration': record.number_of_days_temp * 8,
'description': record.notes,
'user_id': record.user_id.id,
'start': record.date_from,
'stop': record.date_to,
'allday': False,
'state': 'open', # to block that meeting date in the calendar
'class': 'confidential'
}
#Add the partner_id (if exist) as an attendee
if record.user_id and record.user_id.partner_id:
meeting_vals['partner_ids'] = [(4,record.user_id.partner_id.id)]
ctx_no_email = dict(context or {}, no_email=True)
meeting_id = meeting_obj.create(cr, uid, meeting_vals, context=ctx_no_email)
self._create_resource_leave(cr, uid, [record], context=context)
self.write(cr, uid, ids, {'meeting_id': meeting_id})
elif record.holiday_type == 'category':
emp_ids = obj_emp.search(cr, uid, [('category_ids', 'child_of', [record.category_id.id])])
leave_ids = []
batch_context = dict(context, mail_notify_force_send=False)
for emp in obj_emp.browse(cr, uid, emp_ids, context=context):
vals = {
'name': record.name,
'type': record.type,
'holiday_type': 'employee',
'holiday_status_id': record.holiday_status_id.id,
'date_from': record.date_from,
'date_to': record.date_to,
'notes': record.notes,
'number_of_days_temp': record.number_of_days_temp,
'parent_id': record.id,
'employee_id': emp.id
}
leave_ids.append(self.create(cr, uid, vals, context=batch_context))
for leave_id in leave_ids:
# TODO is it necessary to interleave the calls?
for sig in ('confirm', 'validate', 'second_validate'):
self.signal_workflow(cr, uid, [leave_id], sig)
return True
@api.multi
def holidays_validate(self):
for record in self:
if self.env.user.id != record.employee_id.parent_id.user_id.id:
raise Warning(_('Only the Manager of this employee can approve this leave request.'))
if record.is_ot_leave:
# commented function customer wants to approve leaves to actual ot_count.
# User can have positive actual ot count at the end of the month, although the ot_count at employee is negative,
# because it is updated one time a month only.
# if self.ot_hours < self.leave_hours:
# raise Warning(_('The number of overtime count is not sufficient for Overtime leave.'))
new_ot = record.ot_hours - record.leave_hours
# self.employee_id.sudo().write({'overtime_count': new_ot})
record.employee_id.sudo().employee_overtime_id.write({'emp_overtime_count': new_ot})
self.check_holidays2()
self.create_leave_journal_entry()
self.create_nextyear_leave_entry() #new added.to store the leave data for the next year which will be use for main dec scheduler
self.write({"approved_by": self.env.user.id, 'approved_at': datetime.strftime(datetime.today(), DEFAULT_SERVER_DATETIME_FORMAT)})
return self.holidays_validate_old()
def create_nextyear_leave_entry(self):
"""new added.to store the leave data for the next year which will be use for main dec scheduler
"""
for record in self:
year = datetime.today().year
# for sow17 testing
for_sow17 = self.env['res.company'].sudo().search([('for_sow17','=',True)],limit=1)
if for_sow17:
year = datetime.strptime(for_sow17.next_year_date,DEFAULT_SERVER_DATE_FORMAT).date().year
next_year = year+1
date_from = datetime.strptime(record.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
date_to = datetime.strptime(record.date_to.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
if date_from.year == next_year:
date_data_dict = record.get_date_data(date_from,date_to)
# print"date_data_dict------",date_data_dict
for date, day_amt in date_data_dict.iteritems():
nextyear_leave_vals={'date':date,'leave_days':day_amt,'employee_id':record.employee_id.id,'holiday_id':record.id}
self.env['hr.leave.nextyear'].create(nextyear_leave_vals)
def get_date_data(self,date_from,date_to):
"""Subfunction of the above function(create_nextyear_leave_entry)"""
today_date = datetime.today().date()
temp_date = date_from
date_data_dict={}
while temp_date <= date_to:
holiday = None
holiday = self.env['itis.holiday'].search([('date', '=', temp_date)])
if holiday:
temp_date += timedelta(days=1)
continue
if today_date.year == temp_date.year:
temp_date += timedelta(days=1)
continue
weekday = temp_date.weekday()
for contract in self.employee_id.contract_ids:
cont_start_date = datetime.strptime(contract.date_start, DEFAULT_SERVER_DATE_FORMAT)
cont_end_date = False
if not contract.date_end:
if cont_start_date <= temp_date:
if self.get_hours(weekday, contract.working_hours.attendance_ids) > 0.0:
if temp_date == date_from and self.leave_selection =='half_day':
date_data_dict[temp_date] =0.5
break
if temp_date == date_to and self.leave_selection_date_to =='half_day':
date_data_dict[temp_date] =0.5
break
date_data_dict[temp_date] =1
else:
cont_end_date = datetime.strptime(contract.date_end, DEFAULT_SERVER_DATE_FORMAT)
# cont_end_date += timedelta(days=1)
if cont_start_date <= temp_date and cont_end_date >= temp_date:
if self.get_hours(weekday, contract.working_hours.attendance_ids) > 0.0:
if temp_date == date_from and self.leave_selection =='half_day':
date_data_dict[temp_date] =0.5
break
if temp_date == date_to and self.leave_selection_date_to =='half_day':
date_data_dict[temp_date] =0.5
break
date_data_dict[temp_date] =1
temp_date += timedelta(days=1)
return date_data_dict
def check_same_day(self, date_from, date_to):
return date_from.date() == date_to.date()
@api.depends("date_from", "date_to", 'is_ot_leave', 'leave_selection', 'leave_selection_date_to')
def calc_leave_hours(self):
for record in self:
if not record.is_ot_leave:
return True
if not record.date_from or not record.date_to:
return True
date_from = datetime.strptime(record.date_from, DEFAULT_SERVER_DATETIME_FORMAT)
date_to = datetime.strptime(record.date_to, DEFAULT_SERVER_DATETIME_FORMAT)
same_day = record.check_same_day(date_from, date_to)
temp_date = date_from
day_hours = 0.0
date_from = datetime.strptime(record.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
date_to = datetime.strptime(record.date_to.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
temp_date = date_from
#temp_date += timedelta(days=1)
while temp_date <= date_to:
holiday = self.env['itis.holiday'].search([('date', '=', temp_date)])
if holiday:
temp_date += timedelta(days=1)
continue
weekday = temp_date.weekday()
for contract in record.employee_id.contract_ids:
cont_start_date = datetime.strptime(contract.date_start, DEFAULT_SERVER_DATE_FORMAT)
cont_end_date = False
if not contract.date_end:
if cont_start_date <= temp_date:
if (temp_date==date_from and record.leave_selection == 'half_day') or (temp_date.date()==date_from.date() and record.leave_selection_date_to == 'half_day'):
day_hours += record.get_hours(weekday, contract.working_hours.attendance_ids)/2
else:
day_hours += record.get_hours(weekday, contract.working_hours.attendance_ids)
else:
cont_end_date = datetime.strptime(contract.date_end, DEFAULT_SERVER_DATE_FORMAT)
if cont_start_date <= temp_date and cont_end_date >= temp_date:
if (temp_date==date_from and record.leave_selection == 'half_day') or (temp_date.date()==date_from.date() and record.leave_selection_date_to == 'half_day'):
day_hours += record.get_hours(weekday, contract.working_hours.attendance_ids)/2
else:
day_hours += record.get_hours(weekday, contract.working_hours.attendance_ids)
temp_date += timedelta(days=1)
# print"day_hours-----",day_hours
record.leave_hours = day_hours
return True
def get_day_hours(self, date_from, atten_ids):
weekday = date_from.weekday()
res = self.get_hours(weekday, atten_ids)
return res
def get_hours(self, weekday, atten_ids):
res = 0.0
for atten in atten_ids:
if int(atten.dayofweek) == weekday:
res += atten.hour_to - atten.hour_from
return res
@api.onchange("holiday_status_id")
def onchange_holiday_status_id(self):
ot_leave_rec = self.env['ir.model.data'].xmlid_to_object('itis_hr_extend.itis_leave_overtime')
if ot_leave_rec.id == self.holiday_status_id.id:
self.is_ot_leave = True
else:
self.is_ot_leave = False
return {}
#for SOW17, Made some changes in existing function
def create_leave_journal_entry(self):
leave_journal_obj = self.env['hr.leave.journal']
if self.is_ot_leave:
leave_type = 'hours'
year = datetime.strptime(self.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year
if year != datetime.strptime(self.date_to.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year:
raise Warning(_("Please create a leave request for every year."))
values = {
'year': year,
'year_type': 'actual',
'type': 'leave',
'leave_type': leave_type,
'leave_days': self.number_of_days_temp,
'leave_hours': self.leave_hours,
'name': self.name,
'employee_id': self.employee_id.id,
'leave_start': self.date_from,
'leave_end': self.date_to,
'leave_id': self.id
}
ljournal_id = leave_journal_obj.create(values)
else:
leave_type = 'days'
year = datetime.strptime(self.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year
if year != datetime.strptime(self.date_to.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year:
raise Warning(_("Please create a leave request for every year."))
if self.number_of_days_temp_ny ==0.0: #when leave is apply for the current ongoing year
yeartype = self.get_year_type()
print"yeartype------",yeartype
if len(yeartype)==2 or len(yeartype)==4:
leave_days = yeartype[1]
values = {
'year': year,
'year_type': yeartype[0],
'type': 'leave',
'leave_type': leave_type,
'leave_days': leave_days,
'name': self.name,
'employee_id': self.employee_id.id,
'leave_id': self.id
}
leave_journal_obj.create(values)
if len(yeartype)==4:
leave_days = yeartype[3]
values = {
'year': year,
'year_type': yeartype[2],
'type': 'leave',
'leave_type': leave_type,
'leave_days': leave_days,
'name': self.name,
'employee_id': self.employee_id.id,
'leave_id': self.id
}
leave_journal_obj.create(values)
else:#when there is next year leave in current year
#------create an next leave for the next year----#
c_year = datetime.today().date().year
values = {
'year': c_year+1,
'year_type': 'next',
'type': 'leave',
'leave_type': leave_type,
'leave_days': self.number_of_days_temp_ny,
'name': self.name,
'employee_id': self.employee_id.id,
'leave_id': self.id
}
leave_journal_obj.create(values)
def get_year_type(self):
if datetime.strptime(self.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT) >= datetime.strptime('01-04-'+str(datetime.strptime(self.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year),'%d-%m-%Y'):
return ['actual',self.number_of_days_temp]
elif datetime.strptime(self.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT) <= datetime.strptime('31-03-'+str(datetime.strptime(self.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year),'%d-%m-%Y'):
if self.employee_id.leave_days_last_year >= self.number_of_days_temp:
return ['last',self.number_of_days_temp]
elif self.employee_id.leave_days_last_year > 0:
return ['last', self.employee_id.leave_days_last_year,'actual',self.number_of_days_temp-self.employee_id.leave_days_last_year]
else:
return ['actual',self.number_of_days_temp]
# for SOW17 commented this
# def create_leave_journal_entry(self):
# leave_journal_obj = self.env['hr.leave.journal']
#
# if self.is_ot_leave:
# leave_type = 'hours'
# year = datetime.strptime(self.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year
# if year != datetime.strptime(self.date_to.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year:
# raise Warning(_("Please create a leave request for every year."))
#
# values = {
# 'year': year,
# 'year_type': 'actual',
# 'type': 'leave',
# 'leave_type': leave_type,
# 'leave_days': self.number_of_days_temp,
# 'leave_hours': self.leave_hours,
# 'name': self.name,
# 'employee_id': self.employee_id.id,
# 'leave_start': self.date_from,
# 'leave_end': self.date_to,
# 'leave_id': self.id
# }
# ljournal_id = leave_journal_obj.create(values)
# else:
# leave_type = 'days'
# year = datetime.strptime(self.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year
# if year != datetime.strptime(self.date_to.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year:
# raise Warning(_("Please create a leave request for every year."))
# yeartype = self.get_year_type()
# if len(yeartype)==2 or len(yeartype)==4:
# leave_days = yeartype[1]
# values = {
# 'year': year,
# 'year_type': yeartype[0],
# 'type': 'leave',
# 'leave_type': leave_type,
# 'leave_days': leave_days,
# 'name': self.name,
# 'employee_id': self.employee_id.id,
# 'leave_id': self.id
# }
# leave_journal_obj.create(values)
#
# if len(yeartype)==4:
# leave_days = yeartype[3]
# values = {
# 'year': year,
# 'year_type': yeartype[2],
# 'type': 'leave',
# 'leave_type': leave_type,
# 'leave_days': leave_days,
# 'name': self.name,
# 'employee_id': self.employee_id.id,
# 'leave_id': self.id
# }
# leave_journal_obj.create(values)

View File

@ -0,0 +1,406 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
from openerp.tools import float_round
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
from datetime import datetime, timedelta
from calendar import monthrange
from openerp.exceptions import Warning
import pdb
class HRHolidayStatus(models.Model):
_inherit = "hr.holidays.status"
is_holiday = fields.Boolean(string='Is holiday Type')
is_sick_leave_type = fields.Boolean(string='Is Sick Leave Type')
class HRLeaveNextYear(models.Model):
_name = "hr.leave.nextyear"
date = fields.Date('Date')
holiday_id = fields.Many2one("hr.holidays", "Holiday")
employee_id = fields.Many2one('hr.employee')
leave_days = fields.Float('Tage')
class HRLeaveJournal(models.Model):
_name = "hr.leave.journal"
_order = "year desc"
name = fields.Char("Begründung")
employee_id = fields.Many2one('hr.employee')
year = fields.Integer('Jahr')
# year_type = fields.Selection([('actual','aktuell'),('last','Restanspruch')])
#added for the SOW17
year_type = fields.Selection([('actual','aktuell'),('last','Restanspruch'),('next','next')])
type = fields.Selection([('calculate','Vertraglich'),('leave','Ausgleich'),('manual','Manuell'),('additional','Zusatzurlaub')])
leave_type = fields.Selection([('days','Tage'),('hours','Stunden')])
leave_start = fields.Date('von')
leave_end = fields.Date('bis')
leave_days = fields.Float('Tage')
leave_hours = fields.Float('Stunden')
description = fields.Char('Begründung')
contract_id = fields.Many2one('hr.contract')
last_year_carry_fwd = fields.Boolean('Last Year Carry Fwd Info')
leave_id = fields.Many2one('hr.holidays')
class HREmployee(models.Model):
_inherit = "hr.employee"
leave_days = fields.Float('Urlaubstage', compute="calculate_actual_year_leave_days")
leave_days_last_year = fields.Float('Resturlaub', compute="calculate_last_year_leave_days")
additional_leave_days = fields.Float('Zusatzurlaub', compute="calculate_additional_leave_days")
sum_leaves = fields.Float('Gesamtanspruch', compute="_calculate_sum_leaves")
sum_journal_entries = fields.Integer('Anzahl Journaleinträge', compute="_calculate_sum_journal_entries")
leave_journal_ids = fields.One2many('hr.leave.journal','employee_id')
approved_leaves = fields.Float('abgegoltene Urlaubstage', compute="_calculate_approved_leave_days")
#added new field for the following year june1st SOW17
leave_days_ny = fields.Float('Leaves Following Year', compute="calculate_nextyear_leave_days")
additional_leave_days_ny = fields.Float('Addtional Leaves Following Year', compute="calculate_nextyear_additional_leave_days")
approved_leaves_ny = fields.Float('Approve Leaves Following Year', compute="_calculate_nextyear_approved_leave_days")
sum_leaves_ny = fields.Float('Remaining Leaves Following Year', compute="_calculate_nextyear_sum_leaves")
#added to maintain data for next year so it will be use for dec scheduler
nextyear_leave_ids = fields.One2many('hr.leave.nextyear','employee_id')
approved_leaves_till_march_ny = fields.Float('Approve Leaves Till March', compute="_calculate_nextyear_approved_leave_days_march")
approved_leaves_after_march_ny = fields.Float('Approve Leaves After March', compute="_calculate_nextyear_approved_leave_days_aft_march")
#added field to display remaining leaves of last year based on journal entries from that year
last_year_remaining_leaves = fields.Float('Resturlaub Vorjahr (Zum Jahreswechsel)', compute="calculate_last_year_remaining_leaves")
@api.one
def _calculate_nextyear_approved_leave_days_march(self):
leave_days = 0
next_year = datetime.today().year+1
period_date_start = datetime.strptime('01-01-'+str(next_year),'%d-%m-%Y').date()
period_date_end = datetime.strptime('01-04-'+str(next_year),'%d-%m-%Y').date()
for nextyear_leave in self.nextyear_leave_ids:
leave_date = datetime.strptime(nextyear_leave.date,DEFAULT_SERVER_DATE_FORMAT).date()
if leave_date >=period_date_start and leave_date < period_date_end:
leave_days +=nextyear_leave.leave_days
self.approved_leaves_till_march_ny = leave_days
@api.one
def _calculate_nextyear_approved_leave_days_aft_march(self):
leave_days = 0
next_year = datetime.today().year+1
period_date_start = datetime.strptime('01-04-'+str(next_year),'%d-%m-%Y').date()
period_date_end = datetime.strptime('31-12-'+str(next_year),'%d-%m-%Y').date()
for nextyear_leave in self.nextyear_leave_ids:
leave_date = datetime.strptime(nextyear_leave.date,DEFAULT_SERVER_DATE_FORMAT).date()
if leave_date >=period_date_start and leave_date <= period_date_end:
leave_days +=nextyear_leave.leave_days
self.approved_leaves_after_march_ny = leave_days
#added new functions for the following year june1st SOW17
@api.one
def calculate_nextyear_leave_days(self):
today_date = datetime.today().date()
# for sow17
for_sow17 = self.env['res.company'].sudo().search([('for_sow17','=',True)],limit=1)
if for_sow17:
today_date = datetime.strptime(for_sow17.next_year_date,DEFAULT_SERVER_DATE_FORMAT).date()
leave_days = 0
for leave_id in self.leave_journal_ids:
if leave_id.year_type =='next':# condtion to check year type as next
period_date_start = datetime.strptime('01-06-'+str(leave_id.year-1),'%d-%m-%Y').date()
period_date_end = datetime.strptime('01-01-'+str(leave_id.year),'%d-%m-%Y').date()
if today_date >=period_date_start and today_date < period_date_end:
# condition to display value from 01-06-2018 to 03-01-2019,
# when june scheduler run, this value will display again from june to next jan date
if leave_id.type == 'calculate' or leave_id.type == 'manual':
leave_days += leave_id.leave_days
self.leave_days_ny = leave_days
return
@api.one
def calculate_nextyear_additional_leave_days(self):
today_date = datetime.today().date()
# for sow17
for_sow17 = self.env['res.company'].sudo().search([('for_sow17','=',True)],limit=1)
if for_sow17:
today_date = datetime.strptime(for_sow17.next_year_date,DEFAULT_SERVER_DATE_FORMAT).date()
leave_days = 0
for leave_id in self.leave_journal_ids:
if leave_id.year_type =='next':
period_date_start = datetime.strptime('01-06-'+str(leave_id.year-1),'%d-%m-%Y').date()
period_date_end = datetime.strptime('01-01-'+str(leave_id.year),'%d-%m-%Y').date()
if today_date >=period_date_start and today_date < period_date_end:
# condition to display value from 01-06-2018 to 03-01-2019,
# when june scheduler run, this value will display again from june to next jan date
if leave_id.type == 'additional':
leave_days += leave_id.leave_days
self.additional_leave_days_ny = leave_days
@api.one
def _calculate_nextyear_approved_leave_days(self):
today_date = datetime.today().date()
# for sow17 testing
for_sow17 = self.env['res.company'].sudo().search([('for_sow17','=',True)],limit=1)
if for_sow17:
today_date = datetime.strptime(for_sow17.next_year_date,DEFAULT_SERVER_DATE_FORMAT).date()
leave_days = 0
for leave_id in self.leave_journal_ids:
if leave_id.year_type =='next':
period_date_start = datetime.strptime('01-06-'+str(leave_id.year-1),'%d-%m-%Y').date()
period_date_end = datetime.strptime('01-01-'+str(leave_id.year),'%d-%m-%Y').date()
if today_date >=period_date_start and today_date < period_date_end:
# condition to display value from 01-06-2018 to 03-01-2019,
# when june scheduler run, this value will display again from june to next jan date
if leave_id.type == 'leave' and leave_id.leave_type == 'days':
leave_days += leave_id.leave_days
self.approved_leaves_ny = leave_days
@api.one
def _calculate_nextyear_sum_leaves(self):
sum_leaves = self.leave_days_ny + self.additional_leave_days_ny - self.approved_leaves_ny
self.sum_leaves_ny = sum_leaves
return
#----END----#
@api.one
def _calculate_sum_leaves(self):
sum_leaves = self.leave_days + self.leave_days_last_year + self.additional_leave_days - self.approved_leaves
self.sum_leaves = sum_leaves
return
@api.one
def _calculate_sum_journal_entries(self):
journal_entry_ids = self.env['hr.leave.journal'].search([('employee_id.id','=',self.id),('year','=',datetime.today().year)])
self.sum_journal_entries = len(journal_entry_ids)
@api.one
def calculate_actual_year_leave_days(self):
year = datetime.today().year
# for sow17 testing
for_sow17 = self.env['res.company'].search([('for_sow17','=',True)],limit=1)
if for_sow17:
year = datetime.strptime(for_sow17.next_year_date,DEFAULT_SERVER_DATE_FORMAT).date().year
leave_days = 0
for leave_id in self.leave_journal_ids:
if leave_id.year != year or leave_id.year_type != 'actual':
continue
else:
if leave_id.type == 'calculate':
leave_days += leave_id.leave_days
elif leave_id.type == 'manual':
leave_days += leave_id.leave_days
self.leave_days = leave_days
return
@api.one
def calculate_last_year_leave_days(self):
month = datetime.today().month
year = datetime.today().year
# for sow17 testing
for_sow17 = self.env['res.company'].sudo().search([('for_sow17','=',True)],limit=1)
if for_sow17:
year = datetime.strptime(for_sow17.next_year_date,DEFAULT_SERVER_DATE_FORMAT).date().year
month = datetime.strptime(for_sow17.next_year_date,DEFAULT_SERVER_DATE_FORMAT).date().month
if month > 3:
self.leave_days_last_year = 0
return
leave_days = 0
for leave_id in self.leave_journal_ids:
if leave_id.year != year or leave_id.year_type != 'last' or leave_id.type == 'manual':
continue
else:
if leave_id.type == 'calculate':
leave_days += leave_id.leave_days
elif leave_id.type == 'leave':
leave_days -= leave_id.leave_days
self.leave_days_last_year = leave_days
return
@api.one
def calculate_additional_leave_days(self):
year = datetime.today().year
# for sow17 testing
for_sow17 = self.env['res.company'].sudo().search([('for_sow17','=',True)],limit=1)
if for_sow17:
year = datetime.strptime(for_sow17.next_year_date,DEFAULT_SERVER_DATE_FORMAT).date().year
leave_days = 0
for leave_id in self.leave_journal_ids:
if leave_id.year != year or leave_id.year_type != 'actual':
continue
else:
if leave_id.type == 'additional':
leave_days += leave_id.leave_days
self.additional_leave_days = leave_days
return
@api.one
def _calculate_approved_leave_days(self):
year = datetime.today().year
# for sow17 testing
for_sow17 = self.env['res.company'].sudo().search([('for_sow17','=',True)],limit=1)
if for_sow17:
year = datetime.strptime(for_sow17.next_year_date,DEFAULT_SERVER_DATE_FORMAT).date().year
leave_days = 0
for leave_id in self.leave_journal_ids:
# if leave_id.year != year or leave_id.year_type != 'actual':#original
if leave_id.year != year or leave_id.year_type != 'actual' or leave_id.last_year_carry_fwd: #for sow17 testing
continue
else:
if leave_id.type == 'leave' and leave_id.leave_type == 'days':
leave_days += leave_id.leave_days
self.approved_leaves = leave_days
return
# Function to calculate remaining leaves for last year for information purposes
@api.one
def calculate_last_year_remaining_leaves(self):
year = datetime.today().year-1
#print"Last Year: ",year
leaves_ly = 0
for leave_id in self.leave_journal_ids:
if leave_id.year == year and leave_id.year_type == 'actual' and not leave_id.last_year_carry_fwd:
if leave_id.type in ['calculate', 'manual', 'additional']:
leaves_ly += leave_id.leave_days
elif leave_id.type == 'leave' and leave_id.leave_type == 'days':
leaves_ly -= leave_id.leave_days
#print"leaves_ly =====> ", leaves_ly
self.last_year_remaining_leaves = leaves_ly
return
class HRContract(models.Model):
_inherit = "hr.contract"
def create(self, cr, uid, values, context=None):
new_id = super(HRContract, self).create(cr, uid, values, context=context)
new_rec = self.browse(cr,uid,new_id, context=context)
contract_ids = self.pool.get('hr.leave.journal').search(cr, uid, [('employee_id','=', new_rec.employee_id.id),('type','=','calculate'), ('year_type','=','actual'),('year','=', datetime.today().year)])
if len(contract_ids) == 0:
self.create_leave_journal_entries(cr,uid,new_id,values)
return new_id
@api.one
def create_leave_journal_entries(self,values):
leave_journal_obj = self.env['hr.leave.journal']
leave_days = self.calculate_leave_days(values)
lj_values = {
'employee_id': self.employee_id.id,
'year': datetime.today().year,
'year_type': 'actual',
'type': 'calculate',
'leave_type':'days',
'leave_days': leave_days[0],
'name': 'Vertragsanpassung' + str(datetime.today().date()),
'contract_id': self.id
}
leave_journal_obj.create(lj_values)
return
@api.one
def calculate_leave_days(self,values=None,cyear=None):
leave_days = 0
if not values:
values={}
if not cyear:
cyear = datetime.today().year
date_start = self.date_start
date_end = self.date_end
base_leaves = self.base_leaves
if 'date_start' in values:
date_start = values['date_start']
if 'date_end' in values:
date_end = values['date_end']
if 'base_leaves' in values:
base_leaves = values['base_leaves']
if datetime.strptime(date_start.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year < cyear:
if not date_end:
leave_days = base_leaves
elif datetime.strptime(date_end.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year > cyear:
leave_days = base_leaves
# elif datetime.strptime(date_end.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT) >= datetime.strptime('01-07-'+str(cyear),'%d-%m-%Y'):
# leave_days = base_leaves
else:
st = datetime.strptime('01-01-'+str(cyear),'%d-%m-%Y')
leave_days = self.calculate_partial_year(st, datetime.strptime(date_end.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT), base_leaves)[0]
elif datetime.strptime(date_start.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year == cyear:
if not self.date_end:
date_end = datetime.strptime('31-12-'+str(cyear),'%d-%m-%Y')
else:
if datetime.strptime(date_end.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year > cyear:
date_end = datetime.strptime('31-12-'+str(cyear),'%d-%m-%Y')
elif datetime.strptime(date_end.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT).year == cyear:
date_end = datetime.strptime(date_end.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
# Contract starts on 01.01, duration is full year so no need to call calculate_partial_year
ds = datetime.strptime(date_start.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
de = date_end
#print"date_start: ",ds.year,ds.month,ds.day
#print"date_end: ",de.year,de.month,de.day
if ds.year == cyear and ds.month == 1 and ds.day == 1 and de.year == cyear and de.month == 12 and de.day == 31:
leave_days = base_leaves
else:
leave_days = self.calculate_partial_year(datetime.strptime(date_start.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT), date_end, base_leaves)[0]
return leave_days
@api.one
def calculate_partial_year(self,date_start,date_end,base_leaves):
date_start_calc = date_start
date_end_calc = date_end
if date_start.day != 1 or date_start.month != 1:
date_start_calc = date_start + timedelta(days=-1)
elif date_end.day != 31 or date_end.month != 12:
date_end_calc = date_end + timedelta(days=1)
# else:
# return base_leaves
full_month = date_end_calc.month - date_start_calc.month
if date_end.day != monthrange(date_end.year, date_end.month)[1] and date_start.day != monthrange(date_start.year, date_start.month)[1]:
if date_end.day <= date_start.day:
full_month -= 1
# if full_month >= 6 and date_end.day >= date_start.day:
# leave_days = base_leaves
# else:
# leave_days = float_round(full_month * float(base_leaves) / 12, precision_rounding = 1)
leave_days = float_round(full_month * float(base_leaves) / 12, precision_rounding = 1)
return leave_days

View File

@ -0,0 +1,27 @@
from openerp import models, api, fields, _
from email.utils import formataddr
class mail_message(models.Model):
_inherit = 'mail.message'
@api.model
def create(self, vals):
# print"self._context.------",self._context
# if self._context.get('holiday_create'):
if self._context.get('hr_uid'):
user = self.env['res.users'].browse(self._context.get('hr_uid'))
if user.alias_name and user.alias_domain:
from_address = formataddr((user.name, '%s@%s' % (user.alias_name, user.alias_domain)))
vals.update({'email_from': from_address,'reply_to':from_address})
elif user.email:
from_address = formataddr((user.name, user.email))
vals.update({'email_from': from_address,'reply_to':from_address})
vals.update({'author_id': user.partner_id.id})
res = super(mail_message, self).create(vals)
return res

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="0">
<record id="base.group_hr_payroll_manager" model="res.groups">
<field name="name">Payroll Manager</field>
<field name="comment">the user will have the additional right to approve payroll slips.</field>
<field name="category_id" ref="base.module_category_human_resources"/>
<field name="implied_ids" eval="[(4, ref('base.group_hr_manager'))]"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
<record id="hr_holidays_personal_rule" model="ir.rule">
<field name="name">Assigned Leaves</field>
<field ref="model_hr_holidays" name="model_id"/>
<field name="domain_force">['|',('employee_id.user_id','=',user.id),('employee_id.parent_id.user_id','=',user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="resource.access_resource_calendar_leaves_user" model="ir.model.access">
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="True"/>
</record>
</data>
</openerp>

View File

@ -0,0 +1,32 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_itis_confession,access_itis_confession,model_itis_confession,,1,1,1,1
access_itis_employee_children,access_itis_employee_children,model_itis_employee_children,,1,1,1,1
access_itis_limitation_reason,access_itis_limitation_reason,model_itis_limitation_reason,,1,1,1,1
access_itis_hr_contact_manager,access_itis_hr_contact_manager,model_itis_hr_contact,,1,1,1,1
access_itis_fte_report,access_itis_fte_report,model_fte_report,,1,1,1,1
access_itis_fte_records,access_itis_fre_report,model_fte_records,,1,1,1,1
access_itis_create_fte,access_itis_create_fte,model_create_fte,,1,1,1,1
access_hr_employee_fte,access_hr_employee_fte,model_hr_employee_fte,,1,1,1,1
access_itis_hr_contact_manager,access_itis_hr_contact_manager,model_itis_hr_contact,,1,1,1,1
access_hr_leave_journal,access_hr_leave_journal,model_hr_leave_journal,,1,1,1,1
access_hr_payslip_read,access_hr_payslip_read,hr_payroll.model_hr_payslip,,1,1,1,1
access_leave_time_read,access_leave_time_read,model_leave_time,base.group_user,1,0,0,0
access_hr_contract_read,access_hr_contract_read,hr_contract.model_hr_contract,base.group_user,1,0,0,0
access_resource_calendar_read,access_resource_calendar_read,resource.model_resource_calendar,base.group_user,1,0,0,0
access_resource_calendar_attendance_read,access_resource_calendar_attendance_read,resource.model_resource_calendar_attendance,base.group_user,1,0,0,0
access_itis_emp_report,access_itis_emp_report,model_employee_report,,1,1,1,1
access_itis_emp_report_data,access_itis_emp_report_data,model_employee_report_data,,1,1,1,1
access_itis_health,access_itis_health,model_hr_health_insurance,,1,1,1,1
access_itis_family,access_itis_family,model_hr_family_status,,1,1,1,1
access_itis_leave_days_calc_error,access_itis_leave_days_calc_error,model_itis_leave_days_calc_error,,1,1,1,1
access_itis_employee_meeting,access_employee_meeting,model_employee_meeting,,1,1,1,1
access_itis_employee_instruction,access_employee_instruction,model_employee_instruction,,1,1,1,1
access_itis_planned_jobs,access_planned_jobs,model_planned_job,,1,1,1,1
access_itis_contract_type,access_contract_type,model_itis_contract_type,,1,1,1,1
access_itis_model_employee_overtime_count,access_model_employee_overtime_count,model_employee_overtime_count,,1,1,1,1
access_hr_rule_input,access_hr_rule_input_read,hr_payroll.model_hr_rule_input,,1,1,1,1
access_hr_payslip_worked_days,access_hr_payslip_worked_days_read,hr_payroll.model_hr_payslip_worked_days,,1,1,1,1
access_res_partner,access_res_partner_read,base.model_res_partner,,1,1,1,1
access_hr_leave_nextyear,access_hr_leave_nextyear_read,model_hr_leave_nextyear,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_itis_confession access_itis_confession model_itis_confession 1 1 1 1
3 access_itis_employee_children access_itis_employee_children model_itis_employee_children 1 1 1 1
4 access_itis_limitation_reason access_itis_limitation_reason model_itis_limitation_reason 1 1 1 1
5 access_itis_hr_contact_manager access_itis_hr_contact_manager model_itis_hr_contact 1 1 1 1
6 access_itis_fte_report access_itis_fte_report model_fte_report 1 1 1 1
7 access_itis_fte_records access_itis_fre_report model_fte_records 1 1 1 1
8 access_itis_create_fte access_itis_create_fte model_create_fte 1 1 1 1
9 access_hr_employee_fte access_hr_employee_fte model_hr_employee_fte 1 1 1 1
10 access_itis_hr_contact_manager access_itis_hr_contact_manager model_itis_hr_contact 1 1 1 1
11 access_hr_leave_journal access_hr_leave_journal model_hr_leave_journal 1 1 1 1
12 access_hr_payslip_read access_hr_payslip_read hr_payroll.model_hr_payslip 1 1 1 1
13 access_leave_time_read access_leave_time_read model_leave_time base.group_user 1 0 0 0
14 access_hr_contract_read access_hr_contract_read hr_contract.model_hr_contract base.group_user 1 0 0 0
15 access_resource_calendar_read access_resource_calendar_read resource.model_resource_calendar base.group_user 1 0 0 0
16 access_resource_calendar_attendance_read access_resource_calendar_attendance_read resource.model_resource_calendar_attendance base.group_user 1 0 0 0
17 access_itis_emp_report access_itis_emp_report model_employee_report 1 1 1 1
18 access_itis_emp_report_data access_itis_emp_report_data model_employee_report_data 1 1 1 1
19 access_itis_health access_itis_health model_hr_health_insurance 1 1 1 1
20 access_itis_family access_itis_family model_hr_family_status 1 1 1 1
21 access_itis_leave_days_calc_error access_itis_leave_days_calc_error model_itis_leave_days_calc_error 1 1 1 1
22 access_itis_employee_meeting access_employee_meeting model_employee_meeting 1 1 1 1
23 access_itis_employee_instruction access_employee_instruction model_employee_instruction 1 1 1 1
24 access_itis_planned_jobs access_planned_jobs model_planned_job 1 1 1 1
25 access_itis_contract_type access_contract_type model_itis_contract_type 1 1 1 1
26 access_itis_model_employee_overtime_count access_model_employee_overtime_count model_employee_overtime_count 1 1 1 1
27 access_hr_rule_input access_hr_rule_input_read hr_payroll.model_hr_rule_input 1 1 1 1
28 access_hr_payslip_worked_days access_hr_payslip_worked_days_read hr_payroll.model_hr_payslip_worked_days 1 1 1 1
29 access_res_partner access_res_partner_read base.model_res_partner 1 1 1 1
30 access_hr_leave_nextyear access_hr_leave_nextyear_read model_hr_leave_nextyear 1 1 1 1

View File

@ -0,0 +1,59 @@
<openerp>
<data noupdate="1">
<record id="limit_reason_sachgrundlos" model="itis_limitation_reason">
<field name="name">Sachgrundlos</field>
</record>
<record id="limit_reason_projektbefristet" model="itis_limitation_reason">
<field name="name">Projektbefristet</field>
</record>
<record id="limit_reason_elternzeit" model="itis_limitation_reason">
<field name="name">Elternzeit/Mutterschutz</field>
</record>
<record id="limit_reason_krankheit" model="itis_limitation_reason">
<field name="name">Krankheit</field>
</record>
<record id="limit_reason_sabbatical" model="itis_limitation_reason">
<field name="name">Sabbatical Vertretung</field>
</record>
<record id="lshop_order_creation_path" model="ir.config_parameter">
<field name="key">fte.base</field>
<field name="value">40</field>
</record>
<record id="itis_leave_overtime" model='hr.holidays.status'>
<field name="name">Overtime Leave</field>
<field name="color_name">magenta</field>
<field name="limit">1</field>
</record>
</data>
<data>
<record id="hr_holidays.property_rule_holidays_employee" model="ir.rule">
<field name="name">Employee Holidays</field>
<field name="model_id" ref="model_hr_holidays"/>
<field name="domain_force">['|', ('employee_id.user_id','=',user.id), ('employee_id', 'child_of', [x.id for x in user.employee_ids])]</field>
<field name="perm_create" eval="False"/>
<field name="perm_write" eval="True"/>
<field name="perm_read" eval="True"/>
<field name="perm_unlink" eval="False"/>
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
</record>
<delete model="ir.rule" id="resource.resource_own_leaves"/>
<record model="ir.rule" id="resource.resource_own_leaves">
<field name="name">Resource: see own leaves</field>
<field name="model_id" ref="resource.model_resource_calendar_leaves"/>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
<field name="domain_force">['|','|',
('resource_id', '=', False),
('resource_id.user_id', '=', user.id),
('resource_id.user_id', '!=', user.id),
]</field>
</record>
<record model="workflow.transition" id="hr_holidays.holiday_confirm2validate"> <!-- 2. submitted->accepted (validate signal) if not double_validation-->
<field name="group_id" ref="base.group_user"/>
</record>
<record model="workflow.transition" id="hr_holidays.holiday_validate2refuse"> <!-- 3. accepted->refused (refuse signal) -->
<field name="group_id" ref="base.group_user"/>
</record>
</data>
</openerp>

View File

@ -0,0 +1,52 @@
<openerp>
<data>
<!-- employee meeting Button on Employee Form -->
<record id="act_hr_employee_meeting" model="ir.actions.act_window">
<field name="res_model">employee.meeting</field>
<field name="view_type">form</field>
<field name="name">Employee Meeting</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('employee_id','in',[active_id])]</field>
<field name="context">{'search_default_employee_id': [active_id], 'default_employee_id': active_id}</field>
</record>
<record id="employee_meeting_tree" model="ir.ui.view">
<field name="name">employee_meeting_tree</field>
<field name="model">employee.meeting</field>
<field name="arch" type="xml">
<tree editable="bottom">
<field name="name" required="1"/>
<field name="meeting_date" required="1"/>
<field name="employee_id" invisible="1"/>
<field name="supervisor_id"/>
<field name="note"/>
</tree>
</field>
</record>
<!-- employee instruction Button on Employee Form -->
<record id="act_hr_employee_instruction" model="ir.actions.act_window">
<field name="res_model">employee.instruction</field>
<field name="view_type">form</field>
<field name="name">Employee Instruction</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('employee_id','in',[active_id])]</field>
<field name="context">{'search_default_employee_id': [active_id], 'default_employee_id': active_id}</field>
</record>
<record id="employee_instruction_tree" model="ir.ui.view">
<field name="name">employee_instruction_tree</field>
<field name="model">employee.instruction</field>
<field name="arch" type="xml">
<tree editable="bottom">
<field name="name" required="1"/>
<field name="meeting_date" required="1"/>
<field name="employee_id" invisible="1"/>
<field name="supervisor_id"/>
<field name="note"/>
</tree>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="itis_emp_payroll_report_tree" model='ir.ui.view'>
<field name="name">itis.emp.payroll.report.tree</field>
<field name="model">employee.payroll.report</field>
<field name="arch" type="xml">
<tree string="Employee Payroll Records" colors="orange:record_change=='V';red:record_change=='ST';red:record_change=='SV' ">
<field name='contract_id' invisible="1"/>
<field name='employee_id' invisible="1"/>
<field name="record_change" invisible="1"/>
<field name='identification_id'/>
<field name='name'/>
<field name='surname'/>
<field name='birthday'/>
<field name='address_home_id'/>
<field name='address_id'/>
<field name='bank_account_id'/>
<field name='health_insurance'/>
<field name='disability'/>
<field name="disability_limited_until"/>
<field name='family_status'/>
<field name='children'/>
<field name='contract_name'/>
<field name='contract_start_date'/>
<field name='contract_end_date'/>
<field name='working_hours'/>
<field name='struct_id'/>
<field name = "gross_salary"/>
<field name="wage"/>
<field name = "sick_days"/>
<field name='notes'/>
</tree>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="itis_employee_report_tree" model='ir.ui.view'>
<field name="name">itis.employee.report.tree</field>
<field name="model">employee.report</field>
<field name="arch" type="xml">
<form string="Employees">
<field name='employee_ids' readonly="1">
<tree string="Employees" colors="orange:color=='yellow' ;red:color=='red';green:color=='green'">
<field name='employee_id' />
<field name='overtime_count' widget="float_time"/>
<field name='sum_leaves' />
<field name='sum_leaves_ny' />
</tree>
</field>
</form>
</field>
</record>
<record id="employee_report_action" model="ir.actions.act_window">
<field name="name">Employee Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">employee.report</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
</record>
<menuitem name="Employee Report" parent="menu_hr_reports"
action="employee_report_action" id="menu_employee_report"
groups='base.group_user' />
<!--groups='base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user' />-->
</data>
</openerp>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="company_view_form_itis" model="ir.ui.view">
<field name="name">company_view_form_itis</field>
<field name="model">res.company</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='account_grp']" position="after">
<group name="sow17" string="Jahreswechsel Testen">
<field name="for_sow17"/>
<field name="next_year_date" attrs="{'invisible': [('for_sow17','=',False)],'required': [('for_sow17','=',True)]}"/>
</group>
</xpath>
</field>
</record>
<record id="itis_fte_records_form" model='ir.ui.view'>
<field name="name">itis.fte.records.form</field>
<field name="model">fte.records</field>
<field name="arch" type="xml">
<tree string="FTE Records">
<field name='department_id' />
<field name='planned_fte' />
<field name='fte' />
<field name='diff_fte' />
</tree>
</field>
</record>
<record id="itis_fte_report_tree" model='ir.ui.view'>
<field name="name">itis.fte.report.tree</field>
<field name="model">fte.report</field>
<field name="arch" type="xml">
<tree string="FTE Report">
<field name='name'/>
<field name='create_uid'/>
</tree>
</field>
</record>
<record id="itis_fte_report_form" model='ir.ui.view'>
<field name="name">itis.fte.report.form</field>
<field name="model">fte.report</field>
<field name="arch" type="xml">
<form>
<sheet>
<div class="oe_title">
<h1>
<field name="name" readonly='1' />
</h1>
</div>
<group>
<saperator name='fte_report_field' string="FTE Records" />
<field name='fte_ids' colspan='4' nolabel='1' readonly='1'/>
</group>
</sheet>
</form>
</field>
</record>
<record id="fte_report_action" model="ir.actions.act_window">
<field name="name">FTE Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">fte.report</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Reports" parent="hr.menu_hr_root"
id="menu_hr_reports" groups='base.group_user'/>
<menuitem name="FTE Reports" parent="menu_hr_reports" action="fte_report_action"
id="menu_fte_report" groups='base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user'/>
</data>
</openerp>

View File

@ -0,0 +1,782 @@
<openerp>
<data>
<!--<record id="resource_calendar_form_inherit" model="ir.ui.view">-->
<!--<field name="name">resource_calendar_form_inherit</field>-->
<!--<field name="model">resource.calendar</field>-->
<!--<field name="inherit_id" ref="resource.resource_calendar_form"/>-->
<!--<field name="arch" type="xml">-->
<!--<xpath expr="//field[@name='company_id']" position="after">-->
<!--<field name='hourly_basis'/>-->
<!--</xpath>-->
<!--</field>-->
<!--</record>-->
<record id="hr_department_view_form_itis" model="ir.ui.view">
<field name="name">hr_department_view_form_itis</field>
<field name="model">hr.department</field>
<field name="inherit_id" ref="hr.view_department_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='company_id']" position="after">
<field name='planned_fte'/>
<field name="account_id"/>
</xpath>
</field>
</record>
<record id="act_hr_leaves_overview" model="ir.actions.act_window">
<field name="res_model">hr.leave.journal</field>
<!--<field name="src_model">hr.employee</field>-->
<field name="view_mode">tree,form</field>
<field name="view_type">form</field>
<field name="name">Leaves</field>
<field name="context">{'search_default_employee_id': [active_id], 'default_employee_id': active_id}</field>
<!--<field name="context">{'default_employee_id': active_id}</field>-->
</record>
<record id="itis_leave_journal_tree" model="ir.ui.view">
<field name="name">hr_leave_journal_tree</field>
<field name="model">hr.leave.journal</field>
<!--<field name="view_type">tree</field>-->
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="employee_id"/>
<field name="year"/>
<field name="year_type"/>
<field name="type"/>
<field name="leave_type"/>
<field name="leave_start"/>
<field name="leave_end"/>
<field name="leave_days"/>
<field name="leave_hours"/>
</tree>
</field>
</record>
<record id="itis_leave_journal_form" model="ir.ui.view">
<field name="name">hr_leave_journal_form</field>
<field name="model">hr.leave.journal</field>
<!--<field name="view_type">form</field>-->
<field name="arch" type="xml">
<form>
<group>
<field name="name"/>
<field name="employee_id"/>
<field name="year"/>
<field name="year_type"/>
<field name="type"/>
<field name="leave_type"/>
<field name="leave_start"/>
<field name="leave_end"/>
<field name="leave_days"/>
<field name="leave_hours"/>
<field name="contract_id"/>
<field name="leave_id"/>
</group>
</form>
</field>
</record>
<record id="itis_hr_leave_journal_form" model="ir.ui.view">
<field name="name">hr_leave_journal_form</field>
<field name="model">hr.leave.journal</field>
<field name="arch" type="xml">
<search string="Search Leave">
<field name="employee_id"/>
<field name="year"/>
<field name="year_type"/>
<field name="type"/>
<group expand="0" string="Group By">
<filter string="Jahr" icon="terp-personal" domain="[]" context="{'group_by':'year'}"/>
<filter string="Jahr Art" icon="terp-personal" domain="[]" context="{'group_by':'year_type'}"/>
<filter string="Art" icon="terp-personal" domain="[]" context="{'group_by':'type'}"/>
<filter string="Leave Type" icon="terp-personal" domain="[]" context="{'group_by':'leave_type'}"/>
</group>
</search>
</field>
</record>
<record id="hr_hr_employee_view_form_itis" model="ir.ui.view">
<field name="name">hr_hr_employee_view_form_itis</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr_contract.hr_hr_employee_view_form2"/>
<field name="arch" type="xml">
<!--#added new field for the following year june1st SOW17-->
<xpath expr="//group[@string='Contract']" position="before">
<group string="Leaves Following Year">
<label for="leave_days_ny"/>
<div>
<field name="leave_days_ny" class="oe_inline" />
<button name="open_nextyear_leaved_day_change" type="object" class="oe_link" string="Update"/>
</div>
<label for="additional_leave_days_ny"/>
<div>
<field name="additional_leave_days_ny" class="oe_inline" />
<button name="open_nextyear_add_day_change" type="object" class="oe_link" string="Update"/>
</div>
<label for="approved_leaves_ny"/>
<div>
<field name="approved_leaves_ny" class="oe_inline" />
</div>
<label for="sum_leaves_ny"/>
<div>
<field name="sum_leaves_ny" class="oe_inline" />
</div>
<!--<br/>-->
<label for="approved_leaves_till_march_ny"/>
<div>
<field name="approved_leaves_till_march_ny" class="oe_inline" />
</div>
<label for="approved_leaves_after_march_ny"/>
<div>
<field name="approved_leaves_after_march_ny" class="oe_inline" />
</div>
<!--<button name="year_change_calc_days" string="Check" type="object"/>-->
<field name="nextyear_leave_ids" nolabel="1" invisible="1">
<tree>
<field name="date"/>
<field name="leave_days"/>
<field name="holiday_id"/>
</tree>
</field>
</group>
</xpath>
<xpath expr="//group[@string='Leaves']/div" position="after">
<label for="leave_days"/>
<div>
<field name="leave_days" class="oe_inline" readonly="1"/>
<button name="open_leaved_day_change" type="object" class="oe_link" string="Update"/>
</div>
<label for="additional_leave_days"/>
<div>
<field name="additional_leave_days" class="oe_inline" readonly="1"/>
<button name="open_ld_change" type="object" class="oe_link" string="Update"/>
</div>
<label for="leave_days_last_year"/>
<div>
<field name="leave_days_last_year" class="oe_inline" readonly="1"/>
</div>
<label for="approved_leaves"/>
<div>
<field name="approved_leaves" class="oe_inline" readonly="1"/>
</div>
<label for="sum_leaves"/>
<div>
<field name="sum_leaves" class="oe_inline" readonly="1"/>
</div>
<label for="overtime_count" invisible="1"/>
<div invisible="1">
<field name="overtime_count" widget="float_time" class="oe_inline" readonly="1" invisible="1"/>
</div>
<label for="computed_overtime_count"/>
<div>
<field name="computed_overtime_count" widget="float_time" class="oe_inline" />
<button name="open_ot_change" type="object" class="oe_link" string="Update"/>
</div>
<!--<label for="employee_overtime_id"/>-->
<!--<div>-->
<!--<field name="employee_overtime_id" />-->
<!--</div>-->
<!--Additional field to show remaining leaves from last year-->
<br/><br/>
<label for="last_year_remaining_leaves"/>
<div>
<field name="last_year_remaining_leaves" />
</div>
</xpath>
<xpath expr="//group[@string='Leaves']/div" position="attributes">
<attribute name="invisible">True</attribute>
</xpath>
<xpath expr="//group[@string='Leaves']/label" position="attributes">
<attribute name="invisible">True</attribute>
</xpath>
<label for="name" position="attributes">
<attribute name="string">Mitarbeiter/in</attribute>
</label>
<label for="work_phone" position="attributes">
<attribute name="string">Telefon (interne Durchwahl)</attribute>
<attribute name="class"/>
</label>
<label for="category_ids" position="replace"></label>
<field name="category_ids" position="replace"></field>
<field name="medic_exam" position="before">
<field name="category_ids" widget="many2many_tags" placeholder="e.g. Part Time" groups="base.group_hr_user"/>
<field name="fte"/>
<field name="initial_date"/>
<field name="temp_contract_end_date"/>
</field>
<xpath expr="//field[@name='vehicle_distance']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<field name="medic_exam" position="after">
<field name="position"/>
</field>
<field name="work_location" position="replace"></field>
<field name="passport_id" position="attributes">
<attribute name="string">Sozialversicherungsnummer</attribute>
</field>
<field name="otherid" position="attributes">
<attribute name="string">Steuer-ID</attribute>
</field>
<field name="otherid" position="after">
<field name="taxclass"/>
<field name="confession"/>
<field name="health_insurance" widget="selection"/>
<field name="disability"/>
<field name="disability_limited_until" attrs="{'invisible': [('disability','!=','yes')]}"/>
<field name="sign_permission" invisible="1"/>
</field>
<field name="address_home_id" position="after">
<field name="emergency_contact"/>
<field name="emergency_contact2"/>
</field>
<field name="children" position="after">
<field name="children_ids" string="Kinder">
<tree>
<field name="name"/>
<field name="birth_date"/>
</tree>
</field>
</field>
<page string="HR Settings" position="attributes">
<attribute name="string">Vertragsinformationen</attribute>
</page>
<field name="address_home_id" position="before">
<!--<label for="surname"/>-->
<field name="surname"/>
<!--<label for="second_name"/>-->
<field name="second_name"/>
</field>
<field name="place_of_birth" position="after">
<field name="birth_name"/>
</field>
<field name="active" position="after">
<field name="five_years"/>
</field>
<field name="department_id" position="before">
<field name="bereich"/>
</field>
<!--do not display the field is a manager-->
<field name="manager" position="replace"/>
<label for="work_email" position="attributes">
<attribute name="class"/>
</label>
<xpath expr="//group[@name='active_group']" position='after'>
<group string="Meeting">
<field name="last_ma_conversation_date"/>
<field name="employee_instruction_id"/>
</group>
<group string="FTEs">
<field name="fte_ids" nolabel='1' colspan='4'>
<tree editable='bottom'>
<field name='department_id'/>
<field name='fte' string="FTE(%)"/>
</tree>
</field>
</group>
</xpath>
<xpath expr="//field[@name='vehicle']" position='attributes'>
<attribute name='invisible'>1</attribute>
</xpath>
<xpath expr="//field[@name='marital']" position='replace'>
<field name='family_status' widget="selection"/>
</xpath>
<xpath expr="//div[@name='button_box']" position="inside">
<button name="%(act_hr_leaves_overview)d"
type="action"
class="oe_stat_button"
icon="fa-clock-o"
groups="base.group_hr_manager">
<field name="sum_journal_entries" widget="statinfo" string="Urlaubsjournal"/>
</button>
</xpath>
</field>
</record>
<!-- hr employee form view-->
<record id="view_employee_form_inherit_itis" model="ir.ui.view">
<field name="name">hr.employee.form.itis.inherit</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="arch" type="xml">
<div name="button_box" position="inside">
<button name="%(act_hr_employee_meeting)d"
string="Meetings"
class="oe_stat_button"
icon="fa-calendar"
type="action"
>
</button>
<button name="%(act_hr_employee_instruction)d"
string="Memo"
class="oe_stat_button"
icon="fa-calendar"
type="action"
>
</button>
</div>
<field name="mobile_phone" position="after">
<field name="executive_employee"/>
</field>
<field name="job_id" position="after">
<field name="planned_job_id" widget="selection"/>
</field>
<field name="coach_id" position="after">
<field name="br_member"/>
</field>
<page string="HR Settings" position="after">
<page string="Bemerkungen" name="wage_information" groups="base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user">
<group>
<field name="wage_info" nolabel="1"/>
</group>
<!--TODO this section consists of fields created by the customer, they are not present in the dev environment-->
<!--TODO On dev environment this section needs to be commented-->
<group>
<field name="x_Kuendigungsfrist" nolabel="0"/>
</group>
<group>
<field name="x_BVG" nolabel="0"/>
<field name="x_BVG-Ausgabe" nolabel="0"/>
<field name="x_BVG-Preis" nolabel="0"/>
<field name="x_BVG_Ring" nolabel="0"/>
<field name="x_BVG-Rueckgabe" nolabel="0"/>
</group>
<group>
<field name="x_BAV" nolabel="0"/>
<field name="x_BAV-aufklaerung" nolabel="0"/>
<field name="x_BAV-Anbieter" nolabel="0"/>
<field name="x_BAV-Versicherung" nolabel="0"/>
<field name="x_BAV-Intervall" nolabel="0"/>
<field name="x_BAV-Start" nolabel="0"/>
<field name="x_BAV-Ende" nolabel="0"/>
<field name="x_BAV-AG-Anteil" nolabel="0"/>
<field name="x_BAV-AN-Anteil" nolabel="0"/>
<field name="x_BAV-Kommentar"></field>
</group>
</page>
</page>
</field>
</record>
<record id="view_hr_employee_grade_form_inherit_itis" model="ir.ui.view">
<field name="name">hr.payroll.structure.form.inherit.itis</field>
<field name="model">hr.payroll.structure</field>
<field name="inherit_id" ref="hr_payroll.view_hr_employee_grade_form"/>
<field name="arch" type="xml">
<field name="parent_id" position="after">
<field name="base_on_hours" string="Basiert auf Stundens"/>
</field>
</field>
</record>
<!--contract tree view-->
<record id="hr_contract_view_tree_inherit" model="ir.ui.view">
<field name="name">hr.contract.view.tree.inherit</field>
<field name="model">hr.contract</field>
<field name="inherit_id" ref="hr_contract.hr_contract_view_tree"/>
<field name="arch" type="xml">
<field name="employee_id" position="before">
<field name="itis_contract_type"/>
</field>
</field>
</record>
<!--Inherit Form View to Modify it-->
<record id="hr_contract_view_form_itis" model="ir.ui.view">
<field name="name">hr_contract_view_form_itis</field>
<field name="model">hr.contract</field>
<field name="inherit_id" ref="hr_contract.hr_contract_view_form"/>
<field name="arch" type="xml">
<field name="working_hours" position="before">
<field name="limitation_reason"/>
</field>
<field name="working_hours" position="after">
<field name="base_leaves" required="True"/>
</field>
<field name="type_id" position="after">
<field name="itis_contract_type" />
</field>
<field name="working_hours" position="attributes">
<attribute name="required">True</attribute>
</field>
</field>
</record>
<record id="itis_employee_children_form" model="ir.ui.view">
<field name="name">itis_employee_childrenform</field>
<field name="model">itis_employee_children</field>
<field name="arch" type="xml">
<form>
<group>
<group>
<field name="name"/>
</group>
<group>
<field name="birth_date"/>
</group>
</group>
</form>
</field>
</record>
<!--Inherit Form View to Modify it-->
<record id="hr_payroll_view_hr_payslip_form_itis" model="ir.ui.view">
<field name="name">hr_payroll_view_hr_payslip_form_itis</field>
<field name="model">hr.payslip</field>
<field name="inherit_id" ref="hr_payroll.view_hr_payslip_form"/>
<field name="arch" type="xml">
<button name="hr_verify_sheet" position="attributes">
<attribute name="groups">base.group_hr_payroll_manager</attribute>
</button>
</field>
</record>
<record id="itis_hr_contact_tree" model="ir.ui.view">
<field name="name">itis.hr.contact.tree</field>
<field name="model">itis.hr.contact</field>
<field eval="8" name="priority"/>
<field name="arch" type="xml">
<tree string="Contacts">
<field name="name" string="Name"/>
<field name="phone"/>
<field name="email"/>
</tree>
</field>
</record>
<record id="itis_hr_contact_form" model="ir.ui.view">
<field name="name">itis.hr.contact.form</field>
<field name="model">itis.hr.contact</field>
<field name="arch" type="xml">
<form>
<sheet>
<div class="oe_title">
<h1>
<field name="name" default_focus="1" placeholder="Name"/>
</h1>
</div>
<group>
<group>
<label for="street" string="Address"/>
<div class="o_address_format">
<field name="street" placeholder="Street..." class="o_address_street"/>
<field name="street2" placeholder="Street 2..." class="o_address_street"/>
<field name="city" placeholder="City" class="o_address_city"/>
<field name="state_id" class="o_address_state" placeholder="State" options='{"no_open": True}'/>
<field name="zip" placeholder="ZIP" class="o_address_zip"/>
<field name="country_id" placeholder="Country" class="o_address_country" options='{"no_open": True, "no_create": True}'/>
</div>
</group>
<group>
<field name="phone" widget="phone"/>
<field name="mobile" widget="phone"/>
<field name="fax"/>
<field name="email" widget="email"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_itis_hr_contact" model="ir.actions.act_window">
<field name="name">Contacts</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">itis.hr.contact</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem action="action_itis_hr_contact" groups="base.group_hr_manager" id="itis_hr_contact_menu" name='HR Contacts' parent="hr.menu_hr_main" sequence='100'/>
<record id="hr_emp_data_tree" model='ir.ui.view'>
<field name="name">hr.emp.data.tree</field>
<field name="model">hr.employee</field>
<field name="priority">100</field>
<field name="arch" type="xml">
<tree string="Mitarbeiterdaten" >
<field name="identification_id" />
<field name="surname" />
<field name="second_name" />
<field name="birthday" />
<field name="address_id" string="Company"/>
<field name="bereich" />
<field name="department_id" />
<field name="planned_job_id" />
<field name="job_id" />
<field name="contract_type" string="Vertragstyp"/>
<field name="initial_date" />
<field name="temp_contract_end_date" string="Enddatum befristeter Vertrag"/>
<field name="contract_limitation_reason" string="Befristungsgrund"/>
<field name="contract_trial_end_date" string="Probezeit Enddatum"/>
<field name="last_ma_conversation_date" string="Letztes MA Gespraech"/>
<field name="five_years" />
<field name="contract_working_hours" />
<field name="contract_leaves" string="Urlaub"/>
<field name="disability" />
<field name="last_contract_changed_wage" string="letzte Vertragsänderung_L&amp;G" />
<field name="last_contract_changed_date" string="Startdatum der letzten Vertragversänderung" />
<!--<field name="contract_wage" string="Vergütung"/>-->
<field name="emp_wage_cal" string="Vergütung"/>
<field name="compensation_at_vz" string="Vergütung bei VZ"/>
<field name="remuneration_incl_ag_costs" string="Vergütung inkl. AG Kosten (25%)"/>
<field name="br_member" />
<field name="contract_notes" string="Bemerkungen"/>
<field name="parent_id" />
</tree>
</field>
</record>
<record id="action_sever_itis_emp_data" model="ir.actions.server">
<field name="state">code</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_hr_employee"/>
<field name="code">action = model.open_emp_data_tree()</field>
<field name="condition">True</field>
<field name="name">Personalübersicht</field>
</record>
<!--<record id="action_itis_emp_data" model="ir.actions.act_window">-->
<!--<field name="name">Personalübersicht</field>-->
<!--<field name="type">ir.actions.act_window</field>-->
<!--<field name="res_model">hr.employee</field>-->
<!--<field name="view_type">form</field>-->
<!--<field name="view_mode">tree,form</field>-->
<!--<field name="view_id" ref="hr_emp_data_tree"/>-->
<!--</record>-->
<menuitem action="action_sever_itis_emp_data" groups="base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user" id="itis_emp_data_menu_server" name='Personalübersicht' parent="hr.menu_hr_main" sequence='50'/>
<record id="itis_health_insurance_form" model='ir.ui.view'>
<field name="name">hr.health.insurance.form</field>
<field name="model">hr.health.insurance</field>
<field name="arch" type="xml">
<form string="Health Insurance">
<sheet>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1>
<field name="name" required='1' />
</h1>
</div>
</sheet>
</form>
</field>
</record>
<record id="itis_health_insurance_tree" model='ir.ui.view'>
<field name="name">hr.health.insurance.tree</field>
<field name="model">hr.health.insurance</field>
<field name="arch" type="xml">
<tree string="Health Insurance">
<field name="name" />
</tree>
</field>
</record>
<record id="hr_health_action" model="ir.actions.act_window">
<field name="name">Health Insurance</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hr.health.insurance</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Health Insurance" parent="hr.menu_hr_configuration" action="hr_health_action"
id="menu_health_insurance" groups='base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user'/>
<record id="itis_planned_job_tree" model='ir.ui.view'>
<field name="name">planned_jobs_tree</field>
<field name="model">planned.job</field>
<field name="arch" type="xml">
<tree string="Planned Jobs">
<field name="name" />
</tree>
</field>
</record>
<record id="hr_planned_job" model="ir.actions.act_window">
<field name="name">Planned Jobs</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">planned.job</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Planned Jobs" parent="hr.menu_hr_configuration" action="hr_planned_job"
id="menu_planned_job" groups='base.group_hr_payroll_manager,base.group_hr_manager'/>
<record id="itis_family_status_form" model='ir.ui.view'>
<field name="name">hr.family.status.form</field>
<field name="model">hr.family.status</field>
<field name="arch" type="xml">
<form string="Family Status">
<sheet>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1>
<field name="name" required='1'/>
</h1>
</div>
</sheet>
</form>
</field>
</record>
<record id="itis_family_status_tree" model='ir.ui.view'>
<field name="name">hr.family.status.tree</field>
<field name="model">hr.family.status</field>
<field name="arch" type="xml">
<tree string="Family Status">
<field name="name"/>
</tree>
</field>
</record>
<record id="hr_family_status_action" model="ir.actions.act_window">
<field name="name">Family Status</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hr.family.status</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Family Status" parent="hr.menu_hr_configuration" action="hr_family_status_action"
id="menu_family_status" groups='base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user'/>
<record id="itis_leave_days_calc_error_tree" model='ir.ui.view'>
<field name="name">leave.days.calc.error.tree</field>
<field name="model">itis.leave.days.calc.error</field>
<field name="arch" type="xml">
<tree string="Family Status">
<field name="name"/>
<field name="year"/>
<field name="error"/>
</tree>
</field>
</record>
<record id="leave_days_calc_error_action" model="ir.actions.act_window">
<field name="name">Fehler Urlaubsberechnung</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">itis.leave.days.calc.error</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Fehler Urlaubsberechnung" parent="hr.menu_hr_configuration" action="leave_days_calc_error_action"
id="menu_days_calc_error" groups='base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user'/>
<record id="itis_leave_timing_tree" model='ir.ui.view'>
<field name="name">leave.time.tree</field>
<field name="model">leave.time</field>
<field name="arch" type="xml">
<form string="Leave Time">
<sheet>
<group>
<field name = "active" required="1"/>
</group>
<group>
<label for="fullday_start_time" string="Full Day Period"/>
<div><field name="fullday_start_time" class="oe_inline" required="1"/> to <field name="fullday_end_time" class="oe_inline" required="1"/></div>
</group>
<group>
<label for="halfday_morning_start_time" string="Halfday Morning Period"/>
<div><field name="halfday_morning_start_time" class="oe_inline" required="1"/> to <field name="halfday_morning_end_time" class="oe_inline" required="1"/></div>
</group>
<group>
<label for="halfday_afternoon_start_time" string="Halfday Afternoon Period"/>
<div><field name="halfday_afternoon_start_time" class="oe_inline" required="1"/> to <field name="halfday_afternoon_end_time" class="oe_inline" required="1"/></div>
</group>
</sheet>
</form>
</field>
</record>
<record id="payroll_hr_employee_view_form_inherit" model="ir.ui.view">
<field name="name">payroll.hr.employee.view.form.inherit</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr_payroll.payroll_hr_employee_view_form"/>
<field name="arch" type="xml">
<data>
<xpath expr="//button[@name='%(hr_payroll.act_hr_employee_payslip_list)d']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
</data>
</field>
</record>
<record id="hr_office_time_action" model="ir.actions.act_window">
<field name="name">Office Leave Timing</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">leave.time</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Office Time" parent="hr.menu_hr_configuration" action="hr_office_time_action"
id="menu_office_time" groups='base.group_hr_payroll_manager,base.group_hr_manager'/>
<record id="emp_overtime_count_tree" model='ir.ui.view'>
<field name="name">emp.overtime.count.tree</field>
<field name="model">employee.overtime.count</field>
<field name="arch" type="xml">
<tree string="Employee Overtime Count" create="false" delete="false">
<field name="employee_id"/>
<field name="emp_overtime_count" readonly="1"/>
</tree>
</field>
</record>
<record id="emp_overtime_count_form" model='ir.ui.view'>
<field name="name">emp.overtime.count.form</field>
<field name="model">employee.overtime.count</field>
<field name="arch" type="xml">
<form string="Employee Overtime Count" create="false" delete="false">
<sheet>
<group>
<field name="employee_id"/>
<field name="emp_overtime_count" readonly="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="emp_overtime_count_action" model="ir.actions.act_window">
<field name="name">Employee Overtime Count</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">employee.overtime.count</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Employee Overtime Count" parent="hr.menu_hr_configuration" action="emp_overtime_count_action"
id="menu_emp_overtime_count" groups='base.group_hr_payroll_manager,base.group_hr_manager'/>
</data>
</openerp>

View File

@ -0,0 +1,96 @@
<openerp>
<data>
<record id="hr_holidays_view_tree_itis" model="ir.ui.view">
<field name="name">hr_holidays_view_tree_itis</field>
<field name="model">hr.holidays</field>
<field name="inherit_id" ref="hr_holidays.view_holiday"/>
<field name="arch" type="xml">
<field name="date_from" position="attributes">
<attribute name="widget">date</attribute>
</field>
<field name="date_to" position="attributes">
<attribute name="widget">date</attribute>
</field>
</field>
</record>
<record id="hr_holidays_view_form_itis" model="ir.ui.view">
<field name="name">hr_holidays_view_form_itis</field>
<field name="model">hr.holidays</field>
<field name="inherit_id" ref="hr_holidays.edit_holiday_new"/>
<field name="arch" type="xml">
<field name="employee_id" position="attributes">
<attribute name="readonly">True</attribute>
<attribute name="groups">base.group_user</attribute>
</field>
<button name="validate" position="attributes">
<attribute name="groups">base.group_user</attribute>
</button>
<button name="refuse" position="attributes">
<attribute name="groups">base.group_user</attribute>
</button>
<field name="holiday_status_id" position="after">
<!--<field name="leave_selection" on_change="onchange_leave_type(date_to, date_from,leave_selection)"/>-->
<!--<field name="half_day_type" attrs="{'invisible':[('leave_selection','=', 'full_day')],'required':[('leave_selection','=', 'half_day')]}"/>-->
<field name="is_ot_leave" invisible="1"/>
</field>
<field name="holiday_status_id" position="attributes">
<attribute name="domain">[('is_holiday', '!=',True)]</attribute>
</field>
<label string="-" position="replace"/>
<field name="date_from" position="replace">
<field name="date_from" nolabel="1" on_change="onchange_date_from(date_to, date_from)" attrs="{'required':[('type', '=', 'remove')]}" class="oe_inline" widget='date'/>
<field name="leave_selection" nolabel="1" class="oe_inline" required="1"/>
<!--<field name="date_from" nolabel="1" on_change="onchange_date_from(date_to, date_from,leave_selection)" attrs="{'required':[('type', '=', 'remove')]}" class="oe_inline" widget = 'date'/>-->
<field name="half_day_type" attrs="{'invisible':[('leave_selection','=', 'full_day')],'required':[('leave_selection','=', 'half_day')]}" class="oe_inline" nolabel="1"/>
</field>
<field name="date_to" position="replace">
<field name="date_to" nolabel="1" on_change="onchange_date_to(date_to, date_from)" attrs="{'required':[('type', '=', 'remove')]}" class="oe_inline" widget ='date'/>
<field name="leave_selection_date_to" nolabel="1" class="oe_inline" attrs="{'invisible':[('leave_sele_dateto_flag','=', True)],'required':[('leave_sele_dateto_flag','=', False)]}"/>
<!--<field name="date_to" nolabel="1" on_change="onchange_date_to(date_to, date_from,leave_selection)" attrs="{'required':[('type', '=', 'remove')]}" class="oe_inline" widget = 'date'/>-->
<field name="half_day_type_date_to" attrs="{'invisible':[('leave_selection_date_to','=', 'full_day')],'required':[('leave_selection_date_to','=', 'half_day')]}" class="oe_inline" nolabel="1"/>
</field>
<field name="department_id" position="after">
<field name="leave_sele_dateto_flag" invisible="1"/>
<field name="approved_by" readonly="1"/>
<field name="approved_at" readonly="1"/>
<field name="sum_leaves" />
<field name="sum_leaves_ny" />
<field name="number_of_days_temp_ny" />
<field name="ot_hours" widget="float_time"/>
</field>
<xpath expr="//group//group//div" postion='after'>
<!--<div attrs="{'invisible':[('is_ot_leave','=', False)]}">-->
<div>
<field name="leave_hours" widget="float_time" class="oe_inline"/>hours
</div>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="edit_holiday_status_form_inherit_itis">
<field name="name">hr.holidays.status.form.inherit.itis</field>
<field name="model">hr.holidays.status</field>
<field name="inherit_id" ref="hr_holidays.edit_holiday_status_form"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="is_holiday"/>
<field name="is_sick_leave_type"/>
</field>
<!--<xpath expr="//field[@name='name']" postion='after'>-->
<!--<field name="is_holiday"/>-->
<!--</xpath>-->
</field>
</record>
<record id="hr_holidays.menu_request_approve_holidays" model="ir.ui.menu">
<field name="groups_id" eval="[(4,ref('base.group_user'))]"></field>
</record>
<delete model="ir.ui.menu" id="hr_holidays.menu_open_allocation_holidays"/>
<delete model="ir.ui.menu" id="hr_holidays.menu_request_approve_allocation"/>
<!--<menuitem name="Leave Requests to Approve" parent="hr_holidays.menu_open_ask_holidays" id="menu_request_approve_holidays" action="hr_holidays.request_approve_holidays" groups="base.group_user"/>-->
</data>
</openerp>

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from . import ot_change
from . import fte_wizard
from . import emp_payroll_wizard
from . import emp_data_wizard

View File

@ -0,0 +1,167 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields, api, _
from openerp.exceptions import Warning
import csv
from datetime import datetime
import base64
import os
class employee_data_export(models.TransientModel):
_name = 'employee.data.export'
name = fields.Binary('Timesheet CSV')
file_name = fields.Char('File')
report_selection = fields.Selection([('export_employee','Personalübersicht'),
('export_workcouncil','BR Übersicht')],
string='Report',default='export_employee', required=True)
@api.multi
def export_emp_data_csv(self):
"""
This function is use to export the employee data records which are preselected.
"""
if self._context and 'active_model' in self._context and self._context['active_model'] == 'hr.employee':
context = self._context.copy()
hr_employee = self.env['hr.employee']
if self.report_selection =='export_workcouncil':
hr_employee_records = hr_employee.search([('executive_employee','=',False),('id','in',context['active_ids'])])
else:
hr_employee_records = hr_employee.browse(context['active_ids'])
# print"analytic_timesheet_records----",analytic_timesheet_records
context = self.export_csv_subfunction(hr_employee_records)
return {
'name': _('Exported Employee Data'),
'view_type': 'form',
"view_mode": 'form',
'res_model': 'employee.data.export',
'type': 'ir.actions.act_window',
'context': context,
'target':'new',
}
def get_date_format(self,date):
if date:
return datetime.strptime(date,'%Y-%m-%d').strftime('%d.%m.%Y')
else:
return ''
def export_csv_subfunction(self,emp_data_records):
"""
It is a subfunction for the export csv.
"""
data_list = []
if self._context.get('for_work_council') or self.report_selection =='export_workcouncil':
csv_header = ['Personalnummer','Vorname','Nachname','Bereich','Team','Stellenbezeichnung','Vertragstyp',
'Ersteintrittsdatum','Enddatum befristeter Vertrag','Befristungsgrund','Probezeit Enddatum',
'letztes MA Gespraech',]
csv_name = "Betriebsratsübersicht"
else:
csv_header = ['Personalnummer','Vorname','Nachname','Geburtstag','Company','Bereich','Team','Planstellenbezeichnung',
'Stellenbezeichnung','Vertragstyp','Ersteintrittsdatum','Enddatum befristeter Vertrag','Befristungsgrund',
'Probezeit Enddatum','letztes MA Gespraech','5-Jahresjubilaeum','Arbeitszeit','Urlaub','Schwerbehinderung',
'letzte Vertragsaenderung_L&G','Startdatum der letzten Vertragversänderung','Verguetung','Verguetung bei VZ','Verguetung inkl. AG Kosten (25%)','BR Mitglied',
'Bemerkungen','Manager']
csv_name = "Personalübersicht"
time_csv = datetime.now().strftime('%Y-%m-%d_%H%M%S') + '.csv'
csv_path = "/tmp/" + time_csv
for emp_record in emp_data_records:
if self._context.get('for_work_council') or self.report_selection =='export_workcouncil':
vals = {
'Personalnummer': (emp_record.identification_id or '').encode('utf-8'),
'Nachname': (emp_record.second_name or '').encode('utf-8'),
'Vorname': (emp_record.surname or '').encode('utf-8'),
'Bereich': (emp_record.bereich and emp_record.bereich.name or '').encode('utf-8'),
'Team': (emp_record.department_id and emp_record.department_id.name or '').encode('utf-8'),
'Stellenbezeichnung': (emp_record.job_id and emp_record.job_id.name or '').encode('utf-8'),
'Vertragstyp': (emp_record.sudo().contract_type and emp_record.sudo().contract_type.name or '').encode('utf-8'),
'Ersteintrittsdatum': self.get_date_format(emp_record.initial_date),
'Enddatum befristeter Vertrag': self.get_date_format(emp_record.temp_contract_end_date),
'Befristungsgrund': (emp_record.contract_limitation_reason and emp_record.contract_limitation_reason.name or '').encode('utf-8'),
'Probezeit Enddatum': self.get_date_format(emp_record.contract_trial_end_date),
'letztes MA Gespraech': self.get_date_format(emp_record.last_ma_conversation_date),
}
else:
notes = ''
if emp_record.contract_notes:
notes= emp_record.contract_notes.replace("\n"," / ")
vals = {
'Personalnummer': (emp_record.identification_id or '').encode('utf-8'),
'Nachname': (emp_record.second_name or '').encode('utf-8'),
'Vorname': (emp_record.surname or '').encode('utf-8'),
'Geburtstag': self.get_date_format(emp_record.birthday),
'Company': (emp_record.address_id and emp_record.address_id.sudo().name or '').encode('utf-8'),
'Bereich': (emp_record.bereich and emp_record.bereich.name or '').encode('utf-8'),
'Team': (emp_record.department_id and emp_record.department_id.name or '').encode('utf-8'),
'Planstellenbezeichnung': (emp_record.planned_job_id and emp_record.planned_job_id.name or '').encode('utf-8'),
'Stellenbezeichnung': (emp_record.job_id and emp_record.job_id.name or '').encode('utf-8'),
'Vertragstyp': (emp_record.sudo().contract_type and emp_record.sudo().contract_type.name or '').encode('utf-8'),
'Ersteintrittsdatum': self.get_date_format(emp_record.initial_date),
'Enddatum befristeter Vertrag': self.get_date_format(emp_record.temp_contract_end_date),
'Befristungsgrund': (emp_record.contract_limitation_reason and emp_record.contract_limitation_reason.name or '').encode('utf-8'),
'Probezeit Enddatum': self.get_date_format(emp_record.contract_trial_end_date),
'letztes MA Gespraech': self.get_date_format(emp_record.last_ma_conversation_date),
'5-Jahresjubilaeum': self.get_date_format(emp_record.five_years),
'Arbeitszeit': (emp_record.contract_working_hours and emp_record.contract_working_hours.name or '').encode('utf-8'),
'Urlaub': emp_record.contract_leaves or '',
'Schwerbehinderung': ('ja' if emp_record.disability=='yes' else 'nein' or ''),
# 'letzte Vertragsaenderung_L&G': emp_record.last_contract_changed_wage or '',
'letzte Vertragsaenderung_L&G': ("%.2f" % emp_record.last_contract_changed_wage).replace('.',',') or '',
'Startdatum der letzten Vertragversänderung':self.get_date_format(emp_record.last_contract_changed_date),
'Verguetung': ("%.2f" % emp_record.emp_wage_cal).replace('.',',') or '',
# 'Verguetung bei VZ': emp_record.compensation_at_vz or '',
'Verguetung bei VZ': ("%.2f" % emp_record.compensation_at_vz).replace('.',',') or '',
# 'Verguetung inkl. AG Kosten (25%)': emp_record.remuneration_incl_ag_costs or '',
'Verguetung inkl. AG Kosten (25%)': ("%.2f" % emp_record.remuneration_incl_ag_costs).replace('.',',') or '',
'BR Mitglied': ('ja' if emp_record.br_member=='yes' else 'nein' or '').encode('utf-8'),
'Bemerkungen': (notes).encode('utf-8'),
'Manager': (emp_record.parent_id and emp_record.parent_id.name or '').encode('utf-8'),
}
data_list.append(vals)
with open(csv_path, 'wb') as csvfile:
w = csv.DictWriter(csvfile, fieldnames=csv_header, delimiter=';',quoting=csv.QUOTE_ALL)
w.writeheader()
w.writerows(data_list)
csvfile.close()
data = ''
with open(csv_path, 'rb') as csvfile:
data = csvfile.read()
data = data.encode('base64')
csvfile.close()
context = self._context.copy()
file_name = datetime.now().strftime('%Y%m%d_%H_%M')+'_'+csv_name+ '.csv'
context.update({'default_name': data, 'default_file_name':file_name})
os.remove(csv_path)
return context

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="employee_data_export_form_view" model='ir.ui.view'>
<field name="name">emloyee.data.export.form.view</field>
<field name="model">employee.data.export</field>
<field name="arch" type="xml">
<form>
<label string="Click 'Export' button to export employee data csv" />
<div attrs="{'invisible': [('name', '=', False)]}">
<p>Export file: <field name="name" readonly="1" filename="file_name"/></p>
</div>
<field name='file_name' invisible="1"/>
<group>
<field name='report_selection'/>
</group>
<footer>
<button name='export_emp_data_csv' type='object' string="Export" />
or
<button special="cancel" string="Cancel" class='oe_link' />
</footer>
</form>
</field>
</record>
<record id="employee_data_export_action" model="ir.actions.act_window">
<field name="name">Personalübersicht Export</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">employee.data.export</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<act_window id="launch_employee_data_export_wizard"
name="Personalübersicht Export"
src_model="hr.employee"
res_model="employee.data.export"
view_mode="form,tree"
target="new"
key2="client_action_multi"
groups='base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user'/>
</data>
</openerp>

View File

@ -0,0 +1,327 @@
# -*- coding: utf-8 -*-
from openerp import models, api, fields, _
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
from datetime import datetime
from dateutil.relativedelta import relativedelta
from calendar import monthrange
import csv
import os
import base64
def get_years():
year = []
for i in range(2016,2040):
year.append((i,str(i)))
return year
class create_emp_payroll(models.TransientModel):
_name = 'create.emp.payroll'
@api.model
def _default_date_from(self):
date = datetime.today().date()
last_month_date = (date - relativedelta(months= 1)).replace(day=20)
return last_month_date
@api.model
def _default_date_to(self):
date = datetime.today().date().replace(day=20)
return date
@api.model
def _default_month(self):
date = datetime.today().date()
return date.month
@api.model
def _default_year(self):
date = datetime.today().date()
return date.year
month = fields.Selection([(1,'January'),(2,'February'),(3,'March'),(4,'April'),(5,'May'),(6,'June')
,(7,'July'),(8,'Augast'),(9,'September'),(10,'October'),(11,'November'),(12,'December')],default =_default_month,string='Month')
year = fields.Selection(get_years(),default =_default_year,string='Year')
date_from = fields.Date('Date From',default =_default_date_from)
date_to = fields.Date('Date To',default =_default_date_to)
@api.multi
def generate_employee_report(self):
emp_payroll_report = self.env['employee.payroll.report']
record_ids = []
hr_contract_records = self.env['hr.contract'].search([('employee_id','!=',False)],order='employee_id')
# hr_contract_records = self.env['hr.contract'].search([('id','=',169)],order='employee_id')
for hr_contract_brw in hr_contract_records:
if hr_contract_brw.date_start:
# print"hr_contract_brw----",hr_contract_brw
# ----------------to calculate the selected year month combination for the contract
selected_year_month = str(self.year)+'-'+str(self.month)
# print"selected_year_month------",selected_year_month
contract_date_start = datetime.strptime(hr_contract_brw.date_start,'%Y-%m-%d').date()
if hr_contract_brw.date_end:
contract_date_end = datetime.strptime(hr_contract_brw.date_end,'%Y-%m-%d').date()
else:
contract_date_end = datetime.today().date()
#Added newly
selected_month_range = monthrange(self.year,self.month)
selected_month_enddate = datetime.strptime(selected_year_month+'-'+str(selected_month_range[1]),'%Y-%m-%d').date()
if contract_date_end < selected_month_enddate:
contract_date_end = selected_month_enddate
contract_date_start_new = contract_date_start.replace(day=1)
contract_date_end_new = contract_date_end.replace(day=1)
# print"contract_date_start_new----",contract_date_start_new
# print"contract_date_end_new----",contract_date_end_new
contracted_year_months = []
while contract_date_start_new <=contract_date_end_new:
data = str(contract_date_start_new.year)+'-'+str(contract_date_start_new.month)
contracted_year_months.append(data)
contract_date_start_new = contract_date_start_new + relativedelta(months= 1)
# print"contracted_year_months----",contracted_year_months
# Selected year and month criteria
# if contract_date_start.year <= self.year and contract_date_start.month <= self.month and contract_date_end.year >= self.year and contract_date_end.month >= self.month:
if selected_year_month in contracted_year_months:
# print"Active Contract------",hr_contract_brw.name
# print"Employee Name ------",hr_contract_brw.employee_id.name
# --------------to calculate gross salary
gross_salary = 0.0
hr_payslip = self.env['hr.payslip']
selected_month_range = monthrange(self.year,self.month)
period_start_date = datetime.strptime(selected_year_month+'-01','%Y-%m-%d').date()
period_end_date = datetime.strptime(selected_year_month+'-'+str(selected_month_range[1]),'%Y-%m-%d').date()
if contract_date_start <= period_start_date:
period_contract_start_date =str(period_start_date)
else:
period_contract_start_date =str(contract_date_start)
if contract_date_end >= period_end_date:
period_contract_end_date =str(period_end_date)
else:
period_contract_end_date =str(contract_date_end)
#To check for the date and values
if period_contract_start_date > period_contract_end_date:
period_contract_end_date = period_contract_start_date
#period_contract_end_date = period_contract_start_date
# print"period_contract_start_date------",period_contract_start_date
# print"period_contract_end_date------",period_contract_end_date
# print"contract_date_end------",contract_date_end
payslip_values = {'employee_id':hr_contract_brw.employee_id.id,'date_from':period_contract_start_date,'date_to':period_contract_end_date,
'contract_id':hr_contract_brw.id,'struct_id':hr_contract_brw.struct_id.id,'journal_id':1 }
hr_payslip_brw=hr_payslip.sudo().create(payslip_values)
res = self.pool.get('hr.payslip').onchange_employee_id(self._cr, self._uid, [], period_contract_start_date, period_contract_end_date,
hr_contract_brw.employee_id.id, hr_contract_brw.id, None)
if res and res.get('value'):
value = res.get('value')
worked_days_line_ids = value.get('worked_days_line_ids')
for line_rec in worked_days_line_ids:
line_rec.update({'payslip_id':hr_payslip_brw.id})
self.env['hr.payslip.worked_days'].create(line_rec)
hr_payslip_brw.compute_sheet()
for data in hr_payslip_brw.details_by_salary_rule_category:
if data.code == "NET":
gross_salary = data.total
hr_payslip_brw.unlink()
# ---------------to calculate sick days
sick_days = 0.0
selected_date_from = datetime.strptime(self.date_from,'%Y-%m-%d').date()
selected_date_to = datetime.strptime(self.date_to,'%Y-%m-%d').date()
if contract_date_start<= selected_date_from:
sick_leave_start_date = selected_date_from
else:
sick_leave_start_date = contract_date_start
if contract_date_end >= selected_date_to:
sick_leave_end_date = selected_date_to
else:
sick_leave_end_date = contract_date_end
while sick_leave_start_date <=sick_leave_end_date:
# print"sick_leave_start_date----",sick_leave_start_date
hr_analytic_env = self.env['hr.analytic.timesheet']
search_domain = [
('date', '=', str(sick_leave_start_date)),
('user_id', '=',hr_contract_brw.employee_id.user_id.id),
('account_id', '=', hr_contract_brw.employee_id.company_id.sick_account_id.id)
]
timesheet_line_ids = hr_analytic_env.search(search_domain)
# print"timesheet_line_ids--------",timesheet_line_ids
if len(timesheet_line_ids):
for line in timesheet_line_ids:
for plan in line.sheet_id.planned_ids:
if plan.sheet_date == line.date and plan.duration:
sick_days +=line.unit_amount/plan.duration
sick_days = float("{0:.2f}".format(sick_days))
# print"sick_days--------",sick_days
# sick_day_status = self.env['hr.holidays.status'].search([('is_sick_leave_type','=',True)],limit=1)
# if sick_day_status:
# sick_day_leave_records = self.env['hr.holidays'].search([('holiday_status_id','=',sick_day_status.id),('state','=','validate'),
# ('employee_id','=',hr_contract_brw.employee_id.id),('date_from','<=',str(sick_leave_start_date)),('date_to','>=',str(sick_leave_start_date))],limit=1)
#
# if sick_day_leave_records:
# leave_date_from = datetime.strptime(sick_day_leave_records.date_from,DEFAULT_SERVER_DATETIME_FORMAT).date()
# leave_date_to = datetime.strptime(sick_day_leave_records.date_to,DEFAULT_SERVER_DATETIME_FORMAT).date()
# if leave_date_from == sick_leave_start_date and leave_date_to == sick_leave_start_date:
# sick_days += sick_day_leave_records.number_of_days_temp
# else:
# if leave_date_from == sick_leave_start_date and sick_day_leave_records.leave_selection =='half_day':
# sick_days +=0.5
# elif leave_date_to == sick_leave_start_date and sick_day_leave_records.leave_selection_date_to =='half_day':
# sick_days +=0.5
# else:
# sick_days +=1
sick_leave_start_date = sick_leave_start_date+relativedelta(days=1)
# print"sick_days------",sick_days
# ----------------For coloring base on the last modification date
change_record,employee_brw='N',hr_contract_brw.employee_id
if self.date_from and self.date_to:
if hr_contract_brw.write_date >= self.date_from and hr_contract_brw.write_date <= self.date_to and \
employee_brw.write_date >= self.date_from and employee_brw.write_date <= self.date_to:
change_record = 'SV'
elif self.date_from <= hr_contract_brw.write_date and self.date_to >= hr_contract_brw.write_date:
change_record = 'V'
elif self.date_from <= employee_brw.write_date and self.date_to >= employee_brw.write_date:
change_record = 'ST'
# ----------------To get a wage base on the hourly basis time
wage =0.0
if hr_contract_brw:
wage = hr_contract_brw.wage
vals = {'contract_id':hr_contract_brw.id,'employee_id':hr_contract_brw.employee_id.id,
'record_change':change_record,'sick_days':sick_days,'gross_salary':gross_salary,'wage':wage}
record_ids.append(emp_payroll_report.create(vals).id)
emp_payroll_report_tree_view = self.env.ref('itis_hr_extend.itis_emp_payroll_report_tree', False)
return {
'name': ("Employee Report"),
'view_mode': 'tree',
'view_id': False,
'view_type': 'form',
'res_model': 'employee.payroll.report',
'type': 'ir.actions.act_window',
'target': 'current',
'domain': "[('id', 'in', %s)]" % record_ids,
'views': [(emp_payroll_report_tree_view and emp_payroll_report_tree_view.id or False, 'tree')],
'context': {}
}
class export_emp_payroll(models.TransientModel):
_name = 'export.emp.payroll'
name = fields.Binary('Employee Report CSV')
file_name = fields.Char('File')
@api.multi
def export_csv(self):
"""
This function is use to export the employee payroll report
"""
emp_payroll_report = self.env['employee.payroll.report']
if self._context and 'active_model' in self._context and self._context['active_model'] == 'employee.payroll.report':
emp_payroll_report_records = emp_payroll_report.browse(self._context['active_ids'])
data_list = []
csv_header = ['record_change','Personal-Nr', 'Name', 'Vorname', "Geburtsdatum", "Privatanschrift",'Bankverbindung','Krankenkasse',
'Schwerbehinderung','Schwerbehinderung Gültigkeit','Familienstand','Anzahl Kinder', 'Vertragsreferenz','Vertragsbeginn','Vertragsende',
'Arbeitszeit','Vergütungsmodell','Bruttogehalt','Wage','Krankheitstage','Bemerkung Vertragsinformationen']
time_csv = datetime.now().strftime('%Y-%m-%d_%H_%M_%S') + '.csv'
csv_path = "/tmp/" + time_csv
for emp_report_brw in emp_payroll_report_records:
bank_info =''
if emp_report_brw.bank_account_id:
bank_account_id = emp_report_brw.bank_account_id
if bank_account_id.state =='iban':
bank_info = (bank_account_id.bank_name or ' ') +' '+'IBAN '+(bank_account_id.acc_number or' ')
else:
bank_info = (bank_account_id.bank_name or' ')+' '+(bank_account_id.acc_number or' ')
if bank_account_id.bank_bic:
bank_info = bank_info+' BIC- '+bank_account_id.bank_bic
#
record_change = emp_report_brw.record_change
if record_change =='V':
record_change = ''
vals = {
'record_change': record_change,
'Personal-Nr':(emp_report_brw.identification_id or '').encode('utf-8'),
"Name": (emp_report_brw.name or '').encode('utf-8'),
'Vorname': (emp_report_brw.surname or '').encode('utf-8'),
'Geburtsdatum': emp_report_brw.birthday or '',
'Privatanschrift': (emp_report_brw.address_home_id or '').encode('utf-8') ,
'Bankverbindung': bank_info.encode('utf-8'),
'Krankenkasse': (emp_report_brw.health_insurance and emp_report_brw.health_insurance.name or '').encode('utf-8'),
'Schwerbehinderung': emp_report_brw.disability or '',
'Schwerbehinderung Gültigkeit':emp_report_brw.disability_limited_until or '',
'Familienstand': emp_report_brw.family_status and emp_report_brw.family_status.name or '',
'Anzahl Kinder': emp_report_brw.children,
'Vertragsreferenz':(emp_report_brw.contract_name or '').encode('utf-8'),
'Vertragsbeginn':emp_report_brw.contract_start_date,
'Vertragsende':emp_report_brw.contract_end_date or '',
'Arbeitszeit':(emp_report_brw.working_hours and emp_report_brw.working_hours.name or '').encode('utf-8'),
'Vergütungsmodell':(emp_report_brw.struct_id and emp_report_brw.struct_id.name or '').encode('utf-8'),
'Bruttogehalt':emp_report_brw.gross_salary,
'Wage':emp_report_brw.wage,
'Krankheitstage':emp_report_brw.sick_days,
'Bemerkung Vertragsinformationen':(emp_report_brw.notes or '').replace('\n',' ').encode('utf-8'),
}
data_list.append(vals)
with open(csv_path, 'wb') as csvfile:
w = csv.DictWriter(csvfile, fieldnames=csv_header, delimiter=',', quoting=csv.QUOTE_ALL)
w.writeheader()
w.writerows(data_list)
csvfile.close()
data = ''
with open(csv_path, 'rb') as csvfile:
data = csvfile.read()
data = data.encode('base64')
csvfile.close()
context = self._context.copy()
context.update({'default_name': data, 'default_file_name': 'employee_report_export_' + time_csv})
os.remove(csv_path)
return {
'name': _('Exported Employee Report'),
'view_type': 'form',
"view_mode": 'form',
'res_model': 'export.emp.payroll',
'type': 'ir.actions.act_window',
'context': context,
'target':'new',
}

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="emp_payroll_wiz_form_view" model='ir.ui.view'>
<field name="name">emp.payroll.wiz.form.view</field>
<field name="model">create.emp.payroll</field>
<field name="arch" type="xml">
<form>
<label string="Click 'Generate' button to Generate Employee report" />
<group>
<field name="month" required="1"/>
<field name="year" required="1"/>
</group>
<group>
<field name="date_from" />
<field name="date_to" />
</group>
<footer>
<button name='generate_employee_report' type='object' string="Generate" />
or
<button special="cancel" string="Cancel" class='oe_link' />
</footer>
</form>
</field>
</record>
<record id="emp_payroll_window_action" model="ir.actions.act_window">
<field name="name">Employee Payroll Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">create.emp.payroll</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem name="Generate Employee Payroll Report" parent="menu_hr_reports"
action="emp_payroll_window_action" id="menu_emp_payroll_report_generate"
groups='base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user'/>
<record id="emp_payroll_export_form_view" model='ir.ui.view'>
<field name="name">emp.payroll.export.form.view</field>
<field name="model">export.emp.payroll</field>
<field name="arch" type="xml">
<form>
<label string="Click 'Export' button to export Employee Report csv" />
<div attrs="{'invisible': [('name', '=', False)]}">
<p>Export file: <field name="name" readonly="1" filename="file_name"/></p>
</div>
<field name='file_name' invisible="1"/>
<footer>
<button name='export_csv' type='object' string="Export" />
or
<button special="cancel" string="Cancel" class='oe_link' />
</footer>
</form>
</field>
</record>
<record id="emp_payroll_export_action" model="ir.actions.act_window">
<field name="name">Employee Report Export</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">export.emp.payroll</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<act_window id="launch_emp_payroll_export_wizard"
name="Employee Report Export"
src_model="employee.payroll.report"
res_model="export.emp.payroll"
view_mode="form,tree"
target="new"
key2="client_action_multi"/>
</data>
</openerp>

View File

@ -0,0 +1,108 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
class create_fte(models.TransientModel):
_name = 'create.fte'
@api.model
def check_parent(self, dep_dict, parent, pass_list):
dep_env = self.env['hr.department']
for dep in dep_env.browse(dep_dict.keys()):
if dep.id not in pass_list:
if dep.parent_id.id == parent:
return False
return True
@api.model
def compute_child(self, dep, dep_dict, parent_list, pass_list):
# print "dep_dict", dep_dict
if dep.parent_id:
# print parent_list,">>" , dep.name, ">>", dep.parent_id.name, '=', dep_dict.get(dep.id)
if dep.parent_id.id not in parent_list:
if not dep_dict.get(dep.parent_id.id):
dep_dict[dep.parent_id.id] = dep_dict.get(dep.id)
else:
dep_dict[dep.parent_id.id] += dep_dict.get(dep.id)
if dep_dict.get(dep.id) and self.check_parent(dep_dict, dep.parent_id.id, pass_list):
parent_list.append(dep.parent_id.id)
else:
dep_dict[dep.parent_id.id] = dep_dict.get(dep.id)
self.compute_child(dep.parent_id, dep_dict, parent_list, pass_list)
else:
if not dep_dict.get(dep.parent_id.id):
dep_dict[dep.id] = dep_dict.get(dep.id)
else:
dep_dict[dep.id] += dep_dict.get(dep.id)
return dep_dict, parent_list
@api.model
def calc_fte(self, dep_dict):
dep_env = self.env['hr.department']
parent_list = []
pass_list = []
for dep in dep_env.browse(dep_dict.keys()):
pass_list.append(dep.id)
dep_dict, parent_list = self.compute_child(dep, dep_dict, parent_list, pass_list)
# print "dep_dict", dep_dict
return dep_dict
@api.multi
def generate_fte_report(self):
department_env = self.env['hr.department']
employee_env = self.env['hr.employee']
dep_dict = {}
for emp in employee_env.search([]):
# print emp.fte, emp.name
for fte in emp.fte_ids:
if not dep_dict.get(fte.department_id.id):
dep_dict[fte.department_id.id] = (fte.fte/100) * emp.fte
else:
dep_dict[fte.department_id.id] += (fte.fte/100) * emp.fte
fte_list = []
dep_dict = self.calc_fte(dep_dict)
for dep in department_env.search([]):
vals = {
'department_id': dep.id,
'planned_fte': dep.planned_fte,
'fte': dep_dict.get(dep.id, 0.0),
'diff_fte': dep.planned_fte - dep_dict.get(dep.id, 0.0)
}
fte_list.append((0,0,vals))
fte = self.env['fte.report'].create({'fte_ids': fte_list})
fte_view = self.env.ref('itis_hr_extend.itis_fte_report_form', False)
return {
'name': _('FTE Report'),
'view_type': 'form',
'view_mode': 'form',
'res_model': 'fte.report',
'views': [(fte_view.id,'form')],
'type': 'ir.actions.act_window',
'target': 'current',
'res_id':fte.id
}

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="fte_wiz_form_view" model='ir.ui.view'>
<field name="name">fte.wiz.form.view</field>
<field name="model">create.fte</field>
<field name="arch" type="xml">
<form>
<label string="Click 'Generate' button to Generate FTE report" />
<footer>
<button name='generate_fte_report' type='object' string="Generate" />
or
<button special="cancel" string="Cancel" class='oe_link' />
</footer>
</form>
</field>
</record>
<record id="fte_window_action" model="ir.actions.act_window">
<field name="name">FTE Report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">create.fte</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem name="Generate FTE Report" parent="menu_hr_reports"
action="fte_window_action" id="menu_fte_report_generate"
groups='base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user'/>
</data>
</openerp>

View File

@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
from datetime import datetime, timedelta
class OTChange(models.TransientModel):
_name = "ot.change"
reason = fields.Char("Reason")
ot_time = fields.Float("Overtime Count")
leave_day = fields.Float("Leave Day")
@api.model
def default_get(self, fields):
res = super(OTChange, self).default_get(fields)
emp_id = self.env.context.get("active_id")
emp_rec = self.env['hr.employee'].browse(emp_id)
if self.env.context.get("from_ot_change", False):
# res.update({'ot_time': emp_rec.overtime_count})
res.update({'ot_time': emp_rec.employee_overtime_id.emp_overtime_count})
else:
res.update({'leave_day': emp_rec.additional_leave_days})
return res
@api.multi
def set_ot_time(self):
emp_id = self.env.context.get("active_id")
emp_rec = self.env['hr.employee'].browse(emp_id)
if self.env.context.get("from_ot_change", False):
emp_rec.update_overtime_count(self.ot_time, self.reason)
else:
emp_rec.update_leave_day(self.leave_day, self.reason)
return True
class LDChange(models.TransientModel):
_name = "ld.change"
reason = fields.Char("Reason")
type = fields.Selection([('add', 'Hinzufügen'),('sub', 'Abziehen')], "Type")
leave_day = fields.Float("Leave Day")
@api.multi
def set_ld_time(self):
leave_journal_obj = self.env['hr.leave.journal']
leave_days = self.leave_day
if self.type == 'sub':
leave_days = leave_days * -1
values = {
'employee_id': self.env.context.get("active_id"),
'year': datetime.today().year,
'year_type': 'actual',
'type': 'manual',
'leave_type':'days',
'leave_days': leave_days,
'name': self.reason + ' ' + self.env['res.users'].browse(self._uid).name + ' ' + datetime.now().strftime('%d%m%Y %H:%M:%S'),
}
leave_journal_obj.create(values)
#for SOW17
@api.multi
def set_nextyear_ld_time(self):
"""Add a logic to give ability to change leave day for the next year.
User can only change it after May month
"""
leave_journal_obj = self.env['hr.leave.journal']
leave_days = self.leave_day
if self.type == 'sub':
leave_days = leave_days * -1
values = {
'employee_id': self.env.context.get("active_id"),
'year': datetime.today().year+1,
'year_type': 'next',
'type': 'manual',
'leave_type':'days',
'leave_days': leave_days,
'name': self.reason + ' ' + self.env['res.users'].browse(self._uid).name + ' ' + datetime.now().strftime('%d%m%Y %H:%M:%S'),
}
leave_journal_obj.create(values)

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- vim:fdn=3:
-->
<openerp>
<data>
<record id="ot_change_form_view" model='ir.ui.view'>
<field name="name">ot_change_form_view</field>
<field name="model">ot.change</field>
<field name="arch" type="xml">
<form>
<group>
<field name="ot_time" required="1" widget="float_time" invisible="context.get('from_ld_change')"/>
<field name="leave_day" required="1" invisible="context.get('from_ot_change')"/>
<field name="reason" required="1" />
</group>
<footer>
<button name="set_ot_time" string="OK" type="object" class='oe_highlight'/>
or
<button special="cancel" string="Cancel" class='oe_link' />
</footer>
</form>
</field>
</record>
<record id="ld_change_form_view" model='ir.ui.view'>
<field name="name">ld_change_form_view</field>
<field name="model">ld.change</field>
<field name="arch" type="xml">
<form>
<group>
<field name="type" required="1" />
<field name="leave_day" required="1" />
<field name="reason" required="1" />
</group>
<footer>
<button name="set_ld_time" string="OK" type="object" class='oe_highlight' invisible="context.get('next_year', False)"/>
<button name="set_nextyear_ld_time" string="OK" type="object" class='oe_highlight' invisible="context.get('current_year', False)"/>
or
<button special="cancel" string="Cancel" class='oe_link' />
</footer>
</form>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from . import wizard
from . import models

View File

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': "ITIS HR Leave Extend",
'summary': """ Module will extend Human Ressources leave""",
'description': """
Module to extend the functionalities of the HR module.
""",
'author': "IT IS AG",
'website': "http://www.itis-odoo.de",
'category': 'base',
'version': '1.0.55.0',
'depends': ['itis_hr_extend','itis_hr_attendance_extend'],
'data': [
'views/hr_setting_view.xml',
'security/ir.model.access.csv',
'wizard/hr_sick_leave.xml'
],
'css': [],
'demo': [],

View File

@ -0,0 +1,208 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * itis_hr_leave_extend
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-07 13:17+0000\n"
"PO-Revision-Date: 2017-06-07 15:19+0100\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.4\n"
#. module: itis_hr_leave_extend
#: field:hr.config.settings,leave_account_id:0
#: field:res.company,leave_account_id:0
msgid "Analytic Account for Leave"
msgstr "Kosenstelle für Urlaub"
#. module: itis_hr_leave_extend
#: field:hr.config.settings,ot_leave_account_id:0
#: field:res.company,ot_leave_account_id:0
msgid "Analytic Account for Overtime Leave"
msgstr "Kostenstelle für Überstundenabbau"
#. module: itis_hr_leave_extend
#: view:hr.config.settings:itis_hr_leave_extend.view_human_resources_configuration
msgid "Analytic account"
msgstr "Kostenstelle"
#. module: itis_hr_leave_extend
#: view:hr.sick.leave:itis_hr_leave_extend.sick_leave_form_view
msgid "Cancel"
msgstr "Cancel"
#. module: itis_hr_leave_extend
#: model:ir.model,name:itis_hr_leave_extend.model_res_company
msgid "Companies"
msgstr "Unternehmen"
#. module: itis_hr_leave_extend
#: field:hr.holidays.timesheet,create_uid:0 field:hr.sick.leave,create_uid:0
msgid "Created by"
msgstr "Erstellt von"
#. module: itis_hr_leave_extend
#: field:hr.holidays.timesheet,create_date:0 field:hr.sick.leave,create_date:0
msgid "Created on"
msgstr "Erstellt am"
#. module: itis_hr_leave_extend
#: field:hr.holidays.timesheet,date:0
msgid "Date"
msgstr "Datum"
#. module: itis_hr_leave_extend
#: field:hr.sick.leave,end_date:0
msgid "End Date"
msgstr "End Date"
#. module: itis_hr_leave_extend
#: model:ir.actions.act_window,name:itis_hr_leave_extend.launch_sick_leave_wizard
msgid "Fill Employee Sick Leave"
msgstr "Krankheitstage erfassen"
#. module: itis_hr_leave_extend
#: model:ir.actions.act_window,name:itis_hr_leave_extend.sick_leave_action
msgid "Fill Sick Leave"
msgstr "Krankheitstage erfassen"
#. module: itis_hr_leave_extend
#: view:hr.sick.leave:itis_hr_leave_extend.sick_leave_form_view
msgid "Fill Sick Time"
msgstr "Krankentage buchen."
#. module: itis_hr_leave_extend
#: field:hr.holidays.timesheet,holiday_id:0
msgid "Holiday"
msgstr "Urlaub"
#. module: itis_hr_leave_extend
#: field:hr.holidays.timesheet,duration:0
msgid "Hours"
msgstr "Stunden"
#. module: itis_hr_leave_extend
#: field:hr.holidays.timesheet,id:0 field:hr.sick.leave,id:0
msgid "ID"
msgstr "ID"
#. module: itis_hr_leave_extend
#: field:hr.holidays.timesheet,write_uid:0 field:hr.sick.leave,write_uid:0
msgid "Last Updated by"
msgstr "Aktualisiert von"
#. module: itis_hr_leave_extend
#: field:hr.holidays.timesheet,write_date:0 field:hr.sick.leave,write_date:0
msgid "Last Updated on"
msgstr "Aktualisiert am"
#. module: itis_hr_leave_extend
#: model:ir.model,name:itis_hr_leave_extend.model_hr_holidays
msgid "Leave"
msgstr "Urlaub"
#. module: itis_hr_leave_extend
#: model:ir.model,name:itis_hr_leave_extend.model_hr_holidays_status
msgid "Leave Type"
msgstr "Abwesenheitstyp"
#. module: itis_hr_leave_extend
#: code:addons/itis_hr_leave_extend/models/hr_holiday.py:148
#, python-format
msgid "Please define cost unit for this employee."
msgstr "Bitte definieren Sie ein Konstenjournal für diesen Mitarbeiter."
#. module: itis_hr_leave_extend
#: code:addons/itis_hr_leave_extend/models/hr_holiday.py:121
#, python-format
msgid ""
"Please set the analytic account for Leaves.\n"
"Please contact your administrator for the same."
msgstr ""
"Bitte hinterlegen Sie die Kostenstelle für Urlaub.Bitte kontaktieren Sie "
"dafür Ihren Administrator."
#. module: itis_hr_leave_extend
#: code:addons/itis_hr_leave_extend/wizard/hr_sick_leave.py:55
#, python-format
msgid ""
"Please set the analytic account for Sick Leaves.\n"
"Please contact your administrator for the same."
msgstr ""
"Bitte hinterlegen Sie die Kostenstelle für Krankheit\n"
"Bitte kontaktieren Sie dafür ihren Administrator."
#. module: itis_hr_leave_extend
#: field:hr.holidays.timesheet,sheet_id:0
msgid "Sheet"
msgstr "Sheet"
#. module: itis_hr_leave_extend
#: field:hr.sick.leave,start_date:0
msgid "Start Date"
msgstr "Start Date"
#. module: itis_hr_leave_extend
#: code:addons/itis_hr_leave_extend/models/hr_holiday.py:133
#, python-format
msgid ""
"The Time period is allready closed. \n"
" Please contact the Human Resource Team if the leave request should be "
"confirmed nevertheless"
msgstr ""
"Die Zeiterfassung für den entsprechenden Zeitraum ist bereits "
"abgeschlossen. \n"
"Bitte wenden Sie sich an die Peronalabteilung, wenn der Antrag trotzdem "
"genehmigt werden soll."
#. module: itis_hr_leave_extend
#: view:hr.sick.leave:itis_hr_leave_extend.sick_leave_form_view
msgid "This wizard is use to fill up the time sheet when employee is sick."
msgstr ""
"Mit dieser Maske kann die Krankheitszeit eines Mitarbeiters in dessen "
"Abwesenheit erfasst und gebucht werden."
#. module: itis_hr_leave_extend
#: field:hr.holidays,holidays_timesheet_ids:0
#: field:hr.holidays.timesheet,timesheet_id:0
#: model:ir.model,name:itis_hr_leave_extend.model_hr_timesheet_sheet_sheet
msgid "Timesheet"
msgstr "Zeiterfassung"
#. module: itis_hr_leave_extend
#: code:addons/itis_hr_leave_extend/models/hr_holiday.py:148
#, python-format
msgid "User Error!"
msgstr "Benutzerfehler!"
#. module: itis_hr_leave_extend
#: code:addons/itis_hr_leave_extend/wizard/hr_sick_leave.py:145
#, python-format
msgid ""
"User Error! \n"
"Please define cost unit for this employee."
msgstr ""
"Fehler! \n"
"Bitte legen Sie eine Kostenstelle für den Mitarbeiter fest."
#. module: itis_hr_leave_extend
#: view:hr.config.settings:itis_hr_leave_extend.view_human_resources_configuration
msgid "for Leave"
msgstr "für Urlaub"
#. module: itis_hr_leave_extend
#: view:hr.config.settings:itis_hr_leave_extend.view_human_resources_configuration
msgid "for Overtime Leave"
msgstr "für Überstundenabbau"
#. module: itis_hr_leave_extend
#: view:hr.sick.leave:itis_hr_leave_extend.sick_leave_form_view
msgid "or"
msgstr "or"

View File

@ -0,0 +1,835 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * itis_hr_extend
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-04-19 15:57+0000\n"
"PO-Revision-Date: 2017-04-19 17:59+0100\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.4\n"
#. module: itis_hr_extend
#: field:hr.employee,five_years:0
msgid "5-Jahres-Jubiläum"
msgstr "5 year anniversary"
#. module: itis_hr_extend
#: selection:ld.change,type:0
msgid "Abziehen"
msgstr "Substract"
#. module: itis_hr_extend
#: view:itis.hr.contact:itis_hr_extend.itis_hr_contact_form
msgid "Address"
msgstr "Address"
#. module: itis_hr_extend
#: field:hr.employee,active_employee:0
msgid "Aktiv"
msgstr "active"
#. module: itis_hr_extend
#: field:hr.holidays,approved_at:0
msgid "Approved/Refuse At"
msgstr "Approved/Refuse At"
#. module: itis_hr_extend
#: field:hr.holidays,approved_by:0
msgid "Approved/Refuse By"
msgstr "Approved/Refuse By"
#. module: itis_hr_extend
#: selection:hr.leave.journal,type:0
msgid "Ausgleich"
msgstr "Compensation"
#. module: itis_hr_extend
#: field:hr.employee,disability_limited_until:0
msgid "Befristet bis"
msgstr "Limited until"
#. module: itis_hr_extend
#: field:hr.contract,limitation_reason:0
msgid "Befristungsgrund"
msgstr "reason of Limitation"
#. module: itis_hr_extend
#: field:hr.leave.journal,description:0 field:hr.leave.journal,name:0
msgid "Begründung"
msgstr "reason"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:280
#: code:addons/itis_hr_extend/models/hr_employee.py:326
#, python-format
msgid "Berechnung Urlaub zu Jahresbeginn"
msgstr "calculation year leaves"
#. module: itis_hr_extend
#: field:hr.employee,bereich:0
msgid "Bereich"
msgstr "Section"
#. module: itis_hr_extend
#: field:itis_confession,name:0 field:itis_limitation_reason,name:0
msgid "Bezeichnung"
msgstr "Name"
#. module: itis_hr_extend
#: view:create.fte:itis_hr_extend.fte_wiz_form_view
#: view:ld.change:itis_hr_extend.ld_change_form_view
#: view:ot.change:itis_hr_extend.ot_change_form_view
msgid "Cancel"
msgstr "Cancel"
#. module: itis_hr_extend
#: view:itis.hr.contact:itis_hr_extend.itis_hr_contact_form
#: field:itis.hr.contact,city:0
msgid "City"
msgstr "City"
#. module: itis_hr_extend
#: view:create.fte:itis_hr_extend.fte_wiz_form_view
msgid "Click 'Generate' button to Generate FTE report"
msgstr "Click 'Generate' button to Generate FTE report"
#. module: itis_hr_extend
#: field:employee.report.data,color:0
msgid "Color"
msgstr "Color"
#. module: itis_hr_extend
#: model:ir.actions.act_window,name:itis_hr_extend.action_itis_hr_contact
#: view:itis.hr.contact:itis_hr_extend.itis_hr_contact_tree
msgid "Contacts"
msgstr "Contacts"
#. module: itis_hr_extend
#: model:ir.model,name:itis_hr_extend.model_hr_contract
msgid "Contract"
msgstr "Contract"
#. module: itis_hr_extend
#: field:hr.leave.journal,contract_id:0
msgid "Contract id"
msgstr "Contract id"
#. module: itis_hr_extend
#: view:itis.hr.contact:itis_hr_extend.itis_hr_contact_form
#: field:itis.hr.contact,country_id:0
msgid "Country"
msgstr "Country"
#. module: itis_hr_extend
#: field:create.fte,create_uid:0 field:employee.report,create_uid:0
#: field:employee.report.data,create_uid:0 field:fte.records,create_uid:0
#: field:fte.report,create_uid:0 field:hr.employee.fte,create_uid:0
#: field:hr.family.status,create_uid:0 field:hr.health.insurance,create_uid:0
#: field:hr.leave.journal,create_uid:0 field:itis.hr.contact,create_uid:0
#: field:itis.leave.days.calc.error,create_uid:0
#: field:itis_confession,create_uid:0
#: field:itis_employee_children,create_uid:0
#: field:itis_limitation_reason,create_uid:0 field:ld.change,create_uid:0
#: field:ot.change,create_uid:0
msgid "Created by"
msgstr "Created by"
#. module: itis_hr_extend
#: field:create.fte,create_date:0 field:employee.report,create_date:0
#: field:employee.report.data,create_date:0 field:fte.records,create_date:0
#: field:fte.report,create_date:0 field:hr.employee.fte,create_date:0
#: field:hr.family.status,create_date:0
#: field:hr.health.insurance,create_date:0
#: field:hr.leave.journal,create_date:0 field:itis.hr.contact,create_date:0
#: field:itis.leave.days.calc.error,create_date:0
#: field:itis_confession,create_date:0
#: field:itis_employee_children,create_date:0
#: field:itis_limitation_reason,create_date:0 field:ld.change,create_date:0
#: field:ot.change,create_date:0
msgid "Created on"
msgstr "Created on"
#. module: itis_hr_extend
#: field:employee.report,name:0 field:fte.report,name:0
msgid "Date"
msgstr "Date"
#. module: itis_hr_extend
#: field:fte.records,department_id:0 field:hr.employee.fte,department_id:0
msgid "Department"
msgstr "Department"
#. module: itis_hr_extend
#: field:fte.records,diff_fte:0
msgid "Difference FTE"
msgstr "Difference FTE"
#. module: itis_hr_extend
#: field:itis.hr.contact,email:0
msgid "Email"
msgstr "Email"
#. module: itis_hr_extend
#: field:employee.report.data,employee_id:0 field:hr.employee.fte,emp_id:0
#: model:ir.model,name:itis_hr_extend.model_hr_employee
msgid "Employee"
msgstr "Employee"
#. module: itis_hr_extend
#: field:employee.report.data,employee_report_id:0
#: model:ir.actions.act_window,name:itis_hr_extend.employee_report_action
#: model:ir.ui.menu,name:itis_hr_extend.menu_employee_report
msgid "Employee Report"
msgstr "Employee Report"
#. module: itis_hr_extend
#: field:hr.leave.journal,employee_id:0
msgid "Employee id"
msgstr "Employee id"
#. module: itis_hr_extend
#: view:employee.report:itis_hr_extend.itis_employee_report_tree
#: field:employee.report,employee_ids:0
msgid "Employees"
msgstr "Employees"
#. module: itis_hr_extend
#: field:fte.records,fte:0 field:hr.employee.fte,fte:0
msgid "FTE"
msgstr "FTE"
#. module: itis_hr_extend
#: view:fte.records:itis_hr_extend.itis_fte_records_form
#: view:fte.report:itis_hr_extend.itis_fte_report_form
#: field:fte.report,fte_ids:0
msgid "FTE Records"
msgstr "FTE Records"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/wizard/fte_wizard.py:108
#: field:fte.records,fte_id:0
#: view:fte.report:itis_hr_extend.itis_fte_report_tree
#: model:ir.actions.act_window,name:itis_hr_extend.fte_report_action
#: model:ir.actions.act_window,name:itis_hr_extend.fte_window_action
#, python-format
msgid "FTE Report"
msgstr "FTE Report"
#. module: itis_hr_extend
#: model:ir.ui.menu,name:itis_hr_extend.menu_fte_report
msgid "FTE Reports"
msgstr "FTE Reports"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
msgid "FTE(%)"
msgstr "FTE(%)"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
#: field:hr.employee,fte_ids:0
msgid "FTEs"
msgstr "FTEs"
#. module: itis_hr_extend
#: view:hr.family.status:itis_hr_extend.itis_family_status_form
#: view:hr.family.status:itis_hr_extend.itis_family_status_tree
#: model:ir.actions.act_window,name:itis_hr_extend.hr_family_status_action
#: model:ir.ui.menu,name:itis_hr_extend.menu_family_status
#: view:itis.leave.days.calc.error:itis_hr_extend.itis_leave_days_calc_error_tree
msgid "Family Status"
msgstr "Family Status"
#. module: itis_hr_extend
#: field:itis.hr.contact,fax:0
msgid "Fax"
msgstr "Fax"
#. module: itis_hr_extend
#: model:ir.actions.act_window,name:itis_hr_extend.leave_days_calc_error_action
#: model:ir.ui.menu,name:itis_hr_extend.menu_days_calc_error
msgid "Fehler Urlaubsberechnung"
msgstr "leave Calculation Errors"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:384
#, python-format
msgid ""
"Fehler automatische Kalkulation durch keine durchgängigen Arbeitsverträge"
msgstr "error automatic calculation due to gaps between contracts"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:387
#, python-format
msgid "Fehler automatische Kalkulation durch Änderung Urlaubsanspruch"
msgstr "error automatic calculation due to change of base leave"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:390
#, python-format
msgid "Fehler automatische Kalkulation durch Änderung Wochenarbeitstage"
msgstr "error automatic calculation due to change of work days a week"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:317
#, python-format
msgid "Fehler in Berechnung"
msgstr "error in calculation"
#. module: itis_hr_extend
#: field:itis.leave.days.calc.error,error:0
msgid "Fehlermeldung"
msgstr "error meassage"
#. module: itis_hr_extend
#: field:itis_employee_children,birth_date:0
msgid "Geburtsdatum"
msgstr "birthdate"
#. module: itis_hr_extend
#: field:hr.employee,birth_name:0
msgid "Geburtsname"
msgstr "birth name"
#. module: itis_hr_extend
#: view:create.fte:itis_hr_extend.fte_wiz_form_view
msgid "Generate"
msgstr "Generate"
#. module: itis_hr_extend
#: model:ir.ui.menu,name:itis_hr_extend.menu_fte_report_generate
msgid "Generate FTE Report"
msgstr "Generate FTE Report"
#. module: itis_hr_extend
#: field:employee.report.data,sum_leaves:0
msgid "Gesamtanspruch"
msgstr "Sum Leaves"
#. module: itis_hr_extend
#: model:ir.ui.menu,name:itis_hr_extend.itis_hr_contact_menu
msgid "HR Contacts"
msgstr "HR Contacts"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
#: view:hr.employee:itis_hr_extend.view_employee_form_inherit_itis
msgid "HR Settings"
msgstr "HR Settings"
#. module: itis_hr_extend
#: view:hr.health.insurance:itis_hr_extend.itis_health_insurance_form
#: view:hr.health.insurance:itis_hr_extend.itis_health_insurance_tree
#: model:ir.actions.act_window,name:itis_hr_extend.hr_health_action
#: model:ir.ui.menu,name:itis_hr_extend.menu_health_insurance
msgid "Health Insurance"
msgstr "Health Insurance"
#. module: itis_hr_extend
#: selection:ld.change,type:0
msgid "Hinzufügen"
msgstr "Add"
#. module: itis_hr_extend
#: field:create.fte,id:0 field:employee.report,id:0
#: field:employee.report.data,id:0 field:fte.records,id:0
#: field:fte.report,id:0 field:hr.employee.fte,id:0
#: field:hr.family.status,id:0 field:hr.health.insurance,id:0
#: field:hr.leave.journal,id:0 field:itis.hr.contact,id:0
#: field:itis.leave.days.calc.error,id:0 field:itis_confession,id:0
#: field:itis_employee_children,id:0 field:itis_limitation_reason,id:0
#: field:ld.change,id:0 field:ot.change,id:0
msgid "ID"
msgstr "ID"
#. module: itis_hr_extend
#: field:hr.holidays,is_ot_leave:0
msgid "Is OT Leave"
msgstr "Is Overtime Leave"
#. module: itis_hr_extend
#: selection:hr.employee,disability:0
msgid "Ja"
msgstr "Yes"
#. module: itis_hr_extend
#: field:hr.leave.journal,year:0 field:itis.leave.days.calc.error,year:0
msgid "Jahr"
msgstr "Year"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:304
#, python-format
msgid "Kein Vertrag am 01.Januar vorhanden"
msgstr "No contract on January 01."
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
#: field:hr.employee,children_ids:0
msgid "Kinder"
msgstr "Children"
#. module: itis_hr_extend
#: field:hr.employee,confession:0
msgid "Konfession"
msgstr "Confession"
#. module: itis_hr_extend
#: field:hr.employee,health_insurance:0
msgid "Krankenkasse"
msgstr "health Insurance company"
#. module: itis_hr_extend
#: field:create.fte,write_uid:0 field:employee.report,write_uid:0
#: field:employee.report.data,write_uid:0 field:fte.records,write_uid:0
#: field:fte.report,write_uid:0 field:hr.employee.fte,write_uid:0
#: field:hr.family.status,write_uid:0 field:hr.health.insurance,write_uid:0
#: field:hr.leave.journal,write_uid:0 field:itis.hr.contact,write_uid:0
#: field:itis.leave.days.calc.error,write_uid:0
#: field:itis_confession,write_uid:0 field:itis_employee_children,write_uid:0
#: field:itis_limitation_reason,write_uid:0 field:ld.change,write_uid:0
#: field:ot.change,write_uid:0
msgid "Last Updated by"
msgstr "Last Updated by"
#. module: itis_hr_extend
#: field:create.fte,write_date:0 field:employee.report,write_date:0
#: field:employee.report.data,write_date:0 field:fte.records,write_date:0
#: field:fte.report,write_date:0 field:hr.employee.fte,write_date:0
#: field:hr.family.status,write_date:0 field:hr.health.insurance,write_date:0
#: field:hr.leave.journal,write_date:0 field:itis.hr.contact,write_date:0
#: field:itis.leave.days.calc.error,write_date:0
#: field:itis_confession,write_date:0
#: field:itis_employee_children,write_date:0
#: field:itis_limitation_reason,write_date:0 field:ld.change,write_date:0
#: field:ot.change,write_date:0
msgid "Last Updated on"
msgstr "Last Updated on"
#. module: itis_hr_extend
#: model:ir.model,name:itis_hr_extend.model_hr_holidays
msgid "Leave"
msgstr "Leave"
#. module: itis_hr_extend
#: field:ld.change,leave_day:0 field:ot.change,leave_day:0
msgid "Leave Day"
msgstr "Leave Day"
#. module: itis_hr_extend
#: field:hr.leave.journal,leave_id:0
msgid "Leave id"
msgstr "Leave id"
#. module: itis_hr_extend
#: field:hr.employee,leave_journal_ids:0
msgid "Leave journal ids"
msgstr "Leave journal ids"
#. module: itis_hr_extend
#: field:hr.leave.journal,leave_type:0
msgid "Leave type"
msgstr "Leave type"
#. module: itis_hr_extend
#: model:ir.actions.act_window,name:itis_hr_extend.act_hr_leaves_overview
msgid "Leaves"
msgstr "Leaves"
#. module: itis_hr_extend
#: field:hr.holidays,ljournal_ids:0
msgid "Ljournal ids"
msgstr "Ljournal ids"
#. module: itis_hr_extend
#: selection:hr.leave.journal,type:0
msgid "Manuell"
msgstr "Manual"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:295
#: code:addons/itis_hr_extend/models/hr_employee.py:302
#, python-format
msgid "Mehr als ein Vertrag zum 01.Januar"
msgstr "More than one contract on January 01."
#. module: itis_hr_extend
#: model:ir.model,name:itis_hr_extend.model_mail_message
msgid "Message"
msgstr "Message"
#. module: itis_hr_extend
#: field:itis.leave.days.calc.error,name:0
#: field:itis_employee_children,parent_id:0
msgid "Mitarbeiter"
msgstr "Employee"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
msgid "Mitarbeiter/in"
msgstr "Employee"
#. module: itis_hr_extend
#: field:itis.hr.contact,mobile:0
msgid "Mobile"
msgstr "Mobile"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.view_employee_form_inherit_itis
msgid "Monatlich Lohnrelevante Informationen"
msgstr "salary export information"
#. module: itis_hr_extend
#: field:hr.employee,second_name:0
msgid "Nachname"
msgstr "Surname"
#. module: itis_hr_extend
#: field:hr.health.insurance,name:0
#: view:itis.hr.contact:itis_hr_extend.itis_hr_contact_form
#: view:itis.hr.contact:itis_hr_extend.itis_hr_contact_tree
#: field:itis.hr.contact,name:0 field:itis_employee_children,name:0
msgid "Name"
msgstr "Name"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/employee_report.py:42
#, python-format
msgid "No associated employee found with user"
msgstr "No associated employee found with user"
#. module: itis_hr_extend
#: field:hr.employee,emergency_contact:0
msgid "Notfallkontakt"
msgstr "emergency contact"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_holiday.py:106
#: code:addons/itis_hr_extend/models/hr_holiday.py:119
#, python-format
msgid "Only the Manager of this employee can approve this leave request."
msgstr "Only the Manager of this employee can approve this leave request."
#. module: itis_hr_extend
#: field:employee.report.data,overtime_count:0
#: field:hr.employee,overtime_count:0 field:ot.change,ot_time:0
msgid "Overtime Count"
msgstr "Overtime Count"
#. module: itis_hr_extend
#: model:hr.holidays.status,name:itis_hr_extend.itis_leave_overtime
msgid "Overtime Leave"
msgstr "Overtime Leave"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:180
#: code:addons/itis_hr_extend/models/hr_employee.py:202
#, python-format
msgid "Overtime has been chagned from <b>%s</b> to <b>%s</b>.<br/>Reason : %s"
msgstr "Overtime has been chagned from <b>%s</b> to <b>%s</b>.<br/>Reason : %s"
#. module: itis_hr_extend
#: field:itis.hr.contact,phone:0
msgid "Phone"
msgstr "Phone"
#. module: itis_hr_extend
#: field:fte.records,planned_fte:0 field:hr.department,planned_fte:0
msgid "Planned FTE"
msgstr "Planned FTE"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_holiday.py:295
#: code:addons/itis_hr_extend/models/hr_holiday.py:315
#, python-format
msgid "Please create a leave request for every year."
msgstr "Please create a leave request for every year."
#. module: itis_hr_extend
#: field:ld.change,reason:0 field:ot.change,reason:0
msgid "Reason"
msgstr "reason"
#. module: itis_hr_extend
#: model:ir.ui.menu,name:itis_hr_extend.menu_hr_reports
msgid "Reports"
msgstr "Reports"
#. module: itis_hr_extend
#: selection:hr.leave.journal,year_type:0
msgid "Restanspruch"
msgstr "Remainig last year leaves"
#. module: itis_hr_extend
#: field:hr.employee,disability:0
msgid "Schwerbehinderung"
msgstr "Disability"
#. module: itis_hr_extend
#: view:hr.leave.journal:itis_hr_extend.itis_hr_leave_journal_form
msgid "Search Leave"
msgstr "Search Leave"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
msgid "Sozialversicherungsnummer"
msgstr "social security number"
#. module: itis_hr_extend
#: view:itis.hr.contact:itis_hr_extend.itis_hr_contact_form
#: field:itis.hr.contact,state_id:0
msgid "State"
msgstr "State"
#. module: itis_hr_extend
#: field:hr.family.status,name:0
msgid "Status"
msgstr "Status"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
msgid "Steuer-ID"
msgstr "tax-ID"
#. module: itis_hr_extend
#: field:hr.employee,taxclass:0
msgid "Steuerklasse"
msgstr "tax category"
#. module: itis_hr_extend
#: selection:hr.employee,taxclass:0
msgid "Steuerklasse 1"
msgstr "Steuerklasse 1"
#. module: itis_hr_extend
#: selection:hr.employee,taxclass:0
msgid "Steuerklasse 2"
msgstr "Steuerklasse 2"
#. module: itis_hr_extend
#: selection:hr.employee,taxclass:0
msgid "Steuerklasse 3"
msgstr "Steuerklasse 3"
#. module: itis_hr_extend
#: selection:hr.employee,taxclass:0
msgid "Steuerklasse 4"
msgstr "Steuerklasse 4"
#. module: itis_hr_extend
#: selection:hr.employee,taxclass:0
msgid "Steuerklasse 5"
msgstr "Steuerklasse 5"
#. module: itis_hr_extend
#: selection:hr.employee,taxclass:0
msgid "Steuerklasse 6"
msgstr "Steuerklasse 6"
#. module: itis_hr_extend
#: field:itis.hr.contact,street:0
msgid "Street"
msgstr "Street"
#. module: itis_hr_extend
#: view:itis.hr.contact:itis_hr_extend.itis_hr_contact_form
msgid "Street 2..."
msgstr "Street 2..."
#. module: itis_hr_extend
#: view:itis.hr.contact:itis_hr_extend.itis_hr_contact_form
msgid "Street..."
msgstr "Street..."
#. module: itis_hr_extend
#: field:itis.hr.contact,street2:0
msgid "Street2"
msgstr "Street2"
#. module: itis_hr_extend
#: field:hr.leave.journal,leave_hours:0
#: selection:hr.leave.journal,leave_type:0
msgid "Stunden"
msgstr "Hours"
#. module: itis_hr_extend
#: field:hr.leave.journal,leave_days:0 selection:hr.leave.journal,leave_type:0
msgid "Tage"
msgstr "Days"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
msgid "Telefon (interne Durchwahl)"
msgstr "Telefone number (internal)"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_holiday.py:71
#, python-format
msgid ""
"The number of remaining leaves is not sufficient for this leave type.\n"
"Please verify also the leaves waiting for validation."
msgstr ""
"The number of remaining leaves is not sufficient for this leave type.Please "
"verify also the leaves waiting for validation."
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:223
#, python-format
msgid "There are 2 contracts assigned to this employee."
msgstr "There are 2 contracts assigned to this employee."
#. module: itis_hr_extend
#: view:hr.contract:itis_hr_extend.hr_contract_view_form_itis
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
msgid "True"
msgstr "True"
#. module: itis_hr_extend
#: field:hr.leave.journal,type:0 field:ld.change,type:0
msgid "Type"
msgstr "Type"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:258
#: code:addons/itis_hr_extend/models/hr_employee.py:269
#, python-format
msgid "Umwandlung Resturlaub"
msgstr "transfer remaining leaves"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
msgid "Update"
msgstr "Update"
#. module: itis_hr_extend
#: field:hr.contract,base_leaves:0
msgid "Urlaubsanspruch"
msgstr "leave entitlement"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
msgid "Urlaubsjournal"
msgstr "Leave Journal"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/employee_report.py:44
#, python-format
msgid "User is associated with multiple employee"
msgstr "User is associated with multiple employee"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:420
#, python-format
msgid "Verfall Resturlaub"
msgstr "deletion remaining last year leaves"
#. module: itis_hr_extend
#: selection:hr.leave.journal,type:0
msgid "Vertraglich"
msgstr "based on contract"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
msgid "Vertragsinformationen"
msgstr "contract informationen"
#. module: itis_hr_extend
#: field:hr.employee,surname:0
msgid "Vorname"
msgstr "First name"
#. module: itis_hr_extend
#: field:hr.employee,wage_info:0
msgid "Wage Information"
msgstr "Wage Information"
#. module: itis_hr_extend
#: field:hr.leave.journal,year_type:0
msgid "Year type"
msgstr "Year type"
#. module: itis_hr_extend
#: view:itis.hr.contact:itis_hr_extend.itis_hr_contact_form
msgid "ZIP"
msgstr "ZIP"
#. module: itis_hr_extend
#: field:hr.employee,sign_permission:0
msgid "Zeichnungsbefugnis"
msgstr "signing rights"
#. module: itis_hr_extend
#: field:itis.hr.contact,zip:0
msgid "Zip"
msgstr "Zip"
#. module: itis_hr_extend
#: selection:hr.leave.journal,type:0
msgid "Zusatzurlaub"
msgstr "additional leaves"
#. module: itis_hr_extend
#: selection:hr.leave.journal,year_type:0
msgid "aktuell"
msgstr "actual"
#. module: itis_hr_extend
#: view:hr.payslip:itis_hr_extend.hr_payroll_view_hr_payslip_form_itis
msgid "base.group_hr_payroll_manager"
msgstr "base.group_hr_payroll_manager"
#. module: itis_hr_extend
#: view:hr.holidays:itis_hr_extend.hr_holidays_view_form_itis
msgid "base.group_user"
msgstr "base.group_user"
#. module: itis_hr_extend
#: field:hr.leave.journal,leave_end:0
msgid "bis"
msgstr "to"
#. module: itis_hr_extend
#: view:hr.employee:itis_hr_extend.hr_hr_employee_view_form_itis
msgid "e.g. Part Time"
msgstr "e.g. Part Time"
#. module: itis_hr_extend
#: view:hr.holidays:itis_hr_extend.hr_holidays_view_form_itis
msgid "hours"
msgstr "hours"
#. module: itis_hr_extend
#: selection:hr.employee,disability:0
msgid "nein"
msgstr "no"
#. module: itis_hr_extend
#: view:create.fte:itis_hr_extend.fte_wiz_form_view
#: view:ld.change:itis_hr_extend.ld_change_form_view
#: view:ot.change:itis_hr_extend.ot_change_form_view
msgid "or"
msgstr "or"
#. module: itis_hr_extend
#: field:hr.leave.journal,leave_start:0
msgid "von"
msgstr "of"
#. module: itis_hr_extend
#: field:hr.employee,emergency_contact2:0
msgid "zweiter Notfallkontakt"
msgstr "second emergency contact"
#. module: itis_hr_extend
#: code:addons/itis_hr_extend/models/hr_employee.py:307
#, python-format
msgid "Überschneidende Verträge"
msgstr "two contracts on the same date"

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from . import hr_holiday

View File

@ -0,0 +1,333 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, fields, _
from openerp.osv import osv
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
from datetime import datetime, timedelta
from openerp.exceptions import Warning
import math
from openerp import SUPERUSER_ID
class HRHolidayTimesheet(models.Model):
_name = "hr.holidays.timesheet"
date = fields.Date('Date')
holiday_id = fields.Many2one("hr.holidays", "Holiday")
sheet_id = fields.Many2one('hr_timesheet_sheet.sheet', 'Sheet')
timesheet_id = fields.Many2one("hr.analytic.timesheet", "Timesheet")
duration = fields.Float("Hours")
class HRTimesheetSheet(models.Model):
_inherit = "hr_timesheet_sheet.sheet"
@api.model
def create(self, values):
res = super(HRTimesheetSheet, self).create(values)
res.calc_leave_hours()
return res
@api.multi
def calc_leave_hours(self):
leave_obj = self.env['hr.holidays']
leave_recs = leave_obj.search([('employee_id', '=', self.employee_id.id), ('state', '=', 'validate'), ('state', '!=', 'refuse')])
for leave in leave_recs:
leave_processed = True
for hl_ts_rec in leave.holidays_timesheet_ids:
if not hl_ts_rec.timesheet_id:
#print"Calc leave hours - No Timesheet_id", hl_ts_rec
leave_processed = False
if not leave_processed:
leave.make_timesheet_entry()
class HRHoliday(models.Model):
_inherit = "hr.holidays"
holidays_timesheet_ids = fields.One2many("hr.holidays.timesheet", "holiday_id", "Timesheet")
@api.multi
def holidays_refuse(self):
res = super(HRHoliday, self).holidays_refuse()
for hl_ts_rec in self.sudo().holidays_timesheet_ids:
hl_ts_rec.timesheet_id.unlink()
hl_ts_rec.write({'sheet_id': False})
return res
@api.multi
def holidays_validate(self):
res = super(HRHoliday, self).holidays_validate()
self.make_timesheet_entry()
return res
@api.multi
def make_holidays_timesheet(self, res):
result = []
holi_ts_obj = self.env['hr.holidays.timesheet']
cur_recs = holi_ts_obj.search([('holiday_id', '=', self.id)])
res_days = res.keys()
for rec in cur_recs:
if rec.date not in res_days:
rec.unlink()
for day, duration in res.iteritems():
holiday = None
holiday = self.env['itis.holiday'].search([('date', '=', day)])
if holiday:
continue
cur_rec = holi_ts_obj.search([('holiday_id', '=', self.id), ('date', '=', day)])
if not cur_rec.id:
cur_rec = holi_ts_obj.create({'date': day, 'duration': duration, "holiday_id": self.id})
if cur_rec.duration != duration:
cur_rec.update({'duration': duration})
result.append(cur_rec)
return result
@api.multi
def make_timesheet_entry(self):
res = self.count_day_hours_leave()
res = self.make_holidays_timesheet(res)
account_id = False
if self.is_ot_leave:
account_id = self.env.user.company_id.ot_leave_account_id
else:
account_id = self.env.user.company_id.leave_account_id
if not account_id:
raise Warning(_('Please set the analytic account for Leaves.\nPlease contact your administrator for the same.'))
sheet_obj = self.env['hr_timesheet_sheet.sheet']
timesheets = sheet_obj.search([("employee_id", '=', self.employee_id.id)])
for hl_ts_rec in res:
if hl_ts_rec.timesheet_id:
continue
cur_day = datetime.strptime(hl_ts_rec.date, DEFAULT_SERVER_DATE_FORMAT)
for timesheet in timesheets:
ts_date_from = datetime.strptime(timesheet.date_from, DEFAULT_SERVER_DATE_FORMAT)
ts_date_to = datetime.strptime(timesheet.date_to, DEFAULT_SERVER_DATE_FORMAT)
if cur_day >= ts_date_from and cur_day <= ts_date_to:
if timesheet.state != 'draft':
continue
#raise Warning(_('The Time period is allready closed. \n Please contact the Human Resource Team if the leave request should be confirmed nevertheless'))
#print"cur_day ", cur_day
ana_ts_id = self.create_timesheet(account_id, timesheet, hl_ts_rec.duration, hl_ts_rec.date)
hl_ts_rec.write({'timesheet_id': ana_ts_id[0], 'sheet_id': timesheet.id})
return True
@api.one
def create_timesheet(self, account_id, sheet, duration, day):
timesheet_obj = self.pool.get('hr.analytic.timesheet')
cr = self.env.cr
uid = self.env.uid
emp_obj = self.env['hr.employee']
hour = duration
res = timesheet_obj.default_get(cr, uid, ['product_id','product_uom_id'])
# res.update({
# 'general_account_id': False,
# })
if not res['product_id']:
res['product_id'] = 1
if not res['product_uom_id']:
res['product_uom_id'] = 5
if not res['product_uom_id']:
raise osv.except_osv(_('User Error!'), _('Please define cost unit for this employee.'))
up = timesheet_obj.on_change_unit_amount(cr, uid, False, res['product_id'], hour,False, res['product_uom_id'])['value']
print"UP ", up
res['name'] = "Leave on " + day
res['account_id'] = account_id.id
res['unit_amount'] = hour
emp_journal = emp_obj.search([('user_id', '=', self.employee_id.user_id.id)]).journal_id
res['journal_id'] = emp_journal and emp_journal.id or False
res.update(up)
up = timesheet_obj.on_change_account_id(cr, uid, [], res['account_id']).get('value', {})
res.update(up)
print"RES ", res
# if not res['general_account_id']:
# res['general_account_id'] = 698
res.update({
'date': day,
'user_id': self.employee_id.user_id.id,
'sheet_id': sheet.id,
})
return timesheet_obj.create(cr, SUPERUSER_ID, res)
@api.multi
def count_day_hours_leave(self):
res = {}
date_from = datetime.strptime(self.date_from, DEFAULT_SERVER_DATETIME_FORMAT)
date_to = datetime.strptime(self.date_to, DEFAULT_SERVER_DATETIME_FORMAT)
same_day = self.check_same_day(date_from, date_to)
temp_date = date_from
day_hours = 0.0
weekday = temp_date.weekday()
for contract in self.employee_id.contract_ids:
cont_start_date = datetime.strptime(contract.date_start, DEFAULT_SERVER_DATE_FORMAT)
cont_end_date = False
if not contract.date_end:
if cont_start_date <= temp_date:
if same_day:
cur_hour = self.get_day_hours(date_from, contract.working_hours.attendance_ids)
day_hours = cur_hour
day_str = datetime.strftime(temp_date, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
new_hour = res.get(day_str, 0.0) + cur_hour
if self.leave_selection =='half_day':
new_hour =new_hour/2
res.update({day_str: new_hour})
else:
fday_cur_hour = self.get_day_hours(date_from, contract.working_hours.attendance_ids)
day_hours += fday_cur_hour
lday_cur_hour = self.get_day_hours(date_to, contract.working_hours.attendance_ids)
day_hours = lday_cur_hour
fday_str = datetime.strftime(date_from, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
fday_new_hour = res.get(fday_str, 0.0) + fday_cur_hour
if self.leave_selection =='half_day':
fday_new_hour =fday_new_hour/2
res.update({fday_str: fday_new_hour})
lday_str = datetime.strftime(date_to, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
lday_new_hour = res.get(lday_str, 0.0) + lday_cur_hour
if self.leave_selection_date_to =='half_day':
lday_new_hour =lday_new_hour/2
#if temp_date == self.start_date and self.start_date_leave_selection == 'half_day':
# lday_new_hour =lday_new_hour/2
#elif temp_date == self.end_date and self.end_date_leave_selection == 'half_day':
# lday_new_hour =lday_new_hour/2
res.update({lday_str: lday_new_hour})
else:
cont_end_date = datetime.strptime(contract.date_end, DEFAULT_SERVER_DATE_FORMAT)
cont_end_date += timedelta(days=1)
if cont_start_date <= temp_date and cont_end_date >= temp_date:
if same_day:
cur_hour = self.get_day_hours(date_from, contract.working_hours.attendance_ids)
day_hours += cur_hour
day_str = datetime.strftime(temp_date, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
new_hour = res.get(day_str, 0.0) + cur_hour
if self.leave_selection =='half_day':
new_hour =new_hour/2
res.update({day_str: new_hour})
else:
fday_cur_hour = self.get_day_hours(date_from, contract.working_hours.attendance_ids)
day_hours += fday_cur_hour
lday_cur_hour = self.get_day_hours(date_to, contract.working_hours.attendance_ids)
day_hours = lday_cur_hour
fday_str = datetime.strftime(date_from, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
fday_new_hour = res.get(fday_str, 0.0) + fday_cur_hour
if self.leave_selection =='half_day':
fday_new_hour =fday_new_hour/2
res.update({fday_str: fday_new_hour})
lday_str = datetime.strftime(date_to, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
lday_new_hour = res.get(lday_str, 0.0) + lday_cur_hour
if self.leave_selection_date_to =='half_day':
lday_new_hour =lday_new_hour/2
res.update({lday_str: lday_new_hour})
date_from = datetime.strptime(self.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
date_to = datetime.strptime(self.date_to.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
temp_date = date_from
temp_date += timedelta(days=1)
while temp_date < date_to:
weekday = temp_date.weekday()
for contract in self.employee_id.contract_ids:
cont_start_date = datetime.strptime(contract.date_start, DEFAULT_SERVER_DATE_FORMAT)
cont_end_date = False
if not contract.date_end:
if cont_start_date <= temp_date:
cur_hour = self.get_hours(weekday, contract.working_hours.attendance_ids)
day_hours += cur_hour
day_str = datetime.strftime(temp_date, DEFAULT_SERVER_DATE_FORMAT).split(" ")[0]
new_hour = res.get(day_str, 0.0) + cur_hour
res.update({day_str: new_hour})
else:
cont_end_date = datetime.strptime(contract.date_end, DEFAULT_SERVER_DATE_FORMAT)
# cont_end_date += timedelta(days=1)
if cont_start_date <= temp_date and cont_end_date >= temp_date:
cur_hour = self.get_hours(weekday, contract.working_hours.attendance_ids)
day_hours = cur_hour
day_str = datetime.strftime(temp_date, DEFAULT_SERVER_DATE_FORMAT).split(" ")[0]
new_hour = res.get(day_str, 0.0) + cur_hour
res.update({day_str: new_hour})
temp_date += timedelta(days=1)
return res
@api.onchange("number_of_days_temp","leave_selection","leave_selection_date_to")
def calc_days(self):
res = 0
if not self.date_from or not self.date_to:
return {}
date_from = datetime.strptime(self.date_from.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
date_to = datetime.strptime(self.date_to.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
# if date_from == date_to:
# if self.leave_selection =='half_day' or self.leave_selection_date_to =='half_day':
# self.number_of_days_temp = 0.5
# return {}
temp_date = date_from
while temp_date <= date_to:
holiday = None
holiday = self.env['itis.holiday'].search([('date', '=', temp_date)])
if holiday:
temp_date += timedelta(days=1)
continue
weekday = temp_date.weekday()
for contract in self.employee_id.contract_ids:
cont_start_date = datetime.strptime(contract.date_start, DEFAULT_SERVER_DATE_FORMAT)
cont_end_date = False
if not contract.date_end:
if cont_start_date <= temp_date:
if self.get_hours(weekday, contract.working_hours.attendance_ids) > 0.0:
if temp_date == date_from and self.leave_selection =='half_day':
res += 0.25
break
if temp_date == date_to and self.leave_selection_date_to =='half_day':
res += 0.25
break
res += 1
else:
cont_end_date = datetime.strptime(contract.date_end, DEFAULT_SERVER_DATE_FORMAT)
# cont_end_date += timedelta(days=1)
if cont_start_date <= temp_date and cont_end_date >= temp_date:
if self.get_hours(weekday, contract.working_hours.attendance_ids) > 0.0:
if temp_date == date_from and self.leave_selection =='half_day':
res += 0.25
break
if temp_date == date_to and self.leave_selection_date_to =='half_day':
res += 0.25
break
res += 1
temp_date += timedelta(days=1)
self.number_of_days_temp = res
return {}
class HRHolidayStatus(models.Model):
_inherit = "hr.holidays.status"
def name_get(self, cr, uid, ids, context=None):
if context is None:
context = {}
if not context.get('employee_id',False):
# leave counts is based on employee_id, would be inaccurate if not based on correct employee
return super(HRHolidayStatus, self).name_get(cr, uid, ids, context=context)
res = []
for record in self.browse(cr, uid, ids, context=context):
name = record.name
if not record.limit:
name = name
res.append((record.id, name))
return res

View File

@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_hr_holidays_timesheet,access_hr_holidays_timesheet,model_hr_holidays_timesheet,base.group_user,1,1,1,1
access_hr_sick_leave,access_hr_sick_leave,model_hr_sick_leave,base.group_hr_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_hr_holidays_timesheet access_hr_holidays_timesheet model_hr_holidays_timesheet base.group_user 1 1 1 1
3 access_hr_sick_leave access_hr_sick_leave model_hr_sick_leave base.group_hr_manager 1 1 1 1

View File

@ -0,0 +1 @@
from . import test_hr_leave_extend

View File

@ -0,0 +1,168 @@
# -*- coding: utf-8 -*-
from openerp.tests.common import TransactionCase
from datetime import datetime
from dateutil.relativedelta import relativedelta
from openerp.osv.orm import except_orm
import logging
_logger = logging.getLogger(__name__)
class TestHrLeave(TransactionCase):
def setUp(self):
super(TestHrLeave, self).setUp()
cr, uid = self.cr, self.uid
# Find Employee group
group_employee_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
self.group_employee_id = group_employee_ref and group_employee_ref[1] or False
# Find Hr User group
group_hr_user_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_hr_user')
self.group_hr_user_ref_id = group_hr_user_ref and group_hr_user_ref[1] or False
# Find Hr Manager group
group_hr_manager_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_hr_manager')
self.group_hr_manager_ref_id = group_hr_manager_ref and group_hr_manager_ref[1] or False
self.test_hrmanager_user = self.env['res.users'].create({
'name': 'Bastien HrManager',
'login': 'bastien',
'alias_name': 'bastien',
'email': 'bastien.hrmanager@example.com',
'groups_id': [(6, 0, [self.group_employee_id, self.group_hr_manager_ref_id])]
})
self.test_hrmanager_employee = self.env['hr.employee'].create({
'name': 'Hr Manager Test',
'user_id':self.test_hrmanager_user.id,
})
self.test_user = self.env['res.users'].create({
'name': 'Agrolait Test User',
'login': 'user',
'email': 'hro@example.com',
'signature': '--\nAgr',
'groups_id': [(6, 0, [self.group_employee_id])]
})
self.test_employee = self.env['hr.employee'].create({
'name': 'Agrolait Test Emp',
'user_id':self.test_user.id,
'parent_id':self.test_hrmanager_employee.id,
})
working_hours = self.env["resource.calendar"].search([('name','=','45 Hours/Week')])
struct_id = self.env["hr.payroll.structure"].search([])
today_date = datetime.now().date()
test_contract = self.env['hr.contract'].create({
'name':'test employee contract',
'employee_id':self.test_employee.id,
'struct_id':struct_id[0].id,
'wage':100,
'date_start':str(today_date.replace(month=01,day=01)),
'date_end':str(today_date.replace(month=12,day=01)),
'working_hours':working_hours.id,
})
def test_fillup_sick_leave(self):
"""test case to test the sick leave fill up functionality"""
hr_sick_leave = self.env["hr.sick.leave"]
hr_analytic_timesheet =self.env['hr.analytic.timesheet']
today_date = datetime.now().date()
end_date = today_date+relativedelta(days=1)
hr_sick_leave_rec = hr_sick_leave.create({
'start_date':today_date,
'end_date':end_date,
})
hr_sick_leave_rec.with_context(active_ids = [self.test_employee.id]).confirm_sick_time()
leave_record = hr_analytic_timesheet.search([('date','>=',today_date),('date','<=',end_date),('user_id','<=',self.test_user.id)])
print"leave_record------",leave_record
if leave_record:
_logger.info('-----Sick leave is created.')
else:
self.assertEqual(1,2,'Sick leave is not created.')
def test_create_timesheet(self):
"""test case to test creation of timesheet and planned,fillup hours,closed timesheet"""
account_journal = self.env['account.analytic.journal'].search([])
account_analytic = self.env['account.analytic.account'].search([('use_timesheets','=',True),('type','=','contract')])
timesheet_sheet = self.env['hr_timesheet_sheet.sheet'].create({
'date_from': str(datetime.today()),
'date_to': str(datetime.today()),
'name': 'Agrolait Test',
'state': 'new',
'user_id': self.test_user.id,
'employee_id': self.test_employee.id,
'timesheet_ids': [(0, 0, {
'date': str(datetime.today()),
'name': 'Develop yaml for hr module(1)',
'user_id': self.test_user.id,
'unit_amount': 8.00,
'journal_id':account_journal[0].id,
'account_id':account_analytic[0].id,
})]})
try:
timesheet_sheet.action_timesheet_confirm()
except Exception:
pass
print"Planned hour--------",timesheet_sheet.total_contract_time
print"total_timesheet-11-------",timesheet_sheet.total_timesheet
print"actual_ot-11-------",timesheet_sheet.actual_ot
print"time_diff-11-------",timesheet_sheet.time_diff
self.assertEqual(timesheet_sheet.actual_ot,timesheet_sheet.time_diff,'Total overtime hour need to be equal.')
try:
timesheet_sheet.button_confirm()
except Exception:
pass
self.assertEqual(timesheet_sheet.actual_ot,timesheet_sheet.time_diff,'Total overtime hour need to be equal.')
def test_create_half_day_leave(self):
"""test half day leave test cases"""
hr_holidays = self.registry('hr.holidays')
holidays_status_1 = self.env["hr.holidays.status"].create({
'name': 'NotLimited',
'limit': True,
})
date_from = datetime.today() + relativedelta(days=2)
date_end = datetime.today() + relativedelta(days=2)
timesheet_rec = self.env['hr_timesheet_sheet.sheet'].create({
'date_from': str(date_from),
'date_to': str(date_end),
'name': 'Agrolait Test',
'state': 'new',
'user_id': self.test_user.id,
'employee_id': self.test_employee.id,
})
holiday_id = hr_holidays.create(self.cr, self.test_hrmanager_user.id,{
'name': 'Holiday1',
'employee_id': self.test_employee.id,
'holiday_status_id': holidays_status_1.id,
'date_from': str(date_from),
'date_to': str(date_end),
'leave_selection':'half_day',
'half_day_type':'morning',
'number_of_days_temp':0.5
})
holiday_rec = hr_holidays.browse(self.cr, self.test_hrmanager_user.id, holiday_id)
self.assertEqual(holiday_rec.state, 'confirm', 'hr_holidays: newly created leave request should be in confirm state')
self.assertEqual(holiday_rec.number_of_days_temp, 0.5, 'hr_holidays: Half day leave request need to shaw day as 0.5')
hr_holidays.signal_workflow(self.cr, self.test_hrmanager_user.id, [holiday_id], 'validate')
self.assertEqual(holiday_rec.state, 'validate', 'hr_holidays: validates leave request should be in validate state')
leave_record = self.env['hr.analytic.timesheet'].search([('date','>=',date_from),('date','<=',date_end),('user_id','<=',self.test_user.id)])
if leave_record:
_logger.info('-----Half Day leave is created.')
else:
self.assertEqual(1,2,'Half Day leave is not created.')

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_human_resources_configuration" model="ir.ui.view">
<field name="name">hr settings</field>
<field name="model">hr.config.settings</field>
<field name="inherit_id" ref="hr.view_human_resources_configuration"/>
<field name="arch" type="xml">
<group name="contract_grp" position='after'>
<group name="hr_ot_leave">
<label for="id" string="Analytic account"/>
<div>
<div>
<label for="leave_account_id" string="for Leave " class="oe_inline"/>
<field name="leave_account_id" domain="[('type', 'in', ['normal', 'contract']), ('state', '!=', 'close'), ('use_timesheets', '=', 1)]" options="{'no_open': True, 'no_create': True, 'no_create_edit':True}" class="oe_inline"/>
</div>
<div>
<label for="ot_leave_account_id" string="for Overtime Leave " class="oe_inline"/>
<field name="ot_leave_account_id" domain="[('type', 'in', ['normal', 'contract']), ('state', '!=', 'close'), ('use_timesheets', '=', 1)]" options="{'no_open': True, 'no_create': True, 'no_create_edit':True}" class="oe_inline"/>
</div>
</div>
</group>
</group>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from . import hr_setting
from . import hr_sick_leave

View File

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields, api, _
class HRConfig(models.TransientModel):
_inherit = "hr.config.settings"
leave_account_id = fields.Many2one("account.analytic.account", "Analytic Account for Leave")
ot_leave_account_id = fields.Many2one("account.analytic.account", "Analytic Account for Overtime Leave")
@api.multi
def set_ot_leave_account_id(self):
self.env.user.company_id.write({
"leave_account_id": self.leave_account_id.id,
"ot_leave_account_id": self.ot_leave_account_id.id,
})
return True
@api.model
def default_get(self, fields):
la_id = self.env.user.company_id.leave_account_id.id or False
ola_id = self.env.user.company_id.ot_leave_account_id.id or False
res = super(HRConfig, self).default_get(fields)
res.update({
"leave_account_id": la_id,
"ot_leave_account_id": ola_id,
})
return res
class ResCompany(models.Model):
_inherit = "res.company"
leave_account_id = fields.Many2one("account.analytic.account", "Analytic Account for Leave")
ot_leave_account_id = fields.Many2one("account.analytic.account", "Analytic Account for Overtime Leave")

View File

@ -0,0 +1,278 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields, api, _
from openerp.exceptions import Warning
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
from datetime import datetime, timedelta
from openerp import SUPERUSER_ID
from dateutil.relativedelta import relativedelta
class hr_sick_leave(models.TransientModel):
_name = 'hr.sick.leave'
start_date = fields.Datetime('Start Date')
end_date = fields.Datetime('End Date')
@api.multi
def confirm_sick_time(self):
""" This function is use to fill the timesheet when employee is sick.
"""
hr_employee_env = self.env['hr.employee']
sheet_obj = self.env['hr_timesheet_sheet.sheet']
timesheet_obj = self.pool.get('hr.analytic.timesheet')
active_ids = self.env.context.get('active_ids')
if active_ids:
account_id = self.env.user.company_id and self.env.user.company_id.sick_account_id or False
if not account_id:
raise Warning(_('Please set the analytic account for Sick Leaves.\nPlease contact your administrator for the same.'))
for hr_employee_brw in hr_employee_env.browse(active_ids):
res = self.count_day_sickleave(hr_employee_brw)
timesheets = sheet_obj.search([("employee_id", '=', hr_employee_brw.id)])
#for sick_leave_rec in res:
for key, value in res.iteritems():
cur_day_timesheeht_found = False
cur_day = datetime.strptime(key, DEFAULT_SERVER_DATE_FORMAT)
for timesheet in timesheets:
ts_date_from = datetime.strptime(timesheet.date_from, DEFAULT_SERVER_DATE_FORMAT)
ts_date_to = datetime.strptime(timesheet.date_to, DEFAULT_SERVER_DATE_FORMAT)
if cur_day >= ts_date_from and cur_day <= ts_date_to:
cur_day_timesheeht_found = True
# print"Final Timesheet----",timesheet
# if timesheet.state != 'draft':
# raise Warning(_('The Time period is allready closed. \n Please contact the Human Resource Team if the leave request should be confirmed nevertheless'))
# timesheet_ids = timesheet_obj.search(self.env.cr,self.env.uid,[('name','like','Sick Leave on:'),('sheet_id','=',timesheet.id),('user_id','=',hr_employee_brw.user_id.id)])
# if timesheet_ids:
# timesheet_obj.unlink(self.env.cr,self.env.uid,timesheet_ids)
ana_ts_id = self.create_sickleave_timesheet(account_id, timesheet, value, key,hr_employee_brw)
#hl_ts_rec.write({'timesheet_id': ana_ts_id[0], 'sheet_id': timesheet.id})
if cur_day_timesheeht_found == False:
self.create_future_timesheet(cur_day,account_id, value, key,hr_employee_brw)
return True
def create_future_timesheet(self,cur_day,account_id, value, key,hr_employee_brw):
"""
Use to create a future timesheet base upon the user configuration
"""
hr_timesheet =self.env['hr_timesheet_sheet.sheet']
timesheet_start_date = self.get_timesheet_start_date(cur_day)
timesheet_end_date =self.get_timesheet_end_date(cur_day)
timesheets = hr_timesheet.search([("employee_id", '=', hr_employee_brw.id),("date_from", '=', timesheet_start_date),("date_to", '=', timesheet_end_date)])
# print"START----------END--------",timesheet_start_date,timesheet_end_date,timesheets
if not timesheets:
timesheets = hr_timesheet.create({'employee_id':hr_employee_brw.id,'date_from':timesheet_start_date,'date_to':timesheet_end_date})
self.create_sickleave_timesheet(account_id, timesheets, value, key,hr_employee_brw)
def get_timesheet_start_date(self,cur_day):
user = self.env['res.users'].browse(self.env.uid)
r = user.company_id and user.company_id.timesheet_range or 'month'
if r == 'month':
timesheet_start_date = cur_day.strftime('%Y-%m-01')
elif r == 'week':
timesheet_start_date = (cur_day+ relativedelta(weekday=0, days=-6)).strftime('%Y-%m-%d')
elif r == 'year':
timesheet_start_date = cur_day.strftime('%Y-01-01')
else:
timesheet_start_date = cur_day
return timesheet_start_date
def get_timesheet_end_date(self,cur_day):
user = self.env['res.users'].browse(self.env.uid)
r = user.company_id and user.company_id.timesheet_range or 'month'
if r == 'month':
timesheet_end_date = (cur_day+ relativedelta(months=+1, day=1, days=-1)).strftime('%Y-%m-%d')
elif r == 'week':
timesheet_end_date = (cur_day+ relativedelta(weekday=6)).strftime('%Y-%m-%d')
elif r == 'year':
timesheet_end_date = cur_day.strftime('%Y-12-31')
else:
timesheet_end_date = cur_day
return timesheet_end_date
@api.one
def create_sickleave_timesheet(self, account_id, sheet, duration, day,hr_employee_brw):
"""
This function is use to create analytic timesheet based on the sick date and other inputs
:param account_id: analytic account id
:param sheet: timesheet id
:param duration: planned time of the leave
:param day: date of the leave
:param hr_employee_brw: employee browse record
:return: created record for the analytic timesheet
"""
timesheet_obj = self.pool.get('hr.analytic.timesheet')
cr = self.env.cr
uid = self.env.uid
emp_obj = self.env['hr.employee']
hour = duration
res = timesheet_obj.default_get(cr, uid, ['product_id','product_uom_id'])
if not res['product_uom_id']:
raise Warning(_('User Error! \nPlease define cost unit for this employee.'))
up = timesheet_obj.on_change_unit_amount(cr, uid, False, res['product_id'], hour,False, res['product_uom_id'])['value']
res['name'] = "Sick Leave on:" + day
res['account_id'] = account_id.id
res['unit_amount'] = hour
emp_journal = emp_obj.search([('user_id', '=', hr_employee_brw.user_id.id)]).journal_id
res['journal_id'] = emp_journal and emp_journal.id or False
res.update(up)
up = timesheet_obj.on_change_account_id(cr, uid, [], res['account_id']).get('value', {})
res.update(up)
res.update({
'date': day,
'user_id': hr_employee_brw.user_id.id,
'sheet_id': sheet.id,
})
return timesheet_obj.create(cr, SUPERUSER_ID, res)
def count_day_sickleave(self,hr_employee_brw):
res = {}
date_from = datetime.strptime(self.start_date, DEFAULT_SERVER_DATETIME_FORMAT)
date_to = datetime.strptime(self.end_date, DEFAULT_SERVER_DATETIME_FORMAT)
same_day = self.check_same_day(date_from, date_to)
temp_date = date_from
day_hours = 0.0
weekday = temp_date.weekday()
for contract in hr_employee_brw.contract_ids:
cont_start_date = datetime.strptime(contract.date_start, DEFAULT_SERVER_DATE_FORMAT)
if not contract.date_end:
if cont_start_date <= temp_date:
if same_day:
cur_hour = self.get_sameday_hours(date_from, date_to, contract.working_hours.attendance_ids)
day_hours += cur_hour
day_str = datetime.strftime(temp_date, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
new_hour = res.get(day_str, 0.0) + cur_hour
res.update({day_str: new_hour})
else:
fday_cur_hour = self.get_fday_hours(date_from, contract.working_hours.attendance_ids)
day_hours += fday_cur_hour
lday_cur_hour = self.get_lday_hours(date_to, contract.working_hours.attendance_ids)
day_hours += lday_cur_hour
fday_str = datetime.strftime(date_from, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
fday_new_hour = res.get(fday_str, 0.0) + fday_cur_hour
res.update({fday_str: fday_new_hour})
lday_str = datetime.strftime(date_to, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
lday_new_hour = res.get(lday_str, 0.0) + lday_cur_hour
res.update({lday_str: lday_new_hour})
else:
cont_end_date = datetime.strptime(contract.date_end, DEFAULT_SERVER_DATE_FORMAT)
cont_end_date += timedelta(days=1)
if cont_start_date <= temp_date and cont_end_date >= temp_date:
if same_day:
cur_hour = self.get_sameday_hours(date_from, date_to, contract.working_hours.attendance_ids)
day_hours += cur_hour
day_str = datetime.strftime(temp_date, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
new_hour = res.get(day_str, 0.0) + cur_hour
res.update({day_str: new_hour})
else:
fday_cur_hour = self.get_fday_hours(date_from, contract.working_hours.attendance_ids)
day_hours += fday_cur_hour
lday_cur_hour = self.get_lday_hours(date_to, contract.working_hours.attendance_ids)
day_hours += lday_cur_hour
fday_str = datetime.strftime(date_from, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
fday_new_hour = res.get(fday_str, 0.0) + fday_cur_hour
res.update({fday_str: fday_new_hour})
lday_str = datetime.strftime(date_to, DEFAULT_SERVER_DATETIME_FORMAT).split(" ")[0]
lday_new_hour = res.get(lday_str, 0.0) + lday_cur_hour
res.update({lday_str: lday_new_hour})
date_from = datetime.strptime(self.start_date.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
date_to = datetime.strptime(self.end_date.split(" ")[0], DEFAULT_SERVER_DATE_FORMAT)
temp_date = date_from
temp_date += timedelta(days=1)
while temp_date < date_to:
weekday = temp_date.weekday()
for contract in hr_employee_brw.contract_ids:
cont_start_date = datetime.strptime(contract.date_start, DEFAULT_SERVER_DATE_FORMAT)
cont_end_date = False
if not contract.date_end:
if cont_start_date <= temp_date:
cur_hour = self.get_hours(weekday, contract.working_hours.attendance_ids)
day_hours += cur_hour
day_str = datetime.strftime(temp_date, DEFAULT_SERVER_DATE_FORMAT).split(" ")[0]
new_hour = res.get(day_str, 0.0) + cur_hour
res.update({day_str: new_hour})
else:
cont_end_date = datetime.strptime(contract.date_end, DEFAULT_SERVER_DATE_FORMAT)
if cont_start_date <= temp_date and cont_end_date >= temp_date:
cur_hour = self.get_hours(weekday, contract.working_hours.attendance_ids)
day_hours += cur_hour
day_str = datetime.strftime(temp_date, DEFAULT_SERVER_DATE_FORMAT).split(" ")[0]
new_hour = res.get(day_str, 0.0) + cur_hour
res.update({day_str: new_hour})
temp_date += timedelta(days=1)
return res
def check_same_day(self, date_from, date_to):
return date_from.date() == date_to.date()
def get_sameday_hours(self, date_from, date_to, atten_ids):
weekday = date_from.weekday()
res = self.get_hours(weekday, atten_ids)
return res
def get_lday_hours(self, date_to, atten_ids):
weekday = date_to.weekday()
return self.get_hours(weekday, atten_ids)
def get_fday_hours(self, date_from, atten_ids):
weekday = date_from.weekday()
return self.get_hours(weekday, atten_ids)
def get_hours(self, weekday, atten_ids):
res = 0.0
for atten in atten_ids:
if int(atten.dayofweek) == weekday:
res += atten.hour_to - atten.hour_from
return res

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="sick_leave_form_view" model='ir.ui.view'>
<field name="name">sick.leave.form.view</field>
<field name="model">hr.sick.leave</field>
<field name="arch" type="xml">
<form>
<p>This wizard is use to fill up the time sheet when employee is sick.</p>
<group>
<field name='start_date' required="1"/>
<field name='end_date' required="1"/>
</group>
<footer>
<button name='confirm_sick_time' type='object' string="Fill Sick Time" />
or
<button special="cancel" string="Cancel" class='oe_link' />
</footer>
</form>
</field>
</record>
<record id="sick_leave_action" model="ir.actions.act_window">
<field name="name">Fill Sick Leave</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hr.sick.leave</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<act_window id="launch_sick_leave_wizard"
name="Fill Employee Sick Leave"
src_model="hr.employee"
res_model="hr.sick.leave"
view_mode="form,tree"
target="new"
groups="base.group_hr_manager"
key2="client_action_multi"/>
</data>
</openerp>

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
import models

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
{
'name': "ITIS HR Notifications",
'summary': """
A module by ITIS to send various HR notifications""",
'description': """
A module by ITIS to send various HR notifications
""",
'author': "ITIS AG",
'website': "http://itis.de",
'category': 'Human Resource',
'version': '1.0.55.0',
'depends': ['hr', 'itis_hr_attendance_extend', 'itis_hr_extend'],
'data': [
'data/email_templates.xml',
'hr_view.xml',
'data/ir_cron.xml',
'security/ir.model.access.csv',
],
'application': False,

View File

@ -0,0 +1,112 @@
<?xml version="1.0"?>
<openerp>
<data>
<record id="email_template_training_end" model="email.template">
<field name="name">Training_end Notification</field>
<field name="model_id" ref="itis_hr_notifications.model_hr_notifications" />
<field name="auto_delete" eval="True" />
<field name="email_from">${(user.email or '') | safe}</field>
<field name="email_to">${( object.employee_id.work_email or object.user_id != False and object.user_id.email )|safe}</field>
<field name="subject">Training End Notification</field>
<field name="body_html"><![CDATA[
<p>Hello ${object.employee_id and object.employee_id.name or object.user_id and object.user_id.name},</p>
<br/>
<p>please be informed that the probation period for ${object.for_emp.name} is ending on ${object.date}.
</p><br/>
<p>Regards</p>
<p>Your Human-Resources Team</p>
]]></field>
</record>
<record id="email_template_work_permit_end" model="email.template">
<field name="name">work permit Notification</field>
<field name="model_id" ref="itis_hr_notifications.model_hr_notifications" />
<field name="auto_delete" eval="True" />
<field name="email_from">${(user.email or '') | safe}</field>
<field name="email_to">${( object.employee_id.work_email or object.user_id != False and object.user_id.email )|safe}</field>
<field name="subject">Work Permit End Notification</field>
<field name="body_html"><![CDATA[
<p>Hello ${object.employee_id and object.employee_id.name or object.user_id and object.user_id.name},</p>
<br/>
<p>please be informed that the work permit for ${object.for_emp.name} is ending on ${object.date}.</p>
<br/>
<p>Regards</p>
<p>Your Human-Resources Team</p>
]]></field>
</record>
<record id="email_template_temp_empl" model="email.template">
<field name="name">Term end Notification</field>
<field name="model_id" ref="itis_hr_notifications.model_hr_notifications" />
<field name="auto_delete" eval="True" />
<field name="email_from">${(user.email or '') | safe}</field>
<field name="email_to">${( object.employee_id.work_email or object.user_id != False and object.user_id.email )|safe}</field>
<field name="subject">Term End Notification</field>
<field name="body_html"><![CDATA[
<p>Hello ${object.employee_id and object.employee_id.name or object.user_id and object.user_id.name},</p>
<br/>
<p>please be informed that the temporary employment for ${object.for_emp.name} is ending on ${object.date}.</p>
<br/>
<p>Regards</p>
<p>Your Human-Resources Team</p>
]]></field>
</record>
<record id="email_template_emp_disable" model="email.template">
<field name="name">Disability Notification</field>
<field name="model_id" ref="itis_hr_notifications.model_hr_notifications" />
<field name="auto_delete" eval="True" />
<field name="email_from">${(user.email or '') | safe}</field>
<field name="email_to">${( object.employee_id.work_email or object.user_id != False and object.user_id.email )|safe}</field>
<field name="subject">Disability Notification</field>
<field name="body_html"><![CDATA[
<p>Hello ${object.employee_id and object.employee_id.name or object.user_id and object.user_id.name},</p>
<br/>
<p>please be informed that the severely handicapped pass for ${object.for_emp.name} is ending on ${object.date}.
<br/>
<p>Regards</p>
<p>Your Human-Resources Team</p>
]]></field>
</record>
<record id="email_template_leave_end" model="email.template">
<field name="name">Leave end Notification</field>
<field name="model_id" ref="itis_hr_notifications.model_hr_notifications" />
<field name="auto_delete" eval="True" />
<field name="email_from">${(user.email or '') | safe}</field>
<field name="email_to">${( object.employee_id.work_email or object.user_id != False and object.user_id.email )|safe}</field>
<field name="subject">Leave Balance Notification</field>
<field name="body_html"><![CDATA[
<p>Hello ${object.employee_id and object.employee_id.name or object.user_id and object.user_id.name},</p>
<br/>
<p>please be informed that you have ${object.days} remaining leave.</p>
<p>The leave needs to be taken until the end of march.</p>
<p>Remaining leave from the old year will expire on 1st of April.</p>
<br>
<p>Regards</p>
<p>Your Human-Resources Team</p>
]]></field>
</record>
<record id="email_template_overtime" model="email.template">
<field name="name">Overtime Notification</field>
<field name="model_id" ref="itis_hr_notifications.model_hr_notifications" />
<field name="auto_delete" eval="True" />
<field name="email_from">${(user.email or '') | safe}</field>
<field name="email_to">${( object.employee_id.work_email or object.user_id != False and object.user_id.email )|safe}</field>
<field name="subject">Overtime Notification</field>
<field name="body_html"><![CDATA[
<p>Hello ${object.employee_id and object.employee_id.name or object.user_id and object.user_id.name},</p>
<br/>
<p>please be informed that the timesheet for ${object.for_emp.name} is showing ${object.hours}.</p>
<br>
<p>Regards</p>
<p>Your Human-Resources Team</p>
]]></field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="ir_cron_hr_contract_notify"
model="ir.cron">
<field name="name">HR Contract Notifications</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall" />
<field eval="'hr.contract'" name="model" />
<field eval="'send_notification'" name="function" />
<field eval="'()'" name="args" />
</record>
<record id="ir_cron_hr_notify_disable"
model="ir.cron">
<field name="name">Employee Disability</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall" />
<field eval="'hr.employee'" name="model" />
<field eval="'check_disability'" name="function" />
<field eval="'()'" name="args" />
</record>
<record id="ir_cron_hr_leave_bal"
model="ir.cron">
<field name="name">Employee Leave Balance</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall" />
<field eval="'hr.employee'" name="model" />
<field eval="'check_leave_bal'" name="function" />
<field eval="'()'" name="args" />
</record>
<record id="ir_cron_hr_employee_overtime"
model="ir.cron">
<field name="name">Employee Overtime</field>
<field name="interval_number">1</field>
<field name="interval_type">months</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall" />
<field eval="'hr.employee'" name="model" />
<field eval="'check_overtime'" name="function" />
<field eval="'()'" name="args" />
</record>
</data>
</openerp>

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="itis_view_human_resources_configuration" model="ir.ui.view">
<field name="name">ITIS hr settings</field>
<field name="model">hr.config.settings</field>
<field name="inherit_id" ref='hr.view_human_resources_configuration' />
<field name="arch" type="xml">
<group name="contract_grp" position='after'>
<group name="notification_grp">
<label for="id" string="Notifications" />
<div>
<div>
<label for="training_end_day" />
<field name="training_end_day" class="oe_inline" />
<label string=" Weeks" />
</div>
<div>
<label for="work_permit" />
<field name="work_permit" class="oe_inline" />
<label string=" Weeks" />
</div>
<div>
<label for="term_end" />
<field name="term_end" class="oe_inline" />
<label string=" Weeks" />
</div>
<div>
<label for="savirity" />
<field name="savirity" class="oe_inline" />
<label string=" Weeks" />
</div>
<div>
<label for="remaining_leaves" />
<field name="remaining_leaves" class="oe_inline" />
<label string=" Weeks" />
</div>
<!-- <div> -->
<!-- <label for="over_time" /> -->
<!-- <field name="over_time" class="oe_inline" /> -->
<!-- </div> -->
</div>
</group>
</group>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,328 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * itis_hr_notifications
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-12-11 13:55+0000\n"
"PO-Revision-Date: 2016-12-11 18:53+0100\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.4\n"
#. module: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_temp_empl
msgid ""
"\n"
"\t\t\t<p>Hello ${object.employee_id.name},</p>\n"
"\t\t\t\n"
"\t\t\t<p>please be informed that the temporary employment for ${object."
"employee_id.name} is ending on ${object.date}.</p>\n"
"\t\t\t<br/>\n"
"\t\t\t<p>Regards</p>\n"
"\t\t\t<p>Your Human-Resources Team</p>\n"
"\t\t\t"
msgstr ""
"\n"
"<p>Hallo ${object.employee_id.name},</p>\n"
"\n"
"<p>Das befristete Arbeitsverhältnis für ${object.employee_id.name} endet am "
"${object.date}.</p>\n"
"<br/>\n"
"<p>mit freundlichen Grüßen</p>\n"
"<p>Ihre Personalverwaltung</p>\n"
"\t\t\t"
#. module: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_training_end
msgid ""
"\n"
"\t\t\t<p>Hello ${object.employee_id.name},</p>\n"
"\t\t\t<br/>\n"
"\t\t\t<p>please be informed that the probation period for ${object."
"employee_id.name} is ending on ${object.date}.\n"
"\t\t\t</p><br/>\n"
"\t\t\t<p>Regards</p>\n"
"\t\t\t<p>Your Human-Resources Team</p>\t\t\n"
"\t\t\t"
msgstr ""
"\n"
"<p>Hallo ${object.employee_id.name},</p><br/><p>die Probezeit von ${object."
"employee_id.name} endet am ${object.date}.</p><br/><p>mit freundlichen "
"Grüßen</p><p>Ihre Personalverwaltung</p>\n"
"\t\t\t"
#. module: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_emp_disable
msgid ""
"\n"
"\t\t\t<p>Hello ${object.employee_id.name},</p>\n"
"\t\t\t<br/>\n"
"\t\t\t<p>please be informed that the severely handicapped pass for ${object."
"employee_id.name} is ending on ${object.date}.\n"
"\t\t\t<br/>\n"
"\t\t\t<p>Regards</p>\n"
"\t\t\t<p>Your Human-Resources Team</p>\t\t\n"
"\t\t\t"
msgstr ""
"\n"
"<p>Hallo ${object.employee_id.name},</p><br/><p>der Schwerbehindertenausweis "
"für ${object.employee_id.name} läuft aus am ${object.date}.<br/><p>mit "
"freundlichen Grüßen</p><p>Ihre Personalverwaltung</p>\n"
"\t\t\t"
#. module: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_overtime
msgid ""
"\n"
"\t\t\t<p>Hello ${object.employee_id.name},</p>\n"
"\t\t\t<br/>\n"
"\t\t\t<p>please be informed that the timesheet for ${object.employee_id."
"name} is showing ${object.hours}.</p>\n"
"\t\t\t<br>\n"
"\t\t\t<p>Regards</p>\n"
"\t\t\t<p>Your Human-Resources Team</p>\n"
"\t\t\t"
msgstr ""
"\n"
"<p>Hallo ${object.employee_id.name},</p><br/><p>das Überstundenkonto von "
"${object.employee_id.name} beläuft sich auf ${object.hours} Stunden.</"
"p><br><p>mit freundlichen Grüßen</p><p>Ihre Personalverwaltung</p>\n"
"\t\t\t"
#. module: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_leave_end
msgid ""
"\n"
"\t\t\t<p>Hello ${object.employee_id.name},</p>\n"
"\t\t\t<br/>\n"
"\t\t\t<p>please be informed that you have ${object.days} remaining leave.</"
"p>\n"
"\t\t\t<p>The leave needs to be taken until the end of march.</p> \n"
"\t\t\t<p>Remaining leave from the old year will expire on 1st of April.</p>\n"
"\t\t\t<br>\n"
"\t\t\t<p>Regards</p>\n"
"\t\t\t<p>Your Human-Resources Team</p>\n"
"\t\t\t"
msgstr ""
"\n"
"<p>Hallo ${object.employee_id.name},</p><br/><p>Sie haben ${object.days} "
"Tage Resturlaub..</p><p>Der Resturlaub muss bis 31. März genommen worden "
"sein.</p> <p>Verbleibender Resturlaub des Vorjahres, verfällt am 01. April.</"
"p><br><p>mit freundlichen Grüßen</p><p>Ihre Personalverwaltung</p>\n"
"\t\t\t"
#. module: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_work_permit_end
msgid ""
"\n"
"\t\t\t<p>Hello ${object.employee_id.name},</p>\n"
"\n"
"\t\t\t<p>please be informed that the work permit for ${object.employee_id."
"name} is ending on ${object.date}.</p>\n"
"\t\t\t<br/>\n"
"\t\t\t<p>Regards</p>\n"
"\t\t\t<p>Your Human-Resources Team</p>\n"
"\t\t\t"
msgstr ""
"\n"
"<p>Hallo ${object.employee_id.name},</p><p>Die Arbeitserlaubnis von ${object."
"employee_id.name} endet am ${object.date}.</p><br/><p>mit freundlichen "
"Grüßen</p><p>Ihre Personalverwaltung</p>\n"
"\t\t\t"
#. module: itis_hr_notifications
#: model:ir.model,name:itis_hr_notifications.model_res_company
msgid "Companies"
msgstr "Unternehmen"
#. module: itis_hr_notifications
#: model:ir.model,name:itis_hr_notifications.model_hr_contract
msgid "Contract"
msgstr "Arbeitsvertrag"
#. module: itis_hr_notifications
#: field:hr.notifications,create_uid:0
msgid "Created by"
msgstr "Created by"
#. module: itis_hr_notifications
#: field:hr.notifications,create_date:0
msgid "Created on"
msgstr "Created on"
#. module: itis_hr_notifications
#: field:hr.notifications,date:0
msgid "Date"
msgstr "Datum"
#. module: itis_hr_notifications
#: field:hr.notifications,days:0
msgid "Days"
msgstr "Tage"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Disability"
msgstr "Behinderung"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_emp_disable
msgid "Disability Notification"
msgstr "Erinnerung Behindertenausweis"
#. module: itis_hr_notifications
#: field:hr.notifications,employee_id:0 field:hr.notifications,user_id:0
#: model:ir.model,name:itis_hr_notifications.model_hr_employee
msgid "Employee"
msgstr "Mitarbeiter/-in"
#. module: itis_hr_notifications
#: field:hr.notifications,for_emp:0
msgid "For Employee"
msgstr "für mitarbeiter"
#. module: itis_hr_notifications
#: field:hr.config.settings,remaining_leaves:0
#: field:res.company,remaining_leaves:0
msgid "Holiday Season notification before"
msgstr "Benachrichtigung Resturlaub"
#. module: itis_hr_notifications
#: help:hr.config.settings,remaining_leaves:0
#: help:res.company,remaining_leaves:0
msgid "Holiday season Expiration"
msgstr "Benachrichtigung Verfall Resturlaub"
#. module: itis_hr_notifications
#: field:hr.notifications,hours:0
msgid "Hours"
msgstr "Stunden"
#. module: itis_hr_notifications
#: field:hr.notifications,id:0
msgid "ID"
msgstr "ID"
#. module: itis_hr_notifications
#: field:hr.notifications,write_uid:0
msgid "Last Updated by"
msgstr "Last Updated by"
#. module: itis_hr_notifications
#: field:hr.notifications,write_date:0
msgid "Last Updated on"
msgstr "Last Updated on"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Leave Balance"
msgstr "Leave Balance"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_leave_end
msgid "Leave Balance Notification"
msgstr "Leave Balance Notification"
#. module: itis_hr_notifications
#: view:hr.config.settings:itis_hr_notifications.itis_view_human_resources_configuration
msgid "Notifications"
msgstr "Notifications"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Overtime"
msgstr "Überstunden"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_overtime
msgid "Overtime Notification"
msgstr "Benachrichtigung Überstunden"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Permit End"
msgstr "Ende Erlaubnis"
#. module: itis_hr_notifications
#: field:hr.config.settings,savirity:0 field:res.company,savirity:0
msgid "Savirity notification before"
msgstr "Erinnerung Behindertenausweis"
#. module: itis_hr_notifications
#: help:hr.config.settings,savirity:0 help:res.company,savirity:0
msgid "Severely handicapped persons"
msgstr "Erinnerung Behindertenausweis"
#. module: itis_hr_notifications
#: field:hr.config.settings,term_end:0 field:res.company,term_end:0
msgid "Term End notification before"
msgstr "Benachrichtigung Vertragsende"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Term End"
msgstr "Vertragsende"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_temp_empl
msgid "Term End Notification"
msgstr "Benachrichtigung Vertragsende"
#. module: itis_hr_notifications
#: help:hr.config.settings,term_end:0 help:res.company,term_end:0
msgid "Term End Notification before months"
msgstr "Benachrichtigung Vertragsende"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Training End"
msgstr "Ende Probezeit"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_training_end
msgid "Training End Notification"
msgstr "Benachrichtigung Ende der Probezeit"
#. module: itis_hr_notifications
#: help:hr.config.settings,training_end_day:0
#: help:res.company,training_end_day:0
msgid "Training End Notification before months"
msgstr "Benachrichtigung Ende der Probezeit"
#. module: itis_hr_notifications
#: field:hr.config.settings,training_end_day:0
#: field:res.company,training_end_day:0
msgid "Training End notification before"
msgstr "Benachrichtigung Ende der Probezeit"
#. module: itis_hr_notifications
#: field:hr.notifications,type:0
msgid "Type"
msgstr "Typ"
#. module: itis_hr_notifications
#: view:hr.config.settings:itis_hr_notifications.itis_view_human_resources_configuration
msgid "Weeks"
msgstr "Wochen"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_work_permit_end
msgid "Work Permit End Notification"
msgstr "Benachrichtigung Ende der Arbeitserlaubnis"
#. module: itis_hr_notifications
#: field:hr.config.settings,work_permit:0 field:res.company,work_permit:0
msgid "Work Permit notification before End"
msgstr "Benachrichtigung Ende der Arbeitserlaubnis"
#. module: itis_hr_notifications
#: help:hr.config.settings,work_permit:0 help:res.company,work_permit:0
msgid "Work permit Notification before months"
msgstr "Benachrichtigung Ende der Arbeitserlaubnis"

View File

@ -0,0 +1,332 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * itis_hr_notifications
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-12-11 13:56+0000\n"
"PO-Revision-Date: 2016-12-11 13:56+0000\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: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_temp_empl
msgid "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
" \n"
" <p>please be informed that the temporary employment for ${object.employee_id.name} is ending on ${object.date}.</p>\n"
" <br/>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p>\n"
" "
msgstr "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
" \n"
" <p>please be informed that the temporary employment for ${object.employee_id.name} is ending on ${object.date}.</p>\n"
" <br/>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p>\n"
" "
#. module: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_training_end
msgid "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
" <br/>\n"
" <p>please be informed that the probation period for ${object.employee_id.name} is ending on ${object.date}.\n"
" </p><br/>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p> \n"
" "
msgstr "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
" <br/>\n"
" <p>please be informed that the probation period for ${object.employee_id.name} is ending on ${object.date}.\n"
" </p><br/>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p> \n"
" "
#. module: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_emp_disable
msgid "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
" <br/>\n"
" <p>please be informed that the severely handicapped pass for ${object.employee_id.name} is ending on ${object.date}.\n"
" <br/>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p> \n"
" "
msgstr "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
" <br/>\n"
" <p>please be informed that the severely handicapped pass for ${object.employee_id.name} is ending on ${object.date}.\n"
" <br/>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p> \n"
" "
#. module: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_overtime
msgid "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
" <br/>\n"
" <p>please be informed that the timesheet for ${object.employee_id.name} is showing ${object.hours}.</p>\n"
" <br>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p>\n"
" "
msgstr "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
" <br/>\n"
" <p>please be informed that the timesheet for ${object.employee_id.name} is showing ${object.hours}.</p>\n"
" <br>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p>\n"
" "
#. module: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_leave_end
msgid "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
" <br/>\n"
" <p>please be informed that you have ${object.days} remaining leave.</p>\n"
" <p>The leave needs to be taken until the end of march.</p> \n"
" <p>Remaining leave from the old year will expire on 1st of April.</p>\n"
" <br>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p>\n"
" "
msgstr "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
" <br/>\n"
" <p>please be informed that you have ${object.days} remaining leave.</p>\n"
" <p>The leave needs to be taken until the end of march.</p> \n"
" <p>Remaining leave from the old year will expire on 1st of April.</p>\n"
" <br>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p>\n"
" "
#. module: itis_hr_notifications
#: model:email.template,body_html:itis_hr_notifications.email_template_work_permit_end
msgid "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
"\n"
" <p>please be informed that the work permit for ${object.employee_id.name} is ending on ${object.date}.</p>\n"
" <br/>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p>\n"
" "
msgstr "\n"
" <p>Hello ${object.employee_id.name},</p>\n"
"\n"
" <p>please be informed that the work permit for ${object.employee_id.name} is ending on ${object.date}.</p>\n"
" <br/>\n"
" <p>Regards</p>\n"
" <p>Your Human-Resources Team</p>\n"
" "
#. module: itis_hr_notifications
#: model:ir.model,name:itis_hr_notifications.model_res_company
msgid "Companies"
msgstr "Companies"
#. module: itis_hr_notifications
#: model:ir.model,name:itis_hr_notifications.model_hr_contract
msgid "Contract"
msgstr "Contract"
#. module: itis_hr_notifications
#: field:hr.notifications,create_uid:0
msgid "Created by"
msgstr "Created by"
#. module: itis_hr_notifications
#: field:hr.notifications,create_date:0
msgid "Created on"
msgstr "Created on"
#. module: itis_hr_notifications
#: field:hr.notifications,date:0
msgid "Date"
msgstr "Date"
#. module: itis_hr_notifications
#: field:hr.notifications,days:0
msgid "Days"
msgstr "Days"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Disability"
msgstr "Disability"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_emp_disable
msgid "Disability Notification"
msgstr "Disability Notification"
#. module: itis_hr_notifications
#: field:hr.notifications,employee_id:0
#: field:hr.notifications,user_id:0
#: model:ir.model,name:itis_hr_notifications.model_hr_employee
msgid "Employee"
msgstr "Employee"
#. module: itis_hr_notifications
#: field:hr.notifications,for_emp:0
msgid "For Employee"
msgstr "For Employee"
#. module: itis_hr_notifications
#: field:hr.config.settings,remaining_leaves:0
#: field:res.company,remaining_leaves:0
msgid "Holiday Season notification before"
msgstr "Holiday Season notification before"
#. module: itis_hr_notifications
#: help:hr.config.settings,remaining_leaves:0
#: help:res.company,remaining_leaves:0
msgid "Holiday season Expiration"
msgstr "Holiday season Expiration"
#. module: itis_hr_notifications
#: field:hr.notifications,hours:0
msgid "Hours"
msgstr "Hours"
#. module: itis_hr_notifications
#: field:hr.notifications,id:0
msgid "ID"
msgstr "ID"
#. module: itis_hr_notifications
#: field:hr.notifications,write_uid:0
msgid "Last Updated by"
msgstr "Last Updated by"
#. module: itis_hr_notifications
#: field:hr.notifications,write_date:0
msgid "Last Updated on"
msgstr "Last Updated on"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Leave Balance"
msgstr "Leave Balance"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_leave_end
msgid "Leave Balance Notification"
msgstr "Leave Balance Notification"
#. module: itis_hr_notifications
#: view:hr.config.settings:itis_hr_notifications.itis_view_human_resources_configuration
msgid "Notifications"
msgstr "Notifications"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Overtime"
msgstr "Overtime"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_overtime
msgid "Overtime Notification"
msgstr "Overtime Notification"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Permit End"
msgstr "Permit End"
#. module: itis_hr_notifications
#: field:hr.config.settings,savirity:0
#: field:res.company,savirity:0
msgid "Savirity notification before"
msgstr "Savirity notification before"
#. module: itis_hr_notifications
#: help:hr.config.settings,savirity:0
#: help:res.company,savirity:0
msgid "Severely handicapped persons"
msgstr "Severely handicapped persons"
#. module: itis_hr_notifications
#: field:hr.config.settings,term_end:0
#: field:res.company,term_end:0
msgid "Term End notification before"
msgstr "Term End notification before"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Term End"
msgstr "Term End"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_temp_empl
msgid "Term End Notification"
msgstr "Term End Notification"
#. module: itis_hr_notifications
#: help:hr.config.settings,term_end:0
#: help:res.company,term_end:0
msgid "Term End Notification before months"
msgstr "Term End Notification before months"
#. module: itis_hr_notifications
#: selection:hr.notifications,type:0
msgid "Training End"
msgstr "Training End"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_training_end
msgid "Training End Notification"
msgstr "Training End Notification"
#. module: itis_hr_notifications
#: help:hr.config.settings,training_end_day:0
#: help:res.company,training_end_day:0
msgid "Training End Notification before months"
msgstr "Training End Notification before months"
#. module: itis_hr_notifications
#: field:hr.config.settings,training_end_day:0
#: field:res.company,training_end_day:0
msgid "Training End notification before"
msgstr "Training End notification before"
#. module: itis_hr_notifications
#: field:hr.notifications,type:0
msgid "Type"
msgstr "Type"
#. module: itis_hr_notifications
#: view:hr.config.settings:itis_hr_notifications.itis_view_human_resources_configuration
msgid "Weeks"
msgstr "Weeks"
#. module: itis_hr_notifications
#: model:email.template,subject:itis_hr_notifications.email_template_work_permit_end
msgid "Work Permit End Notification"
msgstr "Work Permit End Notification"
#. module: itis_hr_notifications
#: field:hr.config.settings,work_permit:0
#: field:res.company,work_permit:0
msgid "Work Permit notification before End"
msgstr "Work Permit notification before End"
#. module: itis_hr_notifications
#: help:hr.config.settings,work_permit:0
#: help:res.company,work_permit:0
msgid "Work permit Notification before months"
msgstr "Work permit Notification before months"

View File

@ -0,0 +1,324 @@
# -*- coding: utf-8 -*-
from openerp import models, fields, api, _
from datetime import datetime
from dateutil.relativedelta import relativedelta as delta
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as DF
import re
class res_company(models.Model):
_inherit = 'res.company'
training_end_day = fields.Integer('Training End notification before', help="Training End Notification before months", default=2)
work_permit = fields.Integer('Work Permit notification before End', help="Work permit Notification before months", default=3)
term_end = fields.Integer('Term End notification before', help="Term End Notification before months", default=5)
savirity = fields.Integer('Savirity notification before', help="Severely handicapped persons", default=2)
remaining_leaves = fields.Integer('Holiday Season notification before', help="Holiday season Expiration", default=3)
class hr_config_settings(models.TransientModel):
_inherit = 'hr.config.settings'
training_end_day = fields.Integer('Training End notification before', help="Training End Notification before months", default=2)
work_permit = fields.Integer('Work Permit notification before End', help="Work permit Notification before months", default=3)
term_end = fields.Integer('Term End notification before', help="Term End Notification before months", default=5)
savirity = fields.Integer('Savirity notification before', help="Severely handicapped persons", default=2)
remaining_leaves = fields.Integer('Holiday Season notification before', help="Holiday season Expiration", default=3)
def get_default_notification(self, cr, uid, fields, context=None):
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
return {
'training_end_day': user.company_id.training_end_day,
'work_permit': user.company_id.work_permit,
'term_end': user.company_id.term_end,
'savirity': user.company_id.savirity,
'remaining_leaves': user.company_id.remaining_leaves
}
def set_default_notification(self, cr, uid, ids, context=None):
config = self.browse(cr, uid, ids[0], context)
user = self.pool.get('res.users').browse(cr, uid, uid, context)
user.company_id.write({
'training_end_day': config.training_end_day,
'work_permit': config.work_permit,
'term_end': config.term_end,
'savirity': config.savirity,
'remaining_leaves': config.remaining_leaves
})
class hr_notifications(models.Model):
_name='hr.notifications'
employee_id = fields.Many2one('hr.employee', "Employee")
user_id = fields.Many2one('res.users', "Employee")
for_emp = fields.Many2one('hr.employee', "For Employee")
days = fields.Integer('Days')
hours = fields.Float("Hours", digits=(5, 2))
date = fields.Date('Date')
type = fields.Selection([('training_end','Training End'),
('permit_end','Permit End'),
('term_end','Term End'),
('disability','Disability'),
('leave_balance','Leave Balance'),
('disability','Disability'),
('overtime','Overtime'),
], "Type")
@api.multi
def send(self):
template_env = self.env['email.template']
template = False
#if self.type == 'training_end':
# template = self.env.ref('itis_hr_notifications.email_template_training_end', False)
#elif self.type == 'permit_end':
# template = self.env.ref('itis_hr_notifications.email_template_work_permit_end', False)
#elif self.type == 'term_end':
# template = self.env.ref('itis_hr_notifications.email_template_temp_empl', False)
#elif self.type == 'disability':
# template = self.env.ref('itis_hr_notifications.email_template_emp_disable', False)
#elif self.type == 'leave_balance':
# template = self.env.ref('itis_hr_notifications.email_template_leave_end', False)
#elif self.type == 'overtime':
# template = self.env.ref('itis_hr_notifications.email_template_overtime', False)
if template:
template.send_mail(self.id)
@api.model
def create_notification(self, type, data):
if type == 'training_end':
mail_dict = self.get_usermail(data.get('emp'),employee=True, manager=True, parent=True)
for emp in mail_dict.get('employee'):
vals = {
'employee_id': emp.id,
'date': data.get('date'),
'type': 'training_end',
'for_emp': data.get('emp').id,
}
notification = self.create(vals)
notification.send()
for user in mail_dict.get('users'):
vals = {
'user_id': user.id,
'date': data.get('date'),
'type': 'training_end',
'for_emp': data.get('emp').id,
}
notification = self.create(vals)
notification.send()
if type == 'permit_end':
mail_dict = self.get_usermail(data.get('emp'), employee=False, manager=True, parent=True)
for emp in mail_dict.get('employee'):
vals = {
'employee_id': emp.id,
'date': data.get('date'),
'type': 'permit_end',
'for_emp': data.get('emp').id,
}
notification = self.create(vals)
notification.send()
for user in mail_dict.get('users'):
vals = {
'user_id': user.id,
'date': data.get('date'),
'type': 'permit_end',
'for_emp': data.get('emp').id,
}
notification = self.create(vals)
notification.send()
if type == 'term_end':
mail_dict = self.get_usermail(data.get('emp'), employee=True, manager=True, parent=True)
for emp in mail_dict.get('employee'):
vals = {
'employee_id': emp.id,
'date': data.get('date'),
'type': 'term_end',
'for_emp': data.get('emp').id,
}
notification = self.create(vals)
notification.send()
for user in mail_dict.get('users'):
vals = {
'user_id': user.id,
'date': data.get('date'),
'type': 'term_end',
'for_emp': data.get('emp').id,
}
notification = self.create(vals)
notification.send()
if type == 'disability':
mail_dict = self.get_usermail(data.get('emp'), employee=True, manager=True, parent=False)
for emp in mail_dict.get('employee'):
vals = {
'employee_id': emp.id,
'date': data.get('date'),
'type': 'disability',
'for_emp': data.get('emp').id,
}
notification = self.create(vals)
notification.send()
for user in mail_dict.get('users'):
vals = {
'user_id': user.id,
'date': data.get('date'),
'type': 'disability',
'for_emp': data.get('emp').id,
}
notification = self.create(vals)
notification.send()
if type == 'leave_balance':
mail_dict = self.get_usermail(data.get('emp'), employee=True, manager=False, parent=False)
for emp in mail_dict.get('employee'):
vals = {
'employee_id': emp.id,
'date': data.get('date'),
'type': 'leave_balance',
'for_emp': data.get('emp').id,
'days': abs(data.get('emp').leave_days + data.get('emp').additional_leave_days - data.get('emp').approved_leaves)
}
notification = self.create(vals)
notification.send()
if type == 'overtime':
mail_dict = self.get_usermail(data.get('emp'), employee=True, manager=True, parent=True)
for emp in mail_dict.get('employee'):
vals = {
'employee_id': emp.id,
'date': data.get('date'),
'type': 'overtime',
'for_emp': data.get('emp').id,
# 'hours': data.get('emp').overtime_count
'hours': data.get('emp').employee_overtime_id.emp_overtime_count
}
notification = self.create(vals)
notification.send()
for user in mail_dict.get('users'):
vals = {
'user_id': user.id,
'date': data.get('date'),
'type': 'overtime',
'for_emp': data.get('emp').id,
# 'hours': data.get('emp').overtime_count
'hours': data.get('emp').employee_overtime_id.emp_overtime_count
}
notification = self.create(vals)
notification.send()
@api.model
def get_usermail(self, emp, employee=False, manager=False, parent=False):
# print employee, manager, parent
mail_dict = {'employee': [], 'users': []}
groups_env = self.env['res.groups']
if employee:
mail_dict['employee'].append(emp)
if parent:
if emp and emp.parent_id and emp.parent_id not in mail_dict['employee']:
mail_dict['employee'].append(emp.parent_id)
if manager:
groups = [self.env.ref('base.group_hr_manager').id]
for group in groups_env.browse(groups):
for user in group.users:
if user.login and re.match('[^@]+@[^@]+\.[^@]+', user.login):
flag = True
for emp in mail_dict['employee']:
if emp.user_id.id == user.id:
flag = False
if flag:
mail_dict['users'].append(user)
return mail_dict
class hr_contract(models.Model):
_inherit = 'hr.contract'
@api.model
def send_notification(self):
notify_env = self.env['hr.notifications']
user_rec = self.env['res.users'].search([('id', '=', self._uid)], limit=1)
contract_ids = self.search([])
for rec in contract_ids:
today = datetime.now()#.strftime(DF)
#training_check
if rec.trial_date_end:
exp = user_rec.company_id.training_end_day or 1
date_after_month = today + delta(weeks=exp)
if date_after_month.strftime(DF) == rec.trial_date_end:
data_dict = {"emp":rec.employee_id, 'date': rec.trial_date_end}
notify_env.create_notification('training_end', data_dict)
#work Permit check
if rec.visa_expire:
exp = user_rec.company_id.work_permit or 1
date_after_month = today + delta(weeks=exp)
if date_after_month.strftime(DF) == rec.visa_expire:
data_dict = {"emp":rec.employee_id, 'date': rec.visa_expire}
notify_env.create_notification('permit_end', data_dict)
#end of term
if rec.date_end:
exp = user_rec.company_id.term_end or 1
date_after_month = today + delta(weeks=exp)
new_contract = self.search([('employee_id', '=', rec.employee_id.id), ('date_start', '>', rec.date_end)])
if date_after_month.strftime(DF) == rec.date_end and not new_contract:
data_dict = {"emp":rec.employee_id, 'date': rec.date_end}
notify_env.create_notification('term_end', data_dict)
class hr_employee(models.Model):
_inherit = 'hr.employee'
@api.model
def check_disability(self):
notify_env = self.env['hr.notifications']
user_rec = self.env['res.users'].search([('id', '=', self._uid)], limit=1)
emp_ids = self.search([('disability_limited_until', '!=', False)])
exp = user_rec.company_id.savirity or 1
date_after_month = datetime.now() + delta(weeks=exp)
for rec in emp_ids:
if date_after_month.strftime(DF) == rec.disability_limited_until:
data_dict = {"emp":rec, 'date': rec.disability_limited_until}
notify_env.create_notification('disability', data_dict)
@api.model
def check_leave_bal(self):
notify_env = self.env['hr.notifications']
user_rec = self.env['res.users'].search([('id', '=', self._uid)], limit=1)
exp = user_rec.company_id.remaining_leaves or 1
year_end = datetime(datetime.today().year, 12, 31)
emp_ids = self.search([])
if year_end.strftime(DF) == datetime.now().strftime(DF):
for rec in emp_ids:
if rec.leave_days + rec.additional_leave_days - rec.approved_leaves:
data_dict = {'emp': rec, 'date':year_end.strftime(DF)}
notify_env.create_notification('leave_balance', data_dict)
@api.model
def check_overtime(self):
emp_ids = self.search([])
notify_env = self.env['hr.notifications']
for emp in emp_ids:
# if emp.overtime_count > 40.0 or emp.overtime_count < -40.0:
if emp.employee_overtime_id.emp_overtime_count > 39.99 or emp.employee_overtime_id.emp_overtime_count < -39.99:
data_dict = {'emp': emp}
notify_env.create_notification('overtime', data_dict)
return True
# @api.multi
# def update_overtime_count(self, ot_time, reason):
# res = super(hr_employee, self).update_overtime_count(ot_time, reason)
# if self.overtime_count > 0.0:
# notify_env = self.env['hr.notifications']
# data_dict = {'emp': self}
# notify_env.create_notification('overtime', data_dict)
# return res

View File

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_notification,access_notification,model_hr_notifications,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_notification access_notification model_hr_notifications 1 1 1 1

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from . import models

View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': "ITIS Ldap User Config",
'summary': """ Module to configure new ldap user with old user""",
'description': """
Module to configure new ldap user with old user
""",
'author': "IT IS AG",
'website': "http://www.itis-odoo.de",
'category': 'base',
'version': '1.0.55.0',
'depends': ['base','itis_hr_extend','hr_timesheet_sheet'],
'data': [
'views/ldap_view.xml',
'security/ir.model.access.csv',
'data/cron.xml',
],
'css': [],
'demo': [],
}

View File

@ -0,0 +1,16 @@
<openerp>
<data noupdate="1">
<!--scheduler to update to uopdate ldapuser with old user-->
<record id="itis_update_new_overtime" model="ir.cron">
<field name="name">ITIS Update LDAP User</field>
<field name="function">configure_ldap_user</field>
<field name="interval_type">days</field>
<field name="interval_number">1</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="(False)"/>
<field name="numbercall">-1</field>
<field name="model">ldap.record</field>
<!--<field name="nextcall" eval="(datetime.strptime('2016-12-31 21:00', '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M'))"/>-->
</record>
</data>
</openerp>

View File

@ -0,0 +1,80 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * itis_ldap_config
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-11-29 08:59+0000\n"
"PO-Revision-Date: 2017-11-29 10:07+0100\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.4\n"
#. module: itis_ldap_config
#: view:ldap.record:itis_ldap_config.ldap_record_tree
msgid "Current User name"
msgstr "aktueller Benutzer"
#. module: itis_ldap_config
#: view:ldap.record:itis_ldap_config.ldap_record_tree
msgid "Employee Name"
msgstr "Mitarbeiter"
#. module: itis_ldap_config
#: view:ldap.record:itis_ldap_config.ldap_record_tree
msgid "Employee No"
msgstr "Personal-Nr"
#. module: itis_ldap_config
#: code:addons/itis_ldap_config/models/hr_timesheet.py:18
#, python-format
msgid "Error!"
msgstr "Error!"
#. module: itis_ldap_config
#: field:hr.analytic.timesheet,for_ldap_modification:0
msgid "For Ldap Modification"
msgstr "For Ldap Modification"
#. module: itis_ldap_config
#: model:ir.ui.menu,name:itis_ldap_config.menu_ldap_record
msgid "LDAP Record"
msgstr "LDAP Record"
#. module: itis_ldap_config
#: model:ir.actions.act_window,name:itis_ldap_config.hr_ldap_record_action
#: view:ldap.record:itis_ldap_config.ldap_record_tree
msgid "Ldap Record"
msgstr "Ldap Record"
#. module: itis_ldap_config
#: view:ldap.record:itis_ldap_config.ldap_record_tree
msgid "Ldap User name"
msgstr "Ldap Benutzername"
#. module: itis_ldap_config
#: model:ir.model,name:itis_ldap_config.model_hr_analytic_timesheet
msgid "Timesheet Line"
msgstr "Zeiterfassungsposition"
#. module: itis_ldap_config
#: view:ldap.record:itis_ldap_config.ldap_record_tree
msgid "User Configured"
msgstr "Benutzer konfiguriert"
#. module: itis_ldap_config
#: model:ir.model,name:itis_ldap_config.model_res_users
msgid "Users"
msgstr "Benutzer"
#. module: itis_ldap_config
#: code:addons/itis_ldap_config/models/hr_timesheet.py:18
#, python-format
msgid "You cannot modify an entry in a confirmed timesheet."
msgstr "Sie können keinen Eintrag in einer bestätigten Zeiterfassung ändern"

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from . import hr_timesheet
from . import ldap_record
from . import res_users

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from openerp.osv import fields, osv
from openerp.tools.translate import _
class hr_timesheet_line(osv.osv):
_inherit = "hr.analytic.timesheet"
# Add a column for ldap modifications records
_columns = {
'for_ldap_modification': fields.boolean('For Ldap Modification'),
}
# def _check(self, cr, uid, ids):
# for att in self.browse(cr, uid, ids):
# # print"for ldap,sheet id----",att.for_ldap_modification,att.sheet_id
# if att.sheet_id and att.sheet_id.state not in ('draft', 'new') and not att.for_ldap_modification:#do not give a warning for ldap modify records
# raise osv.except_osv(_('Error!'), _('You cannot modify an entry in a confirmed timesheet.'))
# return True

View File

@ -0,0 +1,103 @@
# -*- coding: utf-8 -*-
from openerp import models, api, fields, _
import logging
logger = logging.getLogger(__name__)
class ldap_record(models.Model):
_name = 'ldap.record'
emp_name= fields.Char()
emp_no= fields.Char()
ldap_uname= fields.Char()
cur_uname=fields.Char()
user_configured=fields.Boolean(string="User Configured")
@api.one
def configure_ldap_user_subfunction(self,context):
ldap_record = self.env['ldap.record']
res_users = self.env['res.users']
if context and context.get('user_id'):
res_user_rec = res_users.browse(context.get('user_id'))
ldap_records_brw = ldap_record.search([('user_configured','=',False),('ldap_uname','=',res_user_rec.login)])
print"ldap_records_brw------",ldap_records_brw
self.ldap_data_exchange(ldap_records_brw)
@api.model
def configure_ldap_user(self):
#Add a logic to map and search LDAP user
logger.info("-----Ldap userconfigure cron---- ")
ldap_record = self.env['ldap.record']
ldap_records_brw = ldap_record.search([('user_configured','=',False)])
self.ldap_data_exchange(ldap_records_brw)
def ldap_data_exchange(self,ldap_records_brw):
res_users = self.env['res.users']
hr_employee = self.env['hr.employee']
for ldap_record_brw in ldap_records_brw:
old_user =False
new_user = res_users.search([('login','=',ldap_record_brw.ldap_uname)],limit=1)
# old_user = res_users.search([('login','=',ldap_record_brw.cur_uname)],limit=1)
related_emp =hr_employee.search([('identification_id','=',ldap_record_brw.emp_no)],limit=1)
if related_emp:
old_user = related_emp.user_id
logger.info("---Ldap In the cron------ " )
logger.info("---Ldap new user--main---- %s" %str(new_user))
logger.info("---Ldap old user---main--- %s" %str(old_user))
# print"old_user------",old_user.name
# print"related_emp------",related_emp.name
if new_user and old_user and related_emp:
# logger.info("---Ldap new user------ %s" %new_user.login)
logger.info("---Ldap old user------ %s" %old_user.login)
related_emp.write({'user_id':new_user.id}) #new user write to emp
#new user write to old time sheet
related_timesheet_records = self.env['hr_timesheet_sheet.sheet'].search([('employee_id','=',related_emp.id),('user_id','=',old_user.id)])
[i.write({'user_id':new_user.id}) for i in related_timesheet_records]
#new user write to old analytic timesheet (I use the query here as well as write function)
related_analytic_timesheet_records = self.env['hr.analytic.timesheet'].search([('user_id','=',old_user.id)])
# related_analytic_ids = related_analytic_timesheet_records.ids
# self._cr.execute("update hr_analytic_timesheet set for_ldap_modification=true where id in %s",(tuple(related_analytic_ids),))
# [i.with_context(for_ldap_records=True).write({'user_id':new_user.id}) for i in related_analytic_timesheet_records]
for i in related_analytic_timesheet_records:
if not i.sheet_id:
i.line_id.write({'user_id':new_user.id})
else:
sheet_id = i.sheet_id
i.line_id.write({'user_id':new_user.id})
self._cr.execute("update hr_analytic_timesheet set sheet_id=%s where id =%s",(sheet_id.id,i.id))
#new user write to the old leave requests
related_leave_requests = self.env['hr.holidays'].search([('user_id','=',old_user.id)]).ids
if related_leave_requests:
self._cr.execute('update hr_holidays set user_id=%s where id in %s',(new_user.id,tuple(related_leave_requests)))
# print"Leave requests-------",related_leave_requests
#new user to the old calendar events
related_calendar_events = self.env['calendar.event'].search([('user_id','=',old_user.id)]).ids
# self._cr.execute('update calendar_event set user_id=%s where id in %s',(new_user.id,tuple(related_calendar_events)))
# print"Calendar Events-------",related_calendar_events
for event_id in related_calendar_events:
if event_id:
self.env['calendar.event'].browse(event_id).write({'user_id':new_user.id})
#assign old user partner to new user and delete or deactivate new user partner
try:
new_user_partner = new_user.partner_id
new_user.write({'partner_id':old_user.partner_id.id})
new_user_partner.unlink()
logger.info("-- Related Partner record can not be link-----")
except:
#Todo Error handling
pass
# old user set to inactive
old_user.write({'active':False})
#write configuration is done for this ldap record
ldap_record_brw.write({'user_configured':True})
logger.info("---Ldap In the cron---successfull--- " )

View File

@ -0,0 +1,17 @@
from openerp import tools
from openerp.osv import fields, osv
from openerp import SUPERUSER_ID
from openerp.modules.registry import RegistryManager
class users(osv.osv):
_inherit = "res.users"
def _login(self, db, login, password):
user_id = super(users, self)._login(db, login, password)
# print"user_id-------",user_id
registry = RegistryManager.get(db)
with registry.cursor() as cr:
ldap_obj = registry.get('ldap.record')
context={'user_id':user_id}
# ldap_obj.configure_ldap_user_subfunction(cr,SUPERUSER_ID,user_id,context)
return user_id

View File

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_itis_ldap_record,access_ldap_record,model_ldap_record,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_itis_ldap_record access_ldap_record model_ldap_record 1 1 1 1

View File

@ -0,0 +1,29 @@
<openerp>
<data>
<record id="ldap_record_tree" model='ir.ui.view'>
<field name="name">ldap.record.tree</field>
<field name="model">ldap.record</field>
<field name="arch" type="xml">
<tree string="Ldap Record" editable="bottom">
<field name="emp_no" string="Employee No"/>
<field name="emp_name" string="Employee Name"/>
<field name="ldap_uname" string="Ldap User name"/>
<field name="cur_uname" string="Current User name"/>
<field name="user_configured" string="User Configured"/>
</tree>
</field>
</record>
<record id="hr_ldap_record_action" model="ir.actions.act_window">
<field name="name">Ldap Record</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ldap.record</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="LDAP Record" parent="hr.menu_hr_configuration" action="hr_ldap_record_action"
id="menu_ldap_record" groups='base.group_hr_payroll_manager,base.group_hr_manager,base.group_hr_user'/>
</data>
</openerp>

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
import hr_setting
import wizard

View File

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
{
'name': "ITIS Payroll Export",
'summary': """
ITIS Payroll Export
""",
'description': """
Module will export Payroll data to csv file
""",
'author': "ITIS AG",
'website': "http://www.itis.de",
'category': 'HR',
'version': '1.0.55.0',
# any module necessary for this one to work correctly
'depends': ['itis_hr_leave_extend', 'itis_hr_extend'],
# always loaded
'data': [
'security/ir.model.access.csv',
'hr_setting_view.xml',
'wizard/payroll_export.xml',
],

View File

@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# 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 <https://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields, api, _
class hr_config(models.TransientModel):
_inherit = "hr.config.settings"
sick_account_id = fields.Many2one("account.analytic.account", "Sick Account")
@api.multi
def set_sick_account_id(self):
self.env.user.company_id.write({
"sick_account_id": self.sick_account_id.id,
})
return True
@api.model
def default_get(self, fields):
sick_id = self.env.user.company_id.sick_account_id.id or False
res = super(hr_config, self).default_get(fields)
res.update({
"sick_account_id": sick_id,
})
return res
class res_company(models.Model):
_inherit = "res.company"
sick_account_id = fields.Many2one("account.analytic.account", "Sick Account")

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_hr_configuration_inh" model="ir.ui.view">
<field name="name">view.hr.configuration.inh</field>
<field name="model">hr.config.settings</field>
<field name="inherit_id" ref="hr.view_human_resources_configuration"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='hr_ot_leave']/div" position="inside">
<div>
<label for="sick_account_id"
class="oe_inline" />
<field name="sick_account_id"
domain="[('type', 'in', ['normal', 'contract']), ('state', '!=', 'close'), ('use_timesheets', '=', 1)]"
options="{'no_open': True, 'no_create': True, 'no_create_edit':True}"
class="oe_inline" />
</div>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,100 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * itis_payroll_export
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-12-11 13:57+0000\n"
"PO-Revision-Date: 2016-12-11 18:57+0100\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.4\n"
#. module: itis_payroll_export
#: view:payroll.export:itis_payroll_export.payroll_export_form_view
msgid "Cancel"
msgstr "Abbrechen"
#. module: itis_payroll_export
#: view:payroll.export:itis_payroll_export.payroll_export_form_view
msgid "Click 'Export' button to export payroll csv"
msgstr "Klicken Sie auf Exportieren um die Lohndaten zu exportieren."
#. module: itis_payroll_export
#: model:ir.model,name:itis_payroll_export.model_res_company
msgid "Companies"
msgstr "Unternehmen"
#. module: itis_payroll_export
#: field:payroll.export,create_uid:0
msgid "Created by"
msgstr "Created by"
#. module: itis_payroll_export
#: field:payroll.export,create_date:0
msgid "Created on"
msgstr "Created on"
#. module: itis_payroll_export
#: view:payroll.export:itis_payroll_export.payroll_export_form_view
msgid "Export"
msgstr "Exportieren"
#. module: itis_payroll_export
#: view:payroll.export:itis_payroll_export.payroll_export_form_view
msgid "Export file:"
msgstr "Export Datei:"
#. module: itis_payroll_export
#: code:addons/itis_payroll_export/wizard/payroll_export.py:101
#, python-format
msgid "Exported Payroll"
msgstr "Exportierter Lohnstapel"
#. module: itis_payroll_export
#: field:payroll.export,file_name:0
msgid "File"
msgstr "Datei"
#. module: itis_payroll_export
#: field:payroll.export,id:0
msgid "ID"
msgstr "ID"
#. module: itis_payroll_export
#: field:payroll.export,write_uid:0
msgid "Last Updated by"
msgstr "Last Updated by"
#. module: itis_payroll_export
#: field:payroll.export,write_date:0
msgid "Last Updated on"
msgstr "Last Updated on"
#. module: itis_payroll_export
#: field:payroll.export,name:0
msgid "Payroll CSV"
msgstr "Lohstapel CSV"
#. module: itis_payroll_export
#: model:ir.actions.act_window,name:itis_payroll_export.payroll_export_action
#: model:ir.ui.menu,name:itis_payroll_export.menu_payroll_export
msgid "Payroll Export"
msgstr "Lohnstapel Export"
#. module: itis_payroll_export
#: field:hr.config.settings,sick_account_id:0
#: field:res.company,sick_account_id:0
msgid "Sick Account"
msgstr "Kostenstelle Krankheit"
#. module: itis_payroll_export
#: view:payroll.export:itis_payroll_export.payroll_export_form_view
msgid "or"
msgstr "oder"

Some files were not shown because too many files have changed in this diff Show More