Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

8.0 new addons: sale_quotation_sourcing #41

Merged
merged 44 commits into from Oct 8, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
f1f2784
scaffold new addon
gurneyalex Sep 10, 2014
06dbb8f
partial implementation
gurneyalex Sep 12, 2014
b479204
manage sourcing on the procurements
gurneyalex Sep 12, 2014
8f4061e
added pot file
gurneyalex Sep 12, 2014
bd6ac9d
split sale_order.py in smaller bits, some flake8 cleanup
gurneyalex Sep 12, 2014
272568e
rename models/ to model/
gurneyalex Sep 12, 2014
7dfd11b
use @api.model decorator where needed
gurneyalex Sep 12, 2014
5757bd4
remove unused demo.xml file
gurneyalex Sep 12, 2014
9e1f5bf
updated travis config
gurneyalex Sep 12, 2014
9209fb2
fix bad use of api.one
gurneyalex Sep 12, 2014
b795c12
restore .travis.yml
gurneyalex Sep 12, 2014
a5dd77a
module name
lepistone Sep 15, 2014
ef2a1cc
do not copy sourced_by
lepistone Sep 15, 2014
277f3c1
source po lines for the same product
lepistone Sep 16, 2014
b07e4ef
enable "Choose MTO, drop shipping... on SO lines"
lepistone Sep 18, 2014
cfbbf7a
find a move rule, not a buy rule
lepistone Sep 19, 2014
3054c07
use nose assertions
lepistone Sep 23, 2014
ca1a544
improved procurement / purchase logic
lepistone Sep 23, 2014
85c0c48
rename tests -> test
lepistone Sep 24, 2014
8268d02
new tests for standard case
lepistone Sep 24, 2014
eb99d26
complete standard mto case standard test
lepistone Sep 25, 2014
ed1d156
make manual test case like the automatic one
lepistone Sep 25, 2014
992c868
say my name
lepistone Sep 25, 2014
a3bdd74
cleanup
lepistone Sep 25, 2014
47e3bfd
fix assertion
lepistone Sep 25, 2014
f129107
more assertions about procurements and pickings
lepistone Sep 25, 2014
4fcb7f6
choose different partners to avoid PO autogrouping
lepistone Sep 25, 2014
dbaea1e
more doc
lepistone Sep 25, 2014
0e995b6
do not depend on nose: it is a test-only dependency
lepistone Sep 25, 2014
d076a45
improve doc
lepistone Sep 29, 2014
2db51a5
yaml: new api
lepistone Sep 29, 2014
623683d
mention the nose test dependency
lepistone Sep 29, 2014
4e734b7
split the tests to avoid interferences
gurneyalex Oct 3, 2014
bfe507e
Add better name_get in po line + search method
jgrandguillaume Oct 7, 2014
1ddf4bf
Remove the selection of PO in the sourcing wizard
jgrandguillaume Oct 7, 2014
84269b7
test: specify product name
lepistone Oct 7, 2014
38fb908
remove useless data from test
lepistone Oct 7, 2014
c82a512
adapt existing tests to the new style
lepistone Oct 7, 2014
0963bc7
test the standard dropshipping case
lepistone Oct 7, 2014
590a606
lint
lepistone Oct 8, 2014
413d5cf
check for consistency between procurement and PO
lepistone Oct 8, 2014
f9d5e61
test and document the drop shipping case
lepistone Oct 8, 2014
4553508
remove stale po_id
lepistone Oct 8, 2014
9adf01c
do not allow to create po, po_lines when sourcing
lepistone Oct 8, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 4 additions & 3 deletions .travis.yml
Expand Up @@ -4,8 +4,10 @@ python:
- "2.7"

env:
- VERSION="8.0" ODOO_REPO="odoo/odoo"
- VERSION="8.0" ODOO_REPO="OCA/OCB"
- VERSION="8.0" ODOO_REPO="odoo/odoo" EXCLUDE="sale_quotation_sourcing"
- VERSION="8.0" ODOO_REPO="OCA/OCB" EXCLUDE="sale_quotation_sourcing"
- VERSION="8.0" ODOO_REPO="odoo/odoo" INCLUDE="sale_quotation_sourcing"
- VERSION="8.0" ODOO_REPO="OCA/OCB" INCLUDE="sale_quotation_sourcing"

