This repository has been archived by the owner on Dec 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
purchase.py
159 lines (125 loc) · 5.22 KB
/
purchase.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.i18n import gettext
from trytond.model import ModelSQL, ModelView, fields
from trytond.modules.product import round_price
from trytond.pool import Pool, PoolMeta
from .common import (
AmendmentLineMixin, get_moves, get_shipments_returns,
handle_shipment_exception_mixin, order_line_component_mixin,
order_line_mixin, order_mixin, search_moves, search_shipments_returns)
from .product import ComponentMixin
class Purchase(order_mixin('purchase'), metaclass=PoolMeta):
__name__ = 'purchase.purchase'
def create_move(self, move_type):
moves = super().create_move(move_type)
for line in self.lines:
if line.components:
for component in line.components:
move = component.get_move(move_type)
if move:
moves.append(move)
return moves
@get_shipments_returns('stock.shipment.in')
def get_shipments(self, name):
return super().get_shipments(name)
@get_shipments_returns('stock.shipment.in.return')
def get_shipment_returns(self, name):
return super().get_shipment_returns(name)
@classmethod
@search_shipments_returns('stock.shipment.in')
def search_shipments(cls, name, clause):
return super().search_shipments(name, clause)
@classmethod
@search_shipments_returns('stock.shipment.in.return')
def search_shipment_returns(cls, name, clause):
return super().search_shipments(name, clause)
@get_moves
def get_moves(self, name):
return super().get_moves(name)
@classmethod
@search_moves
def search_moves(cls, name, clause):
return super().search_moves(name, clause)
class Line(order_line_mixin('purchase'), metaclass=PoolMeta):
__name__ = 'purchase.line'
def get_component_order_line(self, component, **values):
values = values.copy()
values['purchase'] = self.purchase
return super().get_component_order_line(component, **values)
@classmethod
def get_move_product_types(cls):
types = super().get_move_product_types()
types.append('kit')
return types
class LineComponent(
order_line_component_mixin('purchase'), ComponentMixin,
ModelSQL, ModelView):
"Purchase Line Component"
__name__ = 'purchase.line.component'
def get_move(self, move_type):
from trytond.modules.purchase.exceptions import PartyLocationError
pool = Pool()
Move = pool.get('stock.move')
if (self.quantity >= 0) != (move_type == 'in'):
return
quantity = (
self._get_move_quantity(move_type)
- self._get_shipped_quantity(move_type))
quantity = self.unit.round(quantity)
if quantity <= 0:
return
if not self.line.purchase.party.supplier_location:
raise PartyLocationError(
gettext('purchase.msg_purchase_supplier_location_required',
purchase=self.purchase.rec_name,
party=self.purchase.party.rec_name))
move = Move()
move.quantity = quantity
move.uom = self.unit
move.product = self.product
move.from_location = self.line.from_location
move.to_location = self.line.to_location
move.state = 'draft'
move.company = self.line.purchase.company
if move.on_change_with_unit_price_required():
move.unit_price = round_price(
self.line.unit_price * self.price_ratio)
move.currency = self.line.purchase.currency
move.planned_date = self.line.planned_delivery_date
move.origin = self
return move
def _get_move_quantity(self, shipment_type):
'Return the quantity that should be shipped'
return abs(self.quantity)
class LineComponentIgnoredMove(ModelSQL):
'Purchase Line Component - Ignored Move'
__name__ = 'purchase.line.component-ignored-stock.move'
component = fields.Many2One(
'purchase.line.component', "Component",
ondelete='CASCADE', required=True)
move = fields.Many2One(
'stock.move', "Move", ondelete='RESTRICT', required=True)
class LineComponentRecreatedMove(ModelSQL):
'Purchase Line Component - Recreated Move'
__name__ = 'purchase.line.component-recreated-stock.move'
component = fields.Many2One(
'purchase.line.component', "Component",
ondelete='CASCADE', required=True)
move = fields.Many2One(
'stock.move', "Move", ondelete='RESTRICT', required=True)
class HandleShipmentException(
handle_shipment_exception_mixin('purchase'),
metaclass=PoolMeta):
__name__ = 'purchase.handle.shipment.exception'
class Amendment(metaclass=PoolMeta):
__name__ = 'purchase.amendment'
@classmethod
def _stock_moves(cls, line):
yield from super()._stock_moves(line)
for component in line.components:
for move in component.moves:
if move.state == 'draft':
yield move
class AmendmentLine(AmendmentLineMixin, metaclass=PoolMeta):
__name__ = 'purchase.amendment.line'