v2.0
open source Production PLanning
Home
Documentation
Getting started
Modeling guide
User guide
Installation guide
Developer guide
FAQ
C++ API
C++ API - flowplan.cpp Source File
Main Page
Namespaces
Classes
Files
File List
File Members
src
model
flowplan.cpp
Go to the documentation of this file.
1
/***************************************************************************
2
* *
3
* Copyright (C) 2007-2012 by Johan De Taeye, frePPLe bvba *
4
* *
5
* This library is free software; you can redistribute it and/or modify it *
6
* under the terms of the GNU Affero General Public License as published *
7
* by the Free Software Foundation; either version 3 of the License, or *
8
* (at your option) any later version. *
9
* *
10
* This library is distributed in the hope that it will be useful, *
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13
* GNU Affero General Public License for more details. *
14
* *
15
* You should have received a copy of the GNU Affero General Public *
16
* License along with this program. *
17
* If not, see <http://www.gnu.org/licenses/>. *
18
* *
19
***************************************************************************/
20
21
#define FREPPLE_CORE
22
#include "
frepple/model.h
"
23
namespace
frepple
24
{
25
26
DECLARE_EXPORT
const
MetaCategory
*
FlowPlan::metadata
;
27
28
29
int
FlowPlan::initialize
()
30
{
31
// Initialize the metadata
32
metadata
=
new
MetaCategory
(
"flowplan"
,
"flowplans"
);
33
34
// Initialize the Python type
35
PythonType
& x =
FreppleCategory<FlowPlan>::getType
();
36
x.
setName
(
"flowplan"
);
37
x.
setDoc
(
"frePPLe flowplan"
);
38
x.
supportgetattro
();
39
const_cast<
MetaCategory
*
>
(
metadata
)->pythonClass = x.
type_object
();
40
return
x.
typeReady
();
41
}
42
43
44
DECLARE_EXPORT
FlowPlan::FlowPlan
(
OperationPlan
*opplan,
const
Flow
*f)
45
{
46
assert(opplan && f);
47
fl =
const_cast<
Flow
*
>
(f);
48
49
// Initialize the Python type
50
initType
(
metadata
);
51
52
// Link the flowplan to the operationplan
53
oper = opplan;
54
nextFlowPlan = NULL;
55
if
(opplan->firstflowplan)
56
{
57
// Append to the end
58
FlowPlan
*c = opplan->firstflowplan;
59
while
(c->nextFlowPlan) c = c->nextFlowPlan;
60
c->nextFlowPlan =
this
;
61
}
62
else
63
// First in the list
64
opplan->firstflowplan =
this
;
65
66
// Compute the flowplan quantity
67
fl->
getBuffer
()->flowplans.
insert
(
68
this
,
69
fl->
getFlowplanQuantity
(
this
),
70
fl->
getFlowplanDate
(
this
)
71
);
72
73
// Mark the operation and buffer as having changed. This will trigger the
74
// recomputation of their problems
75
fl->
getBuffer
()->
setChanged
();
76
fl->
getOperation
()->
setChanged
();
77
}
78
79
80
DECLARE_EXPORT
void
FlowPlan::update
()
81
{
82
// Update the timeline data structure
83
fl->
getBuffer
()->flowplans.
update
(
84
this
,
85
fl->
getFlowplanQuantity
(
this
),
86
fl->
getFlowplanDate
(
this
)
87
);
88
89
// Mark the operation and buffer as having changed. This will trigger the
90
// recomputation of their problems
91
fl->
getBuffer
()->
setChanged
();
92
fl->
getOperation
()->
setChanged
();
93
}
94
95
96
DECLARE_EXPORT
void
FlowPlan::setFlow
(
const
Flow
* newfl)
97
{
98
// No change
99
if
(newfl == fl)
return
;
100
101
// Verify the data
102
if
(!newfl)
throw
LogicException
(
"Can't switch to NULL flow"
);
103
104
// Remove from the old buffer, if there is one
105
if
(fl)
106
{
107
if
(fl->
getOperation
() != newfl->
getOperation
())
108
throw
LogicException
(
"Only switching to a flow on the same operation is allowed"
);
109
fl->
getBuffer
()->flowplans.
erase
(
this
);
110
fl->
getBuffer
()->
setChanged
();
111
}
112
113
// Insert in the new buffer
114
fl = newfl;
115
fl->
getBuffer
()->flowplans.
insert
(
116
this
,
117
fl->
getFlowplanQuantity
(
this
),
118
fl->
getFlowplanDate
(
this
)
119
);
120
fl->
getBuffer
()->
setChanged
();
121
fl->
getOperation
()->
setChanged
();
122
}
123
124
125
// Remember that this method only superficially looks like a normal
126
// writeElement() method.
127
DECLARE_EXPORT
void
FlowPlan::writeElement
(
XMLOutput
*o,
const
Keyword
& tag,
mode
m)
const
128
{
129
o->
BeginObject
(tag);
130
o->
writeElement
(
Tags::tag_date
,
getDate
());
131
o->
writeElement
(
Tags::tag_quantity
,
getQuantity
());
132
o->
writeElement
(
Tags::tag_onhand
,
getOnhand
());
133
o->
writeElement
(
Tags::tag_minimum
,
getMin
());
134
o->
writeElement
(
Tags::tag_maximum
,
getMax
());
135
if
(!dynamic_cast<OperationPlan*>(o->
getCurrentObject
()))
136
o->
writeElement
(
Tags::tag_operationplan
, &*
getOperationPlan
());
137
138
// Write pegging info
139
if
(o->
getContentType
() == XMLOutput::PLANDETAIL)
140
{
141
// Write the upstream pegging
142
PeggingIterator
k(
this
,
false
);
143
if
(k) --k;
144
for
(; k; --k)
145
{
146
o->
BeginObject
(
Tags::tag_pegging
,
Tags::tag_level
, k.
getLevel
());
147
o->
writeElement
(
Tags::tag_quantity
, k.
getQuantityDemand
());
148
o->
writeElement
(
Tags::tag_factor
, k.
getFactor
());
149
if
(!k.
getPegged
()) o->
writeElement
(
Tags::tag_id
,
"unpegged"
);
150
o->
writeElement
(
Tags::tag_buffer
,
Tags::tag_name
, k.
getBuffer
()->
getName
());
151
if
(k.
getConsumingOperationplan
())
152
o->
writeElement
(
Tags::tag_consuming
,
153
Tags::tag_id
, k.
getConsumingOperationplan
()->
getIdentifier
(),
154
Tags::tag_operation
, k.
getConsumingOperationplan
()->
getOperation
()->
getName
());
155
if
(k.
getProducingOperationplan
())
156
o->
writeElement
(
Tags::tag_producing
,
157
Tags::tag_id
, k.
getProducingOperationplan
()->
getIdentifier
(),
158
Tags::tag_operation
, k.
getProducingOperationplan
()->
getOperation
()->
getName
());
159
o->
writeElement
(
Tags::tag_dates
,
DateRange
(k.
getProducingDate
(),k.
getConsumingDate
()));
160
o->
EndObject
(
Tags::tag_pegging
);
161
}
162
163
// Write the downstream pegging
164
PeggingIterator
l(
this
,
true
);
165
if
(l) ++l;
166
for
(; l; ++l)
167
{
168
o->
BeginObject
(
Tags::tag_pegging
,
Tags::tag_level
, l.
getLevel
());
169
o->
writeElement
(
Tags::tag_quantity
, l.
getQuantityDemand
());
170
o->
writeElement
(
Tags::tag_factor
, l.
getFactor
());
171
if
(!l.
getPegged
()) o->
writeElement
(
Tags::tag_id
,
"unpegged"
);
172
o->
writeElement
(
Tags::tag_buffer
,
Tags::tag_name
, l.
getBuffer
()->
getName
());
173
if
(l.
getConsumingOperationplan
())
174
o->
writeElement
(
Tags::tag_consuming
,
175
Tags::tag_id
, l.
getConsumingOperationplan
()->
getIdentifier
(),
176
Tags::tag_operation
, l.
getConsumingOperationplan
()->
getOperation
()->
getName
());
177
if
(l.
getProducingOperationplan
())
178
o->
writeElement
(
Tags::tag_producing
,
179
Tags::tag_id
, l.
getProducingOperationplan
()->
getIdentifier
(),
180
Tags::tag_operation
, l.
getProducingOperationplan
()->
getOperation
()->
getName
());
181
o->
writeElement
(
Tags::tag_dates
,
DateRange
(l.
getProducingDate
(),l.
getConsumingDate
()));
182
o->
EndObject
(
Tags::tag_pegging
);
183
}
184
}
185
186
o->
EndObject
(tag);
187
}
188
189
190
PyObject* FlowPlan::getattro(
const
Attribute
& attr)
191
{
192
if
(attr.
isA
(
Tags::tag_operationplan
))
193
return
PythonObject
(
getOperationPlan
());
194
if
(attr.
isA
(
Tags::tag_quantity
))
195
return
PythonObject
(
getQuantity
());
196
if
(attr.
isA
(
Tags::tag_flow
))
197
return
PythonObject
(
getFlow
());
198
if
(attr.
isA
(
Tags::tag_date
))
199
return
PythonObject
(
getDate
());
200
if
(attr.
isA
(
Tags::tag_onhand
))
201
return
PythonObject
(
getOnhand
());
202
if
(attr.
isA
(
Tags::tag_buffer
))
// Convenient shortcut
203
return
PythonObject
(
getFlow
()->
getBuffer
());
204
if
(attr.
isA
(
Tags::tag_operation
))
// Convenient shortcut
205
return
PythonObject
(
getFlow
()->
getOperation
());
206
return
NULL;
207
}
208
209
210
int
FlowPlanIterator::initialize
()
211
{
212
// Initialize the type
213
PythonType
& x =
PythonExtension<FlowPlanIterator>::getType
();
214
x.
setName
(
"flowplanIterator"
);
215
x.
setDoc
(
"frePPLe iterator for flowplan"
);
216
x.
supportiter
();
217
return
x.
typeReady
();
218
}
219
220
221
PyObject* FlowPlanIterator::iternext()
222
{
223
FlowPlan
* fl;
224
if
(buffer_or_opplan)
225
{
226
// Skip uninteresting entries
227
while
(*
bufiter
!=
buf
->
getFlowPlans
().
end
() && (*bufiter)->getQuantity()==0.0)
228
++(*bufiter);
229
if
(*
bufiter
==
buf
->
getFlowPlans
().
end
())
return
NULL;
230
fl =
const_cast<
FlowPlan
*
>
(
static_cast<
const
FlowPlan
*
>
(&*((*bufiter)++)));
231
}
232
else
233
{
234
// Skip uninteresting entries
235
while
(*
opplaniter
!=
opplan
->
endFlowPlans
() && (*opplaniter)->
getQuantity
()==0.0)
236
++(*opplaniter);
237
if
(*
opplaniter
==
opplan
->
endFlowPlans
())
return
NULL;
238
fl =
static_cast<
FlowPlan*
>
(&*((*opplaniter)++));
239
}
240
Py_INCREF(fl);
241
return
const_cast<
FlowPlan*
>
(fl);
242
}
243
244
}
// end namespace