Add missing location at the end.
[order_line_extra.git] / haxe / ItemScheduler.hx
1 import php.Lib;
2
3 typedef Detail = {
4         id : String,
5         quantity : Int,
6         position : Int,
7 }
8
9 typedef Order = {
10                 id:String
11                 ,quantity:String
12                 ,priority:Int
13                 ,delivery_date:String
14
15 }
16
17 class ScheduleParameters {
18         var row_id : String;
19         var rowDetails: Hash<Detail>;
20
21         function new(rawData : Dynamic) {
22                 var data  = php.Lib.hashOfAssociativeArray(rawData);
23                 row_id = data.get('row_id');
24                 var raw_order : Dynamic = data.get('row_order');
25
26                 var row_ids = php.Lib.toHaxeArray(raw_order);
27                 if (row_ids!= null) {
28                         rowDetails = new Hash<Detail>();
29                         var position = 1;
30                         for(id in row_ids) {
31                                 var d : Dynamic = data.get(id);
32
33                                 var quantity : Int = null;
34                                 if(d != null) {
35                                                 var o = php.Lib.objectOfAssociativeArray(d);
36                                                 quantity = Std.parseInt(o.quantity);
37                                 }
38                                 
39
40                                 rowDetails.set(id, {
41                                         id: id
42                                         ,quantity: quantity
43                                         ,position: position
44                                         });
45                                 position+=1;
46                         }
47                 }
48         }
49
50         public function position(id: String) : Null<Int> {
51                 if(rowDetails == null) return null;
52                 return rowDetails.get(id).position;
53
54         }
55
56         public function priority(order : {id: String, priority: Int})  : Int {
57                 var orderId = ItemScheduler.orderId(order);
58                 var orderPosition = position(orderId);
59                 return orderPosition != null  ? orderPosition : order.priority;
60         }
61 }
62
63
64 class ItemScheduler {
65         var stock_id:String;
66         var startLocation:String;
67         var parameters:ScheduleParameters; 
68         var qoh: Int;
69         function new(stock_id: String, startLocation, parameters : Null<ScheduleParameters>) {
70                 this.stock_id = stock_id;
71                 this.startLocation = startLocation;
72                 this.parameters = parameters;
73                 qoh =  untyped __call__('get_qoh_on_date', this.stock_id, 'DEF');
74         }
75
76         function tableHeader() {
77                 return ["Order", "Customer", "Quantity", "Before", "After", "Loc", "From",  "Required Date", "Comment"];
78         }
79
80         function generateTable(): Void {
81                 var startDate = Date.fromTime(0);
82
83                 // Sort location by date
84                 var locations = this.locations();
85                 locations.sort(function(a, b) {
86                                 return cast(a.delivery.getTime() - b.delivery.getTime(), Int );
87                                 });
88
89                 // Get the start location, it should be the first one
90                 var locationIter = locations.iterator();
91                 var location  = locationIter.next();
92                 var qoh : Int = location.quantityOnHand(stock_id, null);
93                 var left = qoh;
94                 formatLocation(location, "Initial", left);
95
96                 // We display the order ordered by priority 
97                 // But insert the location when needed (meaning
98                 // when we run out of item available
99                 for(order in orders()) {
100                         var quantity : Int = Std.parseInt(order.quantity);
101
102                         while(0 > left && locationIter.hasNext()) {
103                                 location = locationIter.next();
104                                 var quantityForLocation : Int = location.quantityOnHand(stock_id, null);
105                                 if(quantityForLocation == null || quantityForLocation == 0) continue;
106                                 left += quantityForLocation;
107                                 formatLocation(location, "Delivery", left);
108                         }
109                         left -= quantity;
110
111                         formatOrder(order, left, location.delivery);
112
113                 }
114                 // display the left locations
115                         while(0 > left && locationIter.hasNext()) {
116                                 location = locationIter.next();
117                                 var quantityForLocation : Int = location.quantityOnHand(stock_id, null);
118                                 if(quantityForLocation == null || quantityForLocation == 0) continue;
119                                 left += quantityForLocation;
120                                 formatLocation(location, "Delivery", left);
121                         }
122
123         }
124
125         function printRow(tds : Array<Dynamic>, attributes : Array<String>) {
126                 php.Lib.print('<tr '+attributes.join(' ')+'>');
127                 var position : Int = 1;
128                 for(td in tds) {
129                         php.Lib.print('<td class="cell_'+position+'">');
130                         if(td) php.Lib.print(td);
131                         php.Lib.print('</td>');
132                         position++;
133                 }
134                 php.Lib.print('</tr>');
135         }
136
137         static public function orderId(order) {
138                 return 'order_'+order.id;
139         }
140
141         function formatOrder(order : Dynamic, left : Int, date : Date) {
142                 var row_id = orderId(order);
143                 var attributes = ['id = "'+row_id+'"'];
144                 var classes = [];
145                 var before : Int = left + order.quantity;
146                 /* We have basically 3 different cases;
147                  * - the order can be fullfilled
148                  * - the order can be partially 
149                  * - not at all
150                  */
151                 if (before < 0 ) {
152                         classes.push('soldout');
153                 }
154                 else if(left < 0) {
155                         classes.push('partial');
156                 }
157                 else {
158                         classes.push('full');
159                 }
160
161                 /* The order can also be late if we need
162                  * to wait for a delivery to get it
163                  */
164                 var required_by : Date = FA.sql2date(order.required_date);
165                 if(required_by == null) required_by = FA.sql2date(order.delivery_date);
166                 if(required_by.getTime() < date.getTime()) {
167                         classes.push('late');
168                 }
169                 else {
170                         classes.push('on_time');
171                 }
172                 var cells : Array <Dynamic> = [
173                         order.order_id
174                         , '<a href="/modules/order_line_extra/order_lines_view.php?customer_id='+Std.string(order.debtor_no)+'">'+order.deliver_to+'</a>'
175                         ,'<input type="text" name="'+row_id+'[quantity]" value="'+order.quantity+'">'
176                         ,before
177                         ,left
178                         ,order.from_stk_loc
179                         ,order.delivery_date
180                         ,order.required_date 
181                         ,order.comment
182                         ];
183
184                 attributes.push('class="'+classes.join(' ')+'"');
185                 printRow(cells, attributes);
186
187         }
188
189         function formatLocation(location : Location, type: String,  left : Int) {
190                 var cells = [
191                         type
192                         ,location.name
193                         ,location.quantityOnHand(stock_id, null)
194                         ,left-location.quantityOnHand(stock_id, null)
195                         ,left
196                         ,location.code
197                         ,location.delivery
198                         ,""
199                         ,""
200                         ];
201
202                 printRow(cells, ['class = "tableheader location"', 'id = "loc_'+location.code+'"']);
203         }
204
205         /*
206                  function schedules() {
207 //return orders()+locations();
208 //return  orders();
209 return cast(locations(), Array<Dynamic>);
210
211 }
212          */
213
214 private function loadOrders() {
215         var tb : String =  untyped __php__('TB_PREF');
216         var sql : String = "SELECT *  
217                 FROM "+tb+"denorm_order_details_queue  d
218                 JOIN "+tb+"sales_order_details od ON (od.id = d.id)
219                 JOIN "+tb+"sales_orders so ON (so.order_no = d.order_id)
220                 WHERE stock_id = '"+this.stock_id+"'
221                 AND od.trans_type = 30
222                 ORDER by d.priority";
223
224         return FA.query(sql);
225 }
226
227 function orders():Array<Order>  {
228         var rows = loadOrders();
229         var orderList = [];
230         for(row in rows) {
231                 var order:Order = php.Lib.objectOfAssociativeArray(row);
232                 orderList.push(order);
233         };
234
235         if(parameters != null) {
236                 orderList.sort(function(a, b) { return parameters.priority(a)-parameters.priority(b); });
237
238         }
239                 for(order in orderList) {
240                 }
241
242         return orderList;
243 }
244
245
246
247 function locations() {
248         var TB = FA.tb();
249         var sql = 'SELECT * 
250                 FROM '+TB+'locations';
251         var _locs = [];
252         for(row in FA.query(sql)) {
253                 var location = new Location(row);
254                 if(location.code == startLocation) {
255                         location.delivery =  Date.fromTime(0);
256                 }
257                 _locs.push(location);
258         }
259
260         return _locs;
261
262 }
263
264
265 function purcharseOrders()  {
266 }
267
268
269 }
270
271