Merge PR #570 into 12.0

Signed-off-by rousseldenis
This commit is contained in:
OCA-git-bot
2019-09-30 11:51:45 +00:00
15 changed files with 926 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
===========================
Stock Account Internal Move
===========================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
:target: https://odoo-community.org/page/development-status
:alt: Production/Stable
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github
:target: https://github.com/OCA/stock-logistics-warehouse/tree/12.0/stock_account_internal_move
:alt: OCA/stock-logistics-warehouse
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-12-0/stock-logistics-warehouse-12-0-stock_account_internal_move
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/153/12.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
This module will allow you to configure Odoo to create journal entries when
transferring goods between 2 internal locations.
Use cases
=========
* You have an internal location "Manufacture Stock" with all the goods that will
be used for manufacturing. Goods in this location are considered "Work in
Progress". On the "Manufacture Stock" location, the type is "Internal" and you
should force the accounting entries to set the "Work in Progress" account.
* You have some specific locations in your warehouse where you want a separate
account with the value of all the goods at that location.
**Table of contents**
.. contents::
:local:
Configuration
=============
* Create and edit your location
* Check the box "Force accounting entries?". The Accounting Information should appear.
* Set the account related to the location.
Usage
=====
* Process your internal tranfers
* Check the journal entry created and the amount
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-warehouse/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_account_internal_move%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Camptocamp SA
Contributors
~~~~~~~~~~~~
* Artem Kostyuk <a.kostyuk@mobilunity.com>
* Maxime Chambreuil <mchambreuil@opensourceintegrators.com>
* Kitti Upariphutthiphong <kittiu@ecosoft.co.th>
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-arkostyuk| image:: https://github.com/arkostyuk.png?size=40px
:target: https://github.com/arkostyuk
:alt: arkostyuk
.. |maintainer-max3903| image:: https://github.com/max3903.png?size=40px
:target: https://github.com/max3903
:alt: max3903
Current `maintainers <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-arkostyuk| |maintainer-max3903|
This module is part of the `OCA/stock-logistics-warehouse <https://github.com/OCA/stock-logistics-warehouse/tree/12.0/stock_account_internal_move>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

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

View File

@@ -0,0 +1,24 @@
# Copyright (C) 2018 by Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl-3.0).
{
'name': """Stock Account Internal Move""",
'summary': """Allows tracking moves between internal locations"""
""" via accounts.""",
'category': "Warehouse Management",
'version': "12.0.1.0.0",
'author': "Camptocamp SA,"
" Odoo Community Association (OCA)",
'website': "https://github.com/OCA/stock-logistics-warehouse",
'license': "AGPL-3",
'depends': [
'stock_account',
],
'data': [
'views/stock_location.xml',
],
'development_status': 'Production/Stable',
'maintainers': [
'arkostyuk',
'max3903',
],
}

View File

@@ -0,0 +1,42 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_account_internal_move
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: stock_account_internal_move
#: model:ir.model.fields,field_description:stock_account_internal_move.field_stock_location_force_accounting_entries
msgid "Force accounting entries?"
msgstr ""
#. module: stock_account_internal_move
#: model:ir.model,name:stock_account_internal_move.model_stock_location
msgid "Inventory Locations"
msgstr ""
#. module: stock_account_internal_move
#: model:ir.model,name:stock_account_internal_move.model_stock_move
msgid "Stock Move"
msgstr ""
#. module: stock_account_internal_move
#: code:addons/stock_account_internal_move/models/stock_location.py:21
#, python-format
msgid "You cannot force accounting entries on a non-internal locations."
msgstr ""
#. module: stock_account_internal_move
#: code:addons/stock_account_internal_move/models/stock_location.py:37
#, python-format
msgid "You must provide a valuation in/out accounts in order to force accounting entries."
msgstr ""

View File

@@ -0,0 +1,2 @@
from . import stock_location
from . import stock_move

View File

