23 class ScheduleParameters {
25 var rowDetails: Hash<Detail>;
26 public var mode:ScheduleMode;
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 mode = ScheduleMode.Move;
34 var row_ids = php.Lib.toHaxeArray(raw_order);
36 rowDetails = new Hash<Detail>();
39 var d : Dynamic = data.get(id);
41 var quantity : Int = null;
43 var o = php.Lib.objectOfAssociativeArray(d);
44 quantity = Std.parseInt(o.quantity);
58 public function setMode(action:String) {
59 mode = switch(action) {
69 public function position(id: String) : Null<Int> {
70 if(rowDetails == null) return null;
71 return rowDetails.get(id).position;
75 public function priority(order : {id: String, priority: Int}) : Int {
76 var orderId = ItemScheduler.orderId(order);
77 var orderPosition = position(orderId);
78 return orderPosition != null ? orderPosition : order.priority;
85 var startLocation:String;
86 var parameters:ScheduleParameters;
88 function new(stock_id: String, startLocation, parameters : Null<ScheduleParameters>) {
89 this.stock_id = stock_id;
90 this.startLocation = startLocation;
91 this.parameters = parameters;
92 qoh = untyped __call__('get_qoh_on_date', this.stock_id, 'DEF');
95 function tableHeader() {
96 return ["Order", "Customer", "Quantity", "Before", "After", "Loc", "From", "Required Date", "Comment"];
99 function generateTable(): Void {
100 var startDate = Date.fromTime(0);
102 // Sort location by date
103 var locations = this.locations();
104 locations.sort(function(a, b) {
105 return cast(a.delivery.getTime() - b.delivery.getTime(), Int );
108 // Get the start location, it should be the first one
109 var locationIter = locations.iterator();
110 var location = locationIter.next();
111 var qoh : Int = location.quantityOnHand(stock_id, null);
113 formatLocation(location, "Initial", left);
115 // We display the order ordered by priority
116 // But insert the location when needed (meaning
117 // when we run out of item available
118 for(order in orders()) {
119 var quantity : Int = Std.parseInt(order.quantity);
121 while(0 > left && locationIter.hasNext()) {
122 location = locationIter.next();
123 var quantityForLocation : Int = location.quantityOnHand(stock_id, null);
124 if(quantityForLocation == null || quantityForLocation == 0) continue;
125 left += quantityForLocation;
126 formatLocation(location, "Delivery", left);
130 formatOrder(order, left, location.delivery);
133 // display the left locations
134 while(0 > left && locationIter.hasNext()) {
135 location = locationIter.next();
136 var quantityForLocation : Int = location.quantityOnHand(stock_id, null);
137 if(quantityForLocation == null || quantityForLocation == 0) continue;
138 left += quantityForLocation;
139 formatLocation(location, "Delivery", left);
144 function printRow(tds : Array<Dynamic>, attributes : Array<String>) {
145 php.Lib.print('<tr '+attributes.join(' ')+'>');
146 var position : Int = 1;
148 php.Lib.print('<td class="cell_'+position+'">');
149 if(td) php.Lib.print(td);
150 php.Lib.print('</td>');
153 php.Lib.print('</tr>');
156 static public function orderId(order) {
157 return 'order_'+order.id;
160 function formatOrder(order : Dynamic, left : Int, date : Date) {
161 var row_id = orderId(order);
162 var attributes = ['id = "'+row_id+'"'];
164 var before : Int = left + order.quantity;
165 /* We have basically 3 different cases;
166 * - the order can be fullfilled
167 * - the order can be partially
171 classes.push('soldout');
174 classes.push('partial');
177 classes.push('full');
180 /* The order can also be late if we need
181 * to wait for a delivery to get it
183 var required_by : Date = FA.sql2date(order.required_date);
184 if(required_by == null) required_by = FA.sql2date(order.delivery_date);
185 if(required_by.getTime() < date.getTime()) {
186 classes.push('late');
189 classes.push('on_time');
191 var cells : Array <Dynamic> = [
193 , '<a href="/modules/order_line_extra/order_lines_view.php?customer_id='+Std.string(order.debtor_no)+'">'+order.deliver_to+'</a>'
194 ,'<input type="text" name="'+row_id+'[quantity]" value="'+order.quantity+'">'
203 attributes.push('class="'+classes.join(' ')+'"');
204 printRow(cells, attributes);
208 function formatLocation(location : Location, type: String, left : Int) {
212 ,location.quantityOnHand(stock_id, null)
213 ,left-location.quantityOnHand(stock_id, null)
221 printRow(cells, ['class = "tableheader location"', 'id = "loc_'+location.code+'"']);
225 function schedules() {
226 //return orders()+locations();
228 return cast(locations(), Array<Dynamic>);
233 private function loadOrders() {
234 var tb : String = untyped __php__('TB_PREF');
235 var sql : String = "SELECT *
236 FROM "+tb+"denorm_order_details_queue d
237 JOIN "+tb+"sales_order_details od ON (od.id = d.id)
238 JOIN "+tb+"sales_orders so ON (so.order_no = d.order_id)
239 WHERE stock_id = '"+this.stock_id+"'
240 AND od.trans_type = 30
241 ORDER by d.priority";
243 return FA.query(sql);
246 function orders():Array<Order> {
247 var rows = loadOrders();
250 var order:Order = php.Lib.objectOfAssociativeArray(row);
251 orderList.push(order);
254 if(parameters != null) {
255 orderList.sort(function(a, b) { return parameters.priority(a)-parameters.priority(b); });
258 for(order in orderList) {
266 function locations() {
269 FROM '+TB+'locations';
271 for(row in FA.query(sql)) {
272 var location = new Location(row);
273 if(location.code == startLocation) {
274 location.delivery = Date.fromTime(0);
276 _locs.push(location);
284 function purcharseOrders() {
287 public function needsUpdate():Bool {
288 return parameters != null && parameters.mode == ScheduleMode.Move;