virtualenv:
system_site_packages: true
Expand All @@ -20,7 +22,6 @@ install:
- travis_install_nightly

script:
- travis_run_flake8
- travis_run_tests

after_success:
Expand Down
6 changes: 4 additions & 2 deletions sale_exceptions/sale.py
Expand Up @@ -122,8 +122,9 @@ def _popup_exceptions(self):
}
return action

@api.one
@api.multi
def action_button_confirm(self):
self.ensure_one()
if self.detect_exceptions():
return self._popup_exceptions()
else:
Expand Down Expand Up @@ -184,9 +185,10 @@ def _rule_eval(self, rule, obj_name, rec):
'rule:\n %s \n(%s)') % (rule.name, e))
return space.get('failed', False)

@api.one
@api.multi
def _detect_exceptions(self, order_exceptions,
line_exceptions):
self.ensure_one()
exception_ids = []
for rule in order_exceptions:
if self._rule_eval(rule, 'order', self):
Expand Down
21 changes: 21 additions & 0 deletions sale_quotation_sourcing/__init__.py
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
#
# Author: Alexandre Fayolle, Leonardo Pistone
# Copyright 2014 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
from . import model
from . import wizard
74 changes: 74 additions & 0 deletions sale_quotation_sourcing/__openerp__.py
@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
#
# Author: Alexandre Fayolle, Leonardo Pistone
# Copyright 2014 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
{
'name': "Sale Quotation Sourcing",

'summary': "manual sourcing of sale quotations",
'description': """
This module implements manual sourcing of sale order lines from purchase
order lines.

Instead of having the confirmation of a SO generate procurements which in
turn may generate a PO, we invert the process: in order to generate a quote
for a customer, we ask quotes to different suppliers.

Once the sale quotation is accepted by the customer and the user confirms
it, a wizard is presented to choose which PO to use to source the SO lines.

The process should mimic closely the way that Odoo handles a MTO, buy
order. The only difference is that the PO is chosen manually and not
automatically generated. The end result should be the same.

To show that, two test cases are provided that show the standard process
and the manually sourced one.

The drop shipping case is handled as well, with a warning to check if the
destination locations of the procurement and the sourced PO are
consistent. Since the stock_dropshipping module contains little more than
preconfigured Routes, Rules, and Picking Types, we do not depend
on it but we are fully compatible. The Routes and Rules are recreated in
the tests in order to avoid requiring stock_dropshipping in production.

Note: the package nose is required to run the tests. It is not noted in the
external dependencies since it is not required in production.

""",

'author': "Camptocamp",
'website': "http://www.camptocamp.com",

'category': 'Sales',
'version': '0.1',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add nose in python deps or a comment in the description

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nbessi done


'depends': ['sale_stock', 'purchase'],
'data': ['views/sale_order_sourcing.xml',
'views/sale_order.xml',
'security/group.xml',
],
'test': [
'test/setup_user.yml',
'test/setup_product.yml',
'test/setup_dropshipping.xml',
'test/test_standard_mto_sourcing.yml',
'test/test_standard_dropshipping.yml',
'test/test_manual_mto_sourcing.yml',
'test/test_manual_sourcing_dropshipping.yml',
],
}
135 changes: 135 additions & 0 deletions sale_quotation_sourcing/i18n/sale_quotation_sourcing.pot
@@ -0,0 +1,135 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_quotation_sourcing
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0rc1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-09-12 12:08+0000\n"
"PO-Revision-Date: 2014-09-12 12:08+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: sale_quotation_sourcing
#: view:sale.order.sourcing:sale_quotation_sourcing.sale_order_sourcing_wizard
msgid "Cancel"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.line.sourcing,create_uid:0
#: field:sale.order.sourcing,create_uid:0
msgid "Created by"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.line.sourcing,create_date:0
#: field:sale.order.sourcing,create_date:0
msgid "Created on"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.line.sourcing,id:0
#: field:sale.order.sourcing,id:0
msgid "ID"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.line.sourcing,write_uid:0
#: field:sale.order.sourcing,write_uid:0
msgid "Last Updated by"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.line.sourcing,write_date:0
#: field:sale.order.sourcing,write_date:0
msgid "Last Updated on"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.sourcing,line_ids:0
msgid "Lines"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.line,manually_sourced:0
msgid "Manually Sourced"
msgstr ""