@@ -0,0 +1,45 @@
# Copyright (C) 2018 by Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class StockLocation(models.Model):
_inherit = 'stock.location'
force_accounting_entries = fields.Boolean(
string='Force accounting entries?',
)
@api.constrains(
'usage',
'force_accounting_entries',
)
def _check_force_accounting_entries_internal_only(self):
for loc in self:
if loc.usage != 'internal' and loc.force_accounting_entries:
raise ValidationError(_(
'You cannot force accounting entries'
' on a non-internal location.'))
@api.constrains(
'force_accounting_entries',
'valuation_in_account_id',
'valuation_out_account_id',
)
def _check_internal_valuation_accounts_present(self):
"""Ensure that every location requiring entries has valuation accs."""
for loc in self:
if loc.usage != 'internal' or not loc.force_accounting_entries:
continue # this one doesn't require accounts, it's fine
if not loc.valuation_in_account_id \
or not loc.valuation_out_account_id:
raise ValidationError(_(
'You must provide a valuation in/out account'
' in order to force accounting entries.'))
@api.onchange('usage')
def _onchange_usage(self):
for location in self:
if location.usage != 'internal':
location.update({'force_accounting_entries': False})

View File

@@ -0,0 +1,107 @@
# Copyright (C) 2018 by Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models
from odoo.tools import float_round
class StockMove(models.Model):
_inherit = 'stock.move'
# @override
@api.multi
def _action_done(self):
"""Call _account_entry_move for internal moves as well."""
res = super()._action_done()
for move in res:
# first of all, define if we need to even valuate something
if move.product_id.valuation != 'real_time':
continue
# we're customizing behavior on moves between internal locations
# only, thus ensuring that we don't clash w/ account moves
# created in `stock_account`
if not move._is_internal():
continue
move._account_entry_move()
return res
# @override
@api.multi
def _run_valuation(self, quantity=None):
# Extend `_run_valuation` to make it work on internal moves.
self.ensure_one()
res = super()._run_valuation(quantity)
if self._is_internal() and not self.value:
# TODO: recheck if this part respects product valuation method
self.value = float_round(
value=self.product_id.standard_price * self.quantity_done,
precision_rounding=self.company_id.currency_id.rounding,
)
return res
# @override
@api.multi
def _account_entry_move(self):
self.ensure_one()
res = super()._account_entry_move()
if res is not None and not res:
# `super()` tends to `return False` as an indicator that no
# valuation should happen in this case
return res
# treated by `super()` as a self w/ negative qty due to this hunk:
# quantity = self.product_qty or context.get('forced_quantity')
# quantity = quantity if self._is_in() else -quantity
# so, self qty is flipped twice and thus preserved
self = self.with_context(forced_quantity=-self.product_qty)
location_from = self.location_id
location_to = self.location_dest_id
# get valuation accounts for product
if self._is_internal():
product_valuation_accounts \
= self.product_id.product_tmpl_id.get_product_accounts()
stock_valuation = product_valuation_accounts.get('stock_valuation')
stock_journal = product_valuation_accounts.get('stock_journal')
if location_from.force_accounting_entries \
and location_to.force_accounting_entries:
self._create_account_move_line(
location_from.valuation_out_account_id.id,
location_to.valuation_in_account_id.id,
stock_journal.id)
elif location_from.force_accounting_entries:
self._create_account_move_line(
location_from.valuation_out_account_id.id,
stock_valuation.id,
stock_journal.id)
elif location_to.force_accounting_entries:
self._create_account_move_line(
stock_valuation.id,
location_to.valuation_in_account_id.id,
stock_journal.id)
return res
@api.multi
def _is_internal(self):
self.ensure_one()
return self.location_id.usage == 'internal' \
and self.location_dest_id.usage == 'internal'
@api.multi
def _get_accounting_data_for_valuation(self):
self.ensure_one()
journal_id, acc_src, acc_dest, acc_valuation \
= super()._get_accounting_data_for_valuation()
# intercept account valuation, use account specified on internal
# location as a local valuation
if self._is_in() and self.location_dest_id.force_accounting_entries:
# (acc_src if not dest.usage == 'customer') => acc_valuation
acc_valuation \
= self.location_dest_id.valuation_in_account_id.id
if self._is_out() and self.location_id.force_accounting_entries:
# acc_valuation => (acc_dest if not dest.usage == 'supplier')
acc_valuation \
= self.location_id.valuation_out_account_id.id
return journal_id, acc_src, acc_dest, acc_valuation

