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