#. module: sale_quotation_sourcing
#: code:addons/sale_quotation_sourcing/models/sale_order.py:98
#, python-format
msgid "Manually sourced"
msgstr ""

#. module: sale_quotation_sourcing
#: model:ir.model,name:sale_quotation_sourcing.model_procurement_order
msgid "Procurement"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.line.sourcing,po_id:0
msgid "Purchase Order"
msgstr ""

#. module: sale_quotation_sourcing
#: view:sale.order.sourcing:sale_quotation_sourcing.sale_order_sourcing_wizard
msgid "Record sourcing"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.sourcing,sale_id:0
msgid "Sale Order"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.line.sourcing,so_line_id:0
msgid "Sale Order Line"
msgstr ""

#. module: sale_quotation_sourcing
#: view:sale.order.sourcing:sale_quotation_sourcing.sale_order_sourcing_wizard
msgid "Sale order line sourcing"
msgstr ""

#. module: sale_quotation_sourcing
#: model:ir.model,name:sale_quotation_sourcing.model_sale_order
msgid "Sales Order"
msgstr ""

#. module: sale_quotation_sourcing
#: model:ir.model,name:sale_quotation_sourcing.model_sale_order_line
msgid "Sales Order Line"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.line.sourcing,po_line_id:0
msgid "Sourced By"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.line,sourced_by:0
msgid "Sourced by"
msgstr ""

#. module: sale_quotation_sourcing
#: field:sale.order.line.sourcing,wizard_id:0
msgid "Wizard"
msgstr ""

#. module: sale_quotation_sourcing
#: code:addons/sale_quotation_sourcing/models/sale_order.py:76
#, python-format
msgid "configuration problem"
msgstr ""

#. module: sale_quotation_sourcing
#: code:addons/sale_quotation_sourcing/models/sale_order.py:77
#, python-format
msgid "no buy rule configured for warehouse %d"
msgstr ""

23 changes: 23 additions & 0 deletions sale_quotation_sourcing/model/__init__.py
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
#
# Author: Alexandre Fayolle
# Copyright 2014 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#

from . import sale_order
from . import procurement
from . import purchase
68 changes: 68 additions & 0 deletions sale_quotation_sourcing/model/procurement.py
@@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
#
# Author: Alexandre Fayolle, Leonardo Pistone
# Copyright 2014 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
from openerp import models, api, _

from openerp.exceptions import Warning


class ProcurementOrder(models.Model):
_inherit = 'procurement.order'

@api.multi
def make_po(self):
"""
link the procurement to the PO line sourcing the SO line
if the SO line is manually sourced. Otherwise, use the normal
implementation.
"""
res = {}
to_propagate = self.browse()
for procurement in self:

sale_line = (
procurement.sale_line_id or
procurement.move_dest_id.procurement_id.sale_line_id or
False
)

if sale_line and sale_line.manually_sourced:
po_line = sale_line.sourced_by

if po_line.order_id.location_id != procurement.location_id:
raise Warning(_(
'The manually sourced Purchase Order has Destination '
'location {}, while the Procurement was generated '
'with destination {}. To solve the problem, please '
'source a Sale Order Line with a Purchase Order '
'consistent with the active Route. For example, if '
'the active route is Drop Shipping, the chosen PO '
'should have destination location Customers.'.format(
po_line.order_id.location_id.name,
procurement.location_id.name
)
))

res[procurement.id] = po_line.id
procurement.purchase_line_id = po_line
procurement.message_post(body=_('Manually sourced'))
else:
to_propagate |= procurement
res.update(super(ProcurementOrder, to_propagate).make_po())
return res