View File

@@ -0,0 +1,3 @@
* Create and edit your location
* Check the box "Force accounting entries?". The Accounting Information should appear.
* Set the account related to the location.

View File

@@ -0,0 +1,3 @@
* Artem Kostyuk <a.kostyuk@mobilunity.com>
* Maxime Chambreuil <mchambreuil@opensourceintegrators.com>
* Kitti Upariphutthiphong <kittiu@ecosoft.co.th>

View File

@@ -0,0 +1,12 @@
This module will allow you to configure Odoo to create journal entries when
transferring goods between 2 internal locations.
Use cases
=========
* You have an internal location "Manufacture Stock" with all the goods that will
be used for manufacturing. Goods in this location are considered "Work in
Progress". On the "Manufacture Stock" location, the type is "Internal" and you
should force the accounting entries to set the "Work in Progress" account.
* You have some specific locations in your warehouse where you want a separate
account with the value of all the goods at that location.

View File

@@ -0,0 +1,2 @@
* Process your internal tranfers
* Check the journal entry created and the amount

View File

@@ -0,0 +1,439 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>Stock Account Internal Move</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="stock-account-internal-move">
<h1 class="title">Stock Account Internal Move</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/tree/12.0/stock_account_internal_move"><img alt="OCA/stock-logistics-warehouse" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/stock-logistics-warehouse-12-0/stock-logistics-warehouse-12-0-stock_account_internal_move"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/153/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This module will allow you to configure Odoo to create journal entries when
transferring goods between 2 internal locations.</p>
<div class="section" id="use-cases">
<h1>Use cases</h1>
<ul class="simple">
<li>You have an internal location “Manufacture Stock” with all the goods that will
be used for manufacturing. Goods in this location are considered “Work in
Progress”. On the “Manufacture Stock” location, the type is “Internal” and you
should force the accounting entries to set the “Work in Progress” account.</li>
<li>You have some specific locations in your warehouse where you want a separate
account with the value of all the goods at that location.</li>
</ul>
<p><strong>Table of contents</strong></p>
</div>
<div class="section" id="configuration">
<h1>Configuration</h1>
<ul class="simple">
<li>Create and edit your location</li>
<li>Check the box “Force accounting entries?”. The Accounting Information should appear.</li>
<li>Set the account related to the location.</li>
</ul>
</div>
<div class="section" id="usage">
<h1>Usage</h1>
<ul class="simple">
<li>Process your internal tranfers</li>
<li>Check the journal entry created and the amount</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1>Bug Tracker</h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_account_internal_move%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1>Credits</h1>
<div class="section" id="authors">
<h2>Authors</h2>
<ul class="simple">
<li>Camptocamp SA</li>
</ul>
</div>
<div class="section" id="contributors">
<h2>Contributors</h2>
<ul class="simple">
<li>Artem Kostyuk &lt;<a class="reference external" href="mailto:a.kostyuk&#64;mobilunity.com">a.kostyuk&#64;mobilunity.com</a>&gt;</li>
<li>Maxime Chambreuil &lt;<a class="reference external" href="mailto:mchambreuil&#64;opensourceintegrators.com">mchambreuil&#64;opensourceintegrators.com</a>&gt;</li>
<li>Kitti Upariphutthiphong &lt;<a class="reference external" href="mailto:kittiu&#64;ecosoft.co.th">kittiu&#64;ecosoft.co.th</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2>Maintainers</h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainers</a>:</p>
<p><a class="reference external" href="https://github.com/arkostyuk"><img alt="arkostyuk" src="https://github.com/arkostyuk.png?size=40px" /></a> <a class="reference external" href="https://github.com/max3903"><img alt="max3903" src="https://github.com/max3903.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/tree/12.0/stock_account_internal_move">OCA/stock-logistics-warehouse</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View File

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

View File

