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