forked from OCA/stock-logistics-workflow
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'release/9.0/stock_picking_rate' of https://github.com/l…
…aslabs/stock-logistics-workflow into feature/9.0/LABS-187-migrate-connectoreasypost-to-oca
- Loading branch information
Showing
17 changed files
with
758 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg | ||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html | ||
:alt: License: AGPL-3 | ||
|
||
================== | ||
Stock Picking Rate | ||
================== | ||
|
||
This module adds the concept of delivery rate quotes & purchasing | ||
on Stock Pickings | ||
|
||
This is meant to be combined with an external connector with a carrier | ||
supplier in order to bring in rate quotes, although they can be created & | ||
edited manually if your workflow calls for it. | ||
|
||
Usage | ||
===== | ||
|
||
Dispatch rates can be added in Stock Picking | ||
|
||
Purchase Rate | ||
------------- | ||
|
||
The Purchase Rate wizard can be accessed by clicking the green check next | ||
to the rate quote in a ``stock.picking``. | ||
|
||
Completing this wizard will create ``purchase.order`` for your rate. | ||
If using a connector, this is the point in which a shipment purchase would | ||
be triggered. | ||
|
||
|
||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas | ||
:alt: Try me on Runbot | ||
:target: https://runbot.odoo-community.org/runbot/154/9.0 | ||
|
||
Known issues / Roadmap | ||
====================== | ||
|
||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues | ||
`<https://github.com/OCA/stock-logistics-workflow/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. | ||
|
||
|
||
Credits | ||
======= | ||
|
||
Images | ||
------ | ||
|
||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. | ||
|
||
Contributors | ||
------------ | ||
|
||
* Dave Lasley <dave@laslabs.com> | ||
|
||
|
||
Maintainer | ||
---------- | ||
|
||
.. image:: https://odoo-community.org/logo.png | ||
:alt: Odoo Community Association | ||
:target: https://odoo-community.org | ||
|
||
This module is maintained by the OCA. | ||
|
||
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. | ||
|
||
To contribute to this module, please visit https://odoo-community.org. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 LasLabs Inc. | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from . import models | ||
from . import wizards |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 LasLabs Inc. | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
{ | ||
"name": "Stock Picking Rate", | ||
"summary": "Adds a concept of rate quotes for stock pickings", | ||
"version": "9.0.1.0.0", | ||
"category": "Inventory, Logistics, Warehousing", | ||
"website": "https://laslabs.com/", | ||
"author": "LasLabs, Odoo Community Association (OCA)", | ||
"license": "AGPL-3", | ||
"application": False, | ||
"installable": True, | ||
"depends": [ | ||
"stock", | ||
"delivery", | ||
'purchase', | ||
], | ||
"data": [ | ||
"security/ir.model.access.csv", | ||
"views/stock_picking_view.xml", | ||
"views/stock_picking_dispatch_rate_view.xml", | ||
'wizards/stock_picking_dispatch_rate_purchase_view.xml', | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 LasLabs Inc. | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from . import stock_picking | ||
from . import stock_picking_dispatch_rate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 LasLabs Inc. | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from openerp import models, fields | ||
|
||
|
||
class StockPicking(models.Model): | ||
_inherit = 'stock.picking' | ||
|
||
dispatch_rate_ids = fields.One2many( | ||
string='Dispatch Rates', | ||
comodel_name='stock.picking.dispatch.rate', | ||
inverse_name='picking_id', | ||
) |
117 changes: 117 additions & 0 deletions
117
stock_picking_rate/models/stock_picking_dispatch_rate.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 LasLabs Inc. | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from openerp import models, fields, api | ||
import openerp.addons.decimal_precision as dp | ||
|
||
|
||
class StockPickingDispatchRate(models.Model): | ||
_name = 'stock.picking.dispatch.rate' | ||
_description = 'Stock Picking Dispatch Rate' | ||
|
||
picking_id = fields.Many2one( | ||
string='Stock Picking', | ||
comodel_name='stock.picking', | ||
required=True, | ||
) | ||
service_id = fields.Many2one( | ||
string='Carrier Service', | ||
comodel_name='delivery.carrier', | ||
required=True, | ||
) | ||
date_generated = fields.Datetime( | ||
required=True, | ||
default=lambda s: fields.Datetime.now(), | ||
) | ||
date_purchased = fields.Datetime( | ||
store=True, | ||
compute='_compute_date_purchased', | ||
) | ||
rate_currency_id = fields.Many2one( | ||
string='Rate Currency', | ||
comodel_name='res.currency', | ||
required=True, | ||
) | ||
rate = fields.Float( | ||
digits=dp.get_precision('Product Price'), | ||
required=True, | ||
) | ||
retail_rate = fields.Float( | ||
digits=dp.get_precision('Product Price'), | ||
) | ||
retail_rate_currency_id = fields.Many2one( | ||
string='Retail Rate Currency', | ||
comodel_name='res.currency', | ||
) | ||
list_rate = fields.Float( | ||
digits=dp.get_precision('Product Price'), | ||
) | ||
list_rate_currency_id = fields.Many2one( | ||
string='List Rate Currency', | ||
comodel_name='res.currency', | ||
) | ||
delivery_days = fields.Integer() | ||
date_delivery = fields.Datetime( | ||
string='Est Delivery Date', | ||
) | ||
is_guaranteed = fields.Boolean( | ||
string='Date is Guaranteed?', | ||
) | ||
partner_id = fields.Many2one( | ||
string='Carrier Partner', | ||
comodel_name='res.partner', | ||
related='service_id.partner_id', | ||
) | ||
state = fields.Selection([ | ||
('new', 'Quoted'), | ||
('purchase', 'Purchased'), | ||
('cancel', 'Voided'), | ||
], | ||
default='new', | ||
) | ||
is_purchased = fields.Boolean( | ||
compute='_compute_is_purchased', | ||
) | ||
|
||
@api.multi | ||
@api.depends('state') | ||
def _compute_date_purchased(self): | ||
for rec_id in self: | ||
if rec_id.state == 'purchase' and not rec_id.date_purchased: | ||
rec_id.date_purchased = fields.Datetime.now() | ||
|
||
@api.multi | ||
def _compute_is_purchased(self): | ||
for rec_id in self: | ||
rec_id.is_purchased = bool(rec_id.date_purchased) | ||
|
||
@api.multi | ||
def name_get(self): | ||
res = [] | ||
for rec_id in self: | ||
name = '{partner_name} {service_name} - {rate}'.format( | ||
partner_name=rec_id.partner_id.name, | ||
service_name=rec_id.service_id.name, | ||
rate=rec_id.rate, | ||
) | ||
res.append((rec_id.id, name)) | ||
return res | ||
|
||
@api.multi | ||
def action_purchase(self): | ||
wizard_id = self.env['stock.picking.dispatch.rate.purchase'].create({ | ||
'rate_ids': [(6, 0, [r.id for r in self])], | ||
}) | ||
return wizard_id.action_show_wizard() | ||
|
||
@api.multi | ||
def _expire_other_rates(self): | ||
""" Expires rates in picking that are not record """ | ||
for rec_id in self: | ||
rate_ids = rec_id.picking_id.dispatch_rate_ids.filtered( | ||
lambda r: r.id != rec_id.id | ||
) | ||
rate_ids.write({ | ||
'state': 'cancel', | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink | ||
access_stock_picking_dispatch_rate_user,access_stock_picking_dispatch_rate_user,model_stock_picking_dispatch_rate,stock.group_stock_user,1,1,1,0 | ||
access_stock_picking_dispatch_rate_manager,access_stock_picking_dispatch_rate_manager,model_stock_picking_dispatch_rate,stock.group_stock_manager,1,1,1,1 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 LasLabs Inc. | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from . import test_stock_picking_dispatch_rate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 LasLabs Inc. | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from openerp.tests.common import TransactionCase | ||
|
||
|
||
class TestHelper(TransactionCase): | ||
|
||
def setUp(self): | ||
super(TestHelper, self).setUp() | ||
self.picking_id = self.env['stock.picking'].create({ | ||
'location_dest_id': self.env['stock.location'].search([])[0].id, | ||
'location_id': self.env['stock.location'].search([])[0].id, | ||
'picking_type_id': | ||
self.env['stock.picking.type'].search([])[0].id, | ||
}) | ||
self.partner_id = self.env['res.partner'].create({'name': 'Carrier'}) | ||
self.service_id = self.env['delivery.carrier'].create({ | ||
'partner_id': self.partner_id.id, | ||
'name': 'Test Method', | ||
}) | ||
self.rate = 1.23 | ||
self.rate_vals = { | ||
'picking_id': self.picking_id.id, | ||
'service_id': self.service_id.id, | ||
'rate_currency_id': self.env.ref('base.USD').id, | ||
'rate': self.rate, | ||
} | ||
|
||
def new_record(self): | ||
return self.env['stock.picking.dispatch.rate'].create(self.rate_vals) |
83 changes: 83 additions & 0 deletions
83
stock_picking_rate/tests/test_stock_picking_dispatch_rate.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 LasLabs Inc. | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
import mock | ||
from .common import TestHelper | ||
|
||
|
||
class TestStockPickingDispatchRate(TestHelper): | ||
|
||
def test_compute_date_purchased(self): | ||
""" It should start out with no date, then have one after purchase """ | ||
rec_id = self.new_record() | ||
self.assertFalse(rec_id.date_purchased) | ||
rec_id.write({ | ||
'state': 'purchase', | ||
}) | ||
self.assertTrue(rec_id.date_purchased) | ||
|
||
def test_compute_is_purchased_before(self): | ||
""" It should start out False """ | ||
rec_id = self.new_record() | ||
self.assertFalse(rec_id.is_purchased) | ||
|
||
def test_compute_is_purchased_after(self): | ||
""" It should be True after purchase """ | ||
rec_id = self.new_record() | ||
rec_id.write({ | ||
'date_purchased': '2016-01-01 00:00:00', | ||
}) | ||
self.assertTrue(rec_id.is_purchased) | ||
|
||
def test_name_get(self): | ||
""" It should return proper display_name & syntax """ | ||
rec_id = self.new_record() | ||
expect = '{partner_name} {service_name} - {rate}'.format( | ||
partner_name=self.partner_id.name, | ||
service_name=self.service_id.name, | ||
rate=self.rate, | ||
) | ||
self.assertEqual( | ||
expect, rec_id.name_get()[0][1], | ||
'Did not get name w/ state. Expect %s, Got %s' % ( | ||
expect, rec_id.name_get()[0][1], | ||
) | ||
) | ||
|
||
def test_action_purchase_calls_create(self): | ||
""" It should create new purchase wizard w/ rate """ | ||
rec_id = self.new_record() | ||
with mock.patch.object(rec_id, 'env') as mk: | ||
model_mk = mk['stock.picking.dispatch.rate.purchase'] | ||
rec_id.action_purchase() | ||
model_mk.create.assert_called_once_with( | ||
{'rate_ids': [(6, 0, [rec_id.id])]} | ||
) | ||
|
||
def test_action_purchase_returns_wizard_view(self): | ||
""" It should return result of wizard view helper """ | ||
rec_id = self.new_record() | ||
with mock.patch.object(rec_id, 'env') as mk: | ||
model_mk = mk['stock.picking.dispatch.rate.purchase'] | ||
res = rec_id.action_purchase() | ||
self.assertEqual( | ||
model_mk.create().action_show_wizard(), | ||
res, | ||
) | ||
|
||
def test_expire_other_rates_expires_rates(self): | ||
""" It should expire other rates associated with the same picking """ | ||
rec_ids = [self.new_record(), self.new_record()] | ||
rec_ids[0]._expire_other_rates() | ||
self.assertEqual( | ||
'cancel', rec_ids[1].state, | ||
) | ||
|
||
def test_expire_other_rates_leaves_other_rate(self): | ||
""" It should not expire the rate it is called on """ | ||
rec_ids = [self.new_record(), self.new_record()] | ||
rec_ids[0]._expire_other_rates() | ||
self.assertNotEqual( | ||
'cancel', rec_ids[0].state, | ||
) |
Oops, something went wrong.