Add employee on shipments for some states
issue6183 review26031002
This commit is contained in:
1 parent
ebc381300b
commit
4393bf0e0a
9 files changed
+163
-1
No files matched your search
@@ -1,3 +1,4 @@
|
||||
* Add employee on shipments for some states
|
||||
* Add request state on internal shipment
|
||||
* Manage same picking/storage and output location
|
||||
|
||||
|
||||
+68
@@ -32,6 +32,38 @@ __all__ = ['ShipmentIn', 'ShipmentInReturn',
|
||||
'InteralShipmentReport']
|
||||
|
||||
|
||||
def set_employee(field):
|
||||
def decorator(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(cls, shipments, *args, **kwargs):
|
||||
pool = Pool()
|
||||
User = pool.get('res.user')
|
||||
user = User(Transaction().user)
|
||||
|
||||
result = func(cls, shipments, *args, **kwargs)
|
||||
employee = user.employee
|
||||
if employee:
|
||||
company = employee.company
|
||||
cls.write(
|
||||
[s for s in shipments
|
||||
if not getattr(s, field) and s.company == company], {
|
||||
field: employee.id,
|
||||
})
|
||||
return result
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
def employee_field(string):
|
||||
return fields.Many2One(
|
||||
'company.employee', string,
|
||||
domain=[('company', '=', Eval('company', -1))],
|
||||
states={
|
||||
'readonly': Eval('state').in_(['done', 'cancel']),
|
||||
},
|
||||
depends=['company', 'state'])
|
||||
|
||||
|
||||
class ShipmentIn(Workflow, ModelSQL, ModelView):
|
||||
"Supplier Shipment"
|
||||
__name__ = 'stock.shipment.in'
|
||||
@@ -123,6 +155,8 @@ class ShipmentIn(Workflow, ModelSQL, ModelView):
|
||||
depends=['company'])
|
||||
origins = fields.Function(fields.Char('Origins'), 'get_origins')
|
||||
number = fields.Char('Numer', size=None, select=True, readonly=True)
|
||||
received_by = employee_field("Received By")
|
||||
done_by = employee_field("Done By")
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('done', 'Done'),
|
||||
@@ -393,6 +427,8 @@ class ShipmentIn(Workflow, ModelSQL, ModelView):
|
||||
default['inventory_moves'] = None
|
||||
default['incoming_moves'] = None
|
||||
default.setdefault('number')
|
||||
default.setdefault('received_by')
|
||||
default.setdefault('done_by')
|
||||
return super(ShipmentIn, cls).copy(shipments, default=default)
|
||||
|
||||
@classmethod
|
||||
@@ -460,6 +496,7 @@ class ShipmentIn(Workflow, ModelSQL, ModelView):
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('received')
|
||||
@set_employee('received_by')
|
||||
def receive(cls, shipments):
|
||||
Move = Pool().get('stock.move')
|
||||
Move.do([m for s in shipments for m in s.incoming_moves])
|
||||
@@ -468,6 +505,7 @@ class ShipmentIn(Workflow, ModelSQL, ModelView):
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('done')
|
||||
@set_employee('done_by')
|
||||
def done(cls, shipments):
|
||||
pool = Pool()
|
||||
Move = pool.get('stock.move')
|
||||
@@ -549,6 +587,8 @@ class ShipmentInReturn(Workflow, ModelSQL, ModelView):
|
||||
],
|
||||
depends=['state', 'from_location', 'to_location', 'company'])
|
||||
origins = fields.Function(fields.Char('Origins'), 'get_origins')
|
||||
assigned_by = employee_field("Assigned By")
|
||||
done_by = employee_field("Done By")
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('cancel', 'Canceled'),
|
||||
@@ -727,6 +767,8 @@ class ShipmentInReturn(Workflow, ModelSQL, ModelView):
|
||||
default = {}
|
||||
default = default.copy()
|
||||
default.setdefault('number')
|
||||
default.setdefault('assigned_by')
|
||||
default.setdefault('done_by')
|
||||
return super(ShipmentInReturn, cls).copy(shipments, default=default)
|
||||
|
||||
@classmethod
|
||||
@@ -755,6 +797,7 @@ class ShipmentInReturn(Workflow, ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
@Workflow.transition('assigned')
|
||||
@set_employee('assigned_by')
|
||||
def assign(cls, shipments):
|
||||
Move = Pool().get('stock.move')
|
||||
Move.assign([m for s in shipments for m in s.moves])
|
||||
@@ -762,6 +805,7 @@ class ShipmentInReturn(Workflow, ModelSQL, ModelView):
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('done')
|
||||
@set_employee('done_by')
|
||||
def done(cls, shipments):
|
||||
pool = Pool()
|
||||
Move = pool.get('stock.move')
|
||||
@@ -889,6 +933,9 @@ class ShipmentOut(Workflow, ModelSQL, ModelView):
|
||||
readonly=True)
|
||||
origins = fields.Function(fields.Char('Origins'), 'get_origins')
|
||||
number = fields.Char('Number', size=None, select=True, readonly=True)
|
||||
assigned_by = employee_field("Assigned By")
|
||||
packed_by = employee_field("Packed By")
|
||||
done_by = employee_field("Done By")
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('done', 'Done'),
|
||||
@@ -1153,12 +1200,14 @@ class ShipmentOut(Workflow, ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
@Workflow.transition('assigned')
|
||||
@set_employee('assigned_by')
|
||||
def assign(cls, shipments):
|
||||
cls._sync_inventory_to_outgoing(shipments, create=True, write=False)
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('packed')
|
||||
@set_employee('packed_by')
|
||||
def pack(cls, shipments):
|
||||
pool = Pool()
|
||||
Move = pool.get('stock.move')
|
||||
@@ -1256,6 +1305,7 @@ class ShipmentOut(Workflow, ModelSQL, ModelView):
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('done')
|
||||
@set_employee('done_by')
|
||||
def done(cls, shipments):
|
||||
pool = Pool()
|
||||
Move = pool.get('stock.move')
|
||||
@@ -1337,6 +1387,9 @@ class ShipmentOut(Workflow, ModelSQL, ModelView):
|
||||
default['inventory_moves'] = None
|
||||
default['outgoing_moves'] = None
|
||||
default.setdefault('number')
|
||||
default.setdefault('assigned_by')
|
||||
default.setdefault('packed_by')
|
||||
default.setdefault('done_by')
|
||||
return super(ShipmentOut, cls).copy(shipments, default=default)
|
||||
|
||||
@classmethod
|
||||
@@ -1470,6 +1523,8 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView):
|
||||
readonly=True)
|
||||
origins = fields.Function(fields.Char('Origins'), 'get_origins')
|
||||
number = fields.Char('Number', size=None, select=True, readonly=True)
|
||||
received_by = employee_field("Received By")
|
||||
done_by = employee_field("Done By")
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('done', 'Done'),
|
||||
@@ -1697,6 +1752,8 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView):
|
||||
default['inventory_moves'] = None
|
||||
default['incoming_moves'] = None
|
||||
default.setdefault('number')
|
||||
default.setdefault('received_by')
|
||||
default.setdefault('done_by')
|
||||
return super(ShipmentOutReturn, cls).copy(shipments, default=default)
|
||||
|
||||
@classmethod
|
||||
@@ -1723,6 +1780,7 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView):
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('received')
|
||||
@set_employee('received_by')
|
||||
def receive(cls, shipments):
|
||||
Move = Pool().get('stock.move')
|
||||
Move.do([m for s in shipments for m in s.incoming_moves])
|
||||
@@ -1731,6 +1789,7 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView):
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('done')
|
||||
@set_employee('done_by')
|
||||
def done(cls, shipments):
|
||||
pool = Pool()
|
||||
Move = pool.get('stock.move')
|
||||
@@ -1957,6 +2016,9 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView):
|
||||
depends=['from_location', 'to_location', 'transit_location',
|
||||
'state']),
|
||||
'get_incoming_moves', setter='set_moves')
|
||||
assigned_by = employee_field("Received By")
|
||||
shipped_by = employee_field("Shipped By")
|
||||
done_by = employee_field("Done By")
|
||||
state = fields.Selection([
|
||||
('request', 'Request'),
|
||||
('draft', 'Draft'),
|
||||
@@ -2189,6 +2251,9 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView):
|
||||
default['incoming_moves'] = None
|
||||
default['moves'] = None
|
||||
default.setdefault('number')
|
||||
default.setdefault('assigned_by')
|
||||
default.setdefault('shipped_by')
|
||||
default.setdefault('done_by')
|
||||
copies = super(ShipmentInternal, cls).copy(shipments, default=default)
|
||||
for shipment, copy in zip(shipments, copies):
|
||||
Move.copy(shipment.outgoing_moves, default={
|
||||
@@ -2305,11 +2370,13 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
@Workflow.transition('assigned')
|
||||
@set_employee('assigned_by')
|
||||
def assign(cls, shipments):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
@Workflow.transition('shipped')
|
||||
@set_employee('shipped_by')
|
||||
def ship(cls, shipments):
|
||||
pool = Pool()
|
||||
Move = pool.get('stock.move')
|
||||
@@ -2323,6 +2390,7 @@ class ShipmentInternal(Workflow, ModelSQL, ModelView):
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
@Workflow.transition('done')
|
||||
@set_employee('done_by')
|
||||
def done(cls, shipments):
|
||||
pool = Pool()
|
||||
Move = pool.get('stock.move')
|
||||
|
||||
@@ -53,12 +53,20 @@ Create stock user::
|
||||
|
||||
>>> User = Model.get('res.user')
|
||||
>>> Group = Model.get('res.group')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> Employee = Model.get('company.employee')
|
||||
>>> stock_user = User()
|
||||
>>> stock_user.name = 'Stock'
|
||||
>>> stock_user.login = 'stock'
|
||||
>>> stock_user.main_company = company
|
||||
>>> stock_group, = Group.find([('name', '=', 'Stock')])
|
||||
>>> stock_user.groups.append(stock_group)
|
||||
>>> employee_party = Party(name="Employee")
|
||||
>>> employee_party.save()
|
||||
>>> employee = Employee(party=employee_party)
|
||||
>>> employee.save()
|
||||
>>> stock_user.employees.append(employee)
|
||||
>>> stock_user.employee = employee
|
||||
>>> stock_user.save()
|
||||
|
||||
Create Internal Shipment::
|
||||
@@ -76,11 +84,17 @@ Create Internal Shipment::
|
||||
>>> move.from_location = internal_loc
|
||||
>>> move.to_location = storage_loc
|
||||
>>> move.currency = company.currency
|
||||
>>> shipment.save()
|
||||
>>> shipment.assigned_by
|
||||
>>> shipment.done_by
|
||||
|
||||
>>> shipment.click('wait')
|
||||
>>> shipment.state
|
||||
u'waiting'
|
||||
>>> shipment.click('assign_try')
|
||||
False
|
||||
>>> shipment.assigned_by
|
||||
>>> shipment.done_by
|
||||
|
||||
Create Internal Shipment from lost_found location::
|
||||
|
||||
@@ -110,9 +124,15 @@ Check that now whe can finish the older shipment::
|
||||
|
||||
>>> shipment.click('assign_try')
|
||||
True
|
||||
>>> shipment.assigned_by == employee
|
||||
True
|
||||
>>> shipment.done_by
|
||||
|
||||
>>> shipment.click('done')
|
||||
>>> shipment.state
|
||||
u'done'
|
||||
>>> shipment.done_by == employee
|
||||
True
|
||||
|
||||
Add lead time inside the warehouse::
|
||||
|
||||
|
||||
@@ -46,6 +46,28 @@ Create product::
|
||||
>>> product.template = template
|
||||
>>> product.save()
|
||||
|
||||
Create stock user::
|
||||
|
||||
>>> User = Model.get('res.user')
|
||||
>>> Group = Model.get('res.group')
|
||||
>>> Employee = Model.get('company.employee')
|
||||
>>> stock_user = User()
|
||||
>>> stock_user.name = "Stock"
|
||||
>>> stock_user.login = 'stock'
|
||||
>>> stock_user.main_company = company
|
||||
>>> stock_user.groups.extend(Group.find([
|
||||
... ('name', '=', 'Stock'),
|
||||
... ]))
|
||||
>>> employee_party = Party(name="Employee")
|
||||
>>> employee_party.save()
|
||||
>>> employee = Employee(party=employee_party)
|
||||
>>> employee.save()
|
||||
>>> stock_user.employees.append(employee)
|
||||
>>> stock_user.employee = employee
|
||||
>>> stock_user.save()
|
||||
|
||||
>>> config.user = stock_user.id
|
||||
|
||||
Get stock locations::
|
||||
|
||||
>>> Location = Model.get('stock.location')
|
||||
@@ -78,6 +100,9 @@ Add two shipment lines of same product::
|
||||
... move.unit_price = Decimal('1')
|
||||
... move.currency = company.currency
|
||||
>>> shipment_out.save()
|
||||
>>> shipment_out.assigned_by
|
||||
>>> shipment_out.packed_by
|
||||
>>> shipment_out.done_by
|
||||
|
||||
Set the shipment state to waiting::
|
||||
|
||||
@@ -132,7 +157,15 @@ Delete the draft move, assign and pack shipment::
|
||||
>>> shipment_out.inventory_moves.remove(move)
|
||||
>>> shipment_out.click('assign_try')
|
||||
True
|
||||
>>> shipment_out.assigned_by == employee
|
||||
True
|
||||
>>> shipment_out.packed_by
|
||||
>>> shipment_out.done_by
|
||||
|
||||
>>> shipment_out.click('pack')
|
||||
>>> shipment_out.packed_by == employee
|
||||
True
|
||||
>>> shipment_out.done_by
|
||||
>>> all(m.state == 'assigned' for m in shipment_out.outgoing_moves)
|
||||
True
|
||||
>>> len(shipment_out.outgoing_moves)
|
||||
@@ -148,6 +181,8 @@ Delete the draft move, assign and pack shipment::
|
||||
Set the state as Done::
|
||||
|
||||
>>> shipment_out.click('done')
|
||||
>>> shipment_out.done_by == employee
|
||||
True
|
||||
>>> all(m.state == 'done' for m in shipment_out.outgoing_moves)
|
||||
True
|
||||
>>> planned_dates = [m.planned_date for m in
|
||||
|
||||
@@ -25,6 +25,12 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<page string="Inventory Moves" id="inventory_moves">
|
||||
<field name="inventory_moves" colspan="4"/>
|
||||
</page>
|
||||
<page string="Other Info" id="other">
|
||||
<label name="received_by"/>
|
||||
<field name="received_by"/>
|
||||
<label name="done_by"/>
|
||||
<field name="done_by"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<group col="4" colspan="6" id="state_buttons">
|
||||
<label name="state"/>
|
||||
|
||||
@@ -18,7 +18,17 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="planned_date"/>
|
||||
<label name="effective_date"/>
|
||||
<field name="effective_date"/>
|
||||
<field name="moves" colspan="4"/>
|
||||
<notebook colspan="4">
|
||||
<page name="moves">
|
||||
<field name="moves" colspan="4"/>
|
||||
</page>
|
||||
<page string="Other Info" id="other">
|
||||
<label name="assigned_by"/>
|
||||
<field name="assigned_by"/>
|
||||
<label name="done_by"/>
|
||||
<field name="done_by"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
<group col="-1" colspan="2" id="buttons">
|
||||
|
||||
@@ -30,6 +30,14 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<page name="incoming_moves">
|
||||
<field name="incoming_moves" colspan="4"/>
|
||||
</page>
|
||||
<page string="Other Info" id="other">
|
||||
<label name="assigned_by"/>
|
||||
<field name="assigned_by"/>
|
||||
<label name="shipped_by"/>
|
||||
<field name="shipped_by"/>
|
||||
<label name="done_by"/>
|
||||
<field name="done_by"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
|
||||
@@ -25,6 +25,14 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<page string="Outgoing Moves" id="outgoing_moves">
|
||||
<field name="outgoing_moves" colspan="4"/>
|
||||
</page>
|
||||
<page string="Other Info" id="other">
|
||||
<label name="assigned_by"/>
|
||||
<field name="assigned_by"/>
|
||||
<label name="packed_by"/>
|
||||
<field name="packed_by"/>
|
||||
<label name="done_by"/>
|
||||
<field name="done_by"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<group col="4" colspan="4" id="state_buttons">
|
||||
<label name="state"/>
|
||||
|
||||
@@ -25,6 +25,12 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<page string="Inventory Moves" id="inventory_moves">
|
||||
<field name="inventory_moves" colspan="4"/>
|
||||
</page>
|
||||
<page string="Other Info" id="other">
|
||||
<label name="received_by"/>
|
||||
<field name="received_by"/>
|
||||
<label name="done_by"/>
|
||||
<field name="done_by"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<group col="4" colspan="6" id="state_buttons">
|
||||
<label name="state"/>
|
||||
|
||||
Reference in new issue
Block a user