@@ -0,0 +1,114 @@
from odoo.exceptions import ValidationError
from odoo.tests import common
from odoo.tools import mute_logger
class StockMoveConfirmationCase(common.SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
# we need to emulate a move from one internal location to another one
cls.product = cls.env['product.product'].create({
'name': 'Whatever',
'type': 'product',
'uom_id': cls.env.ref('uom.product_uom_kgm').id,
'uom_po_id': cls.env.ref('uom.product_uom_kgm').id,
'standard_price': 100.,
'valuation': 'real_time',
})
cls.location_from = cls.env.ref('stock.location_gate_a')
cls.location_to = cls.env.ref('stock.location_gate_b')
cls.location_from.usage = cls.location_to.usage = 'internal'
account_type_revenue_id = cls.env.ref(
'account.data_account_type_revenue').id
cls.account_from_in = cls.env['account.account'].create({
'name': 'From Location valuation account',
'code': 'fr0m10c4t10n-1n',
'user_type_id': account_type_revenue_id,
})
cls.account_to_in = cls.env['account.account'].create({
'name': 'To Location valuation account',
'code': 't010c4t10n-1n',
'user_type_id': account_type_revenue_id,
})
cls.account_from_out = cls.env['account.account'].create({
'name': 'From Location valuation account',
'code': 'fr0m10c4t10n-0u7',
'user_type_id': account_type_revenue_id,
})
cls.account_to_out = cls.env['account.account'].create({
'name': 'To Location valuation account',
'code': 't010c4t10n-0u7',
'user_type_id': account_type_revenue_id,
})
cls.location_from.write({
'force_accounting_entries': True,
'valuation_in_account_id': cls.account_from_in.id,
'valuation_out_account_id': cls.account_from_out.id,
})
cls.location_to.write({
'force_accounting_entries': True,
'valuation_in_account_id': cls.account_to_in.id,
'valuation_out_account_id': cls.account_to_out.id,
})
cls.fake_stock_journal = cls.env['account.journal'].create({
'name': 'Stock journal (that\'s **not really true)',
'code': '7h47\'5-n07-|?3411y-7|?u3',
'type': 'general',
})
def _create_move(self):
"""Create a dummy move from Gate A to Gate B."""
res = self.env['stock.move'].create({
'location_id': self.location_from.id,
'name': self.product.name,
'product_id': self.product.id,
'product_uom': self.product.uom_id.id,
'location_dest_id': self.location_to.id,
'move_line_ids': [
(0, 0, {
'product_id': self.product.id,
'qty_done': 5,
'location_id': self.location_from.id,
'location_dest_id': self.location_to.id,
'product_uom_id': self.product.uom_id.id,
}),
],
'picking_type_id': self.env.ref('stock.picking_type_internal').id,
})
# FIXME: refuses to play well w/ moves w/o picking_id
# res._assign_picking(self.env.ref('stock.picking_type_internal'))
res._assign_picking()
return res
def test_00_regular_move(self):
"""Ensure that we didn't broke anything completely.
Regular case, customization shouldn't have any effect on it.
"""
# ensure that we're running in a regular setup
self.location_from.force_accounting_entries = False
self.location_to.force_accounting_entries = False
# simple as that - we're just ensuring that we're allowed to do it.
self._create_move()
@mute_logger('odoo.sql_db')
def test_10_constraint(self):
"""Test that it's impossible to force entries w/o an account."""
with self.assertRaises(ValidationError):
self.location_from.write({
'force_accounting_entries': True,
'valuation_in_account_id': False,
})
def test_50_create_account_move_line(self):
move = self._create_move()
move._action_done()
# perform a manual evaluation of teh fresh move
# we don't really care about those numbers
move._create_account_move_line(
self.location_from.valuation_out_account_id.id,
self.location_to.valuation_in_account_id.id,
self.fake_stock_journal.id)

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_location_form" model="ir.ui.view">
<field name="name">stock.location.form</field>
<field name="model">stock.location</field>
<field name="inherit_id" ref="stock.view_location_form"/>
<field name="arch" type="xml">
<xpath expr="//group[field[@name='valuation_in_account_id']]" position="attributes">
<attribute name="attrs">
{'invisible': [('usage', 'not in', ('internal', 'inventory', 'production'))]}
</attribute>
</xpath>
<field name="valuation_in_account_id" position="before">
<field name="force_accounting_entries"
attrs="{'invisible': [('usage', '!=', 'internal')]}"/>
</field>
</field>
</record>
</odoo>