示例#1
0
 function moveStock($whtransfer, &$errors)
 {
     $data = array();
     $data['stitem_id'] = $this->stitem_id;
     $data['whaction_id'] = $whtransfer->transfer_action;
     $data['process_name'] = 'T';
     $data['process_id'] = $whtransfer->id;
     $data['remarks'] = $this->remarks;
     $data['from_whlocation_id'] = $this->from_whlocation_id;
     $data['to_whlocation_id'] = $this->to_whlocation_id;
     $data['qty'] = $this->transfer_qty;
     $db = DB::Instance();
     $db->StartTrans();
     $transactions = array();
     $transactions = STTransaction::prepareMove($data, $errors);
     if (count($transactions) > 0 && count($errors) == 0) {
         foreach ($transactions as $transaction) {
             if (!$transaction->save($errors)) {
                 $errors[] = 'Error saving transaction';
                 break;
             }
         }
     }
     if (count($errors) > 0) {
         $db->FailTrans();
     } else {
         $db->CompleteTrans();
     }
 }
 public function save_transactions()
 {
     if (!$this->CheckParams('STTransaction')) {
         sendBack();
     }
     $flash = Flash::Instance();
     $db = DB::Instance();
     $db->StartTrans();
     $errors = array();
     $data = $this->_data['STTransaction'];
     $stitem = new STItem();
     $stitem->load($data['stitem_id']);
     $converted = round($data['qty'], $stitem->qty_decimals);
     if ($converted != $data['qty']) {
         $errors[] = 'Quantity can only have ' . $stitem->qty_decimals . ' decimal places';
     } elseif ($data['qty'] <= 0) {
         $errors[] = 'Quantity must be greater than zero';
     } else {
         $models = STTransaction::prepareMove($data, $errors);
         if (count($errors) == 0) {
             foreach ($models as $model) {
                 $result = $model->save($errors);
                 if ($result === false) {
                     $db->FailTrans();
                 }
             }
         }
     }
     if (count($errors) > 0) {
         $errors[] = 'Error transferring stock';
         $db->FailTrans();
         $db->CompleteTrans();
         $flash->addErrors($errors);
         $this->_data['whaction_id'] = $data['whaction_id'];
         $this->refresh();
         return;
     } else {
         $db->CompleteTrans();
         $flash->addMessage('Transfer completed successfully');
     }
     if (isset($this->_data['saveAnother'])) {
         $this->_data['whaction_id'] = $data['whaction_id'];
         $_POST[$this->modeltype]['qty'] = '';
         $_POST[$this->modeltype]['balance'] = '';
         $this->refresh();
     } else {
         sendTo($_SESSION['refererPage']['controller'], $_SESSION['refererPage']['action'], $_SESSION['refererPage']['modules'], isset($_SESSION['refererPage']['other']) ? $_SESSION['refererPage']['other'] : null);
     }
 }
 public function confirm_receipt()
 {
     if (!$this->CheckParams('POrderLine')) {
         sendBack();
     }
     $flash = Flash::Instance();
     $db = DB::Instance();
     $errors = array();
     $generator = new GoodsReceivedNumberHandler();
     $gr_note = $generator->handle(DataObjectFactory::Factory('POReceivedLine'));
     $data['gr_number'] = $gr_note;
     $lines_data = $this->_data['POrderLine'];
     $confirm_count = 0;
     foreach ($lines_data as $id => $line) {
         if (isset($line['confirm'])) {
             $confirm_count++;
             $db->StartTrans();
             $orderline = DataObjectFactory::Factory('POrderLine');
             $orderline->load($id);
             $del_qty = $line['received_qty'];
             $data = array();
             $data['id'] = $orderline->id;
             $data['os_qty'] = $orderline->os_qty - $del_qty;
             $data['del_qty'] = $orderline->del_qty + $del_qty;
             $data['actual_delivery_date'] = date(DATE_FORMAT);
             // Required for optimistic locking
             $data['lastupdated'] = $line['lastupdated'];
             if ($data['os_qty'] <= 0) {
                 $data['status'] = 'R';
                 $data['os_qty'] = 0;
             } else {
                 $data['status'] = 'P';
             }
             $updatedline = DataObject::Factory($data, $errors, 'POrderLine');
             if (count($errors) == 0 && $updatedline) {
                 $result = $updatedline->save();
             } else {
                 $result = false;
             }
             if ($result) {
                 $porder = DataObjectFactory::Factory('POrder');
                 $porder->load($updatedline->order_id);
                 $linestatuses = array();
                 if ($porder->isLoaded()) {
                     $linestatuses = $porder->getLineStatuses();
                     if ($porder->allLinesReceived($linestatuses)) {
                         $porder->status = 'R';
                     } elseif (!$porder->allLinesReceivedOrInvoiced($linestatuses)) {
                         $porder->status = 'P';
                     }
                     $result = $porder->save();
                 } else {
                     $result = false;
                 }
             }
             $data = array();
             $porder = DataObjectFactory::Factory('POrder');
             $porder->load($orderline->order_id);
             $data['gr_number'] = $gr_note;
             $data['order_id'] = $orderline->order_id;
             $data['plmaster_id'] = $porder->plmaster_id;
             $data['received_date'] = date(DATE_FORMAT);
             $data['received_qty'] = $del_qty;
             $data['currency'] = $orderline->currency;
             $data['net_value'] = bcmul($del_qty, $orderline->price);
             $data['orderline_id'] = $orderline->id;
             $data['stuom_id'] = $orderline->stuom_id;
             $data['stitem_id'] = $orderline->stitem_id;
             $data['productline_id'] = $orderline->productline_id;
             $data['item_description'] = $orderline->item_description;
             $data['tax_rate_id'] = $orderline->tax_rate_id;
             $data['status'] = 'R';
             $data['delivery_note'] = $this->_data['delivery_note'];
             $data['received_by'] = $line['received_by'];
             $stitem = DataObjectFactory::Factory('STItem');
             $stitem->load($data['stitem_id']);
             $param = DataObjectFactory::Factory('GLParams');
             $net_mass_uom_id = $param->intrastat_net_mass();
             if ($stitem->isLoaded() && !empty($net_mass_uom_id)) {
                 $data['net_mass'] = $stitem->convertToUoM($data['stuom_id'], $net_mass_uom_id, $data['received_qty']);
             }
             if (empty($data['net_mass']) || $data['net_mass'] === false) {
                 $data['net_mass'] = 0;
             }
             $receivedline = POReceivedLine::Factory($data, $errors, 'POReceivedLine');
             if (count($errors) > 0) {
                 $flash->addErrors($errors);
             }
             if (!$result || !$receivedline || !$receivedline->save()) {
                 $flash->addError('Error creating Goods Received Note ' . $gr_note);
                 $db->FailTrans();
                 $db->CompleteTrans();
                 sendBack();
             }
             if (is_null($orderline->stitem_id)) {
                 // Not stock item so no transactions to create, just do commit
                 $db->CompleteTrans();
             } else {
                 if (!empty($line['whaction_id'])) {
                     // Create transaction pair for Goods Received
                     // if the receipt is for a stock item
                     $data = array();
                     $data['process_name'] = 'GR';
                     $data['process_id'] = $gr_note;
                     $data['whaction_id'] = $line['whaction_id'];
                     $data['from_whlocation_id'] = $line['from_whlocation_id'];
                     $data['to_whlocation_id'] = $line['to_whlocation_id'];
                     $data['to_whbin_id'] = $line['to_whbin_id'];
                     $data['stitem_id'] = $orderline->stitem_id;
                     $data['qty'] = $del_qty;
                     if (!empty($data['stitem_id'])) {
                         $stitem = DataObjectFactory::Factory('STItem');
                         $stitem->load($data['stitem_id']);
                         if ($stitem) {
                             $data['qty'] = round($stitem->convertToUoM($orderline->stuom_id, $stitem->uom_id, $del_qty), $stitem->qty_decimals);
                         }
                     }
                     if ($del_qty <= 0) {
                         $errors[] = 'Delivered quantity must be greater than zero';
                     }
                     $models = STTransaction::prepareMove($data, $errors);
                     $result = false;
                     if (count($errors) === 0) {
                         foreach ($models as $model) {
                             $result = $model->save($errors);
                             if ($result === false) {
                                 break;
                             }
                         }
                     }
                     if (count($errors) > 0 || !$result) {
                         $flash->addErrors($errors);
                         $flash->addError('Error updating stock');
                         $db->FailTrans();
                         $db->CompleteTrans();
                         $this->refresh();
                     }
                 }
                 $db->CompleteTrans();
                 // Need to commit here so that any errors found in backflush
                 // can be written as transaction errors
                 $stitem = DataObjectFactory::Factory('STItem');
                 $stitem->load($orderline->stitem_id);
                 $data['book_qty'] = $del_qty;
                 MFStructure::backflush($data, $stitem->getChildStructures(), $errors);
             }
         }
     }
     if ($confirm_count == 0) {
         $errors[] = 'No Goods Recieved Notes Selected';
     }
     if (count($errors) === 0) {
         $flash->addWarning('GRN ' . $gr_note . ' created OK');
         $flash->addMessage('Goods Received confirmed OK');
         if (isset($this->_data['saveAnother'])) {
             sendTo($this->name, 'viewAwaitingDelivery', $this->_modules);
         }
         if (isset($this->_data['savePrintLabels'])) {
             sendTo($this->name, 'print_label', $this->_modules, array('gr_number' => $gr_note));
         }
         sendTo($this->name, 'index', $this->_modules);
     } else {
         $flash->addErrors($errors);
         $this->refresh();
     }
 }
示例#4
0
 private function moveStock(&$errors = array())
 {
     $customer = DataObjectFactory::Factory('SLCustomer');
     $customer = $customer->load($this->slmaster_id);
     if ($customer) {
         $stock_errors = false;
         foreach ($this->lines as $line) {
             if ($line->move_stock == 't' && !is_null($line->stitem_id)) {
                 $data = array();
                 if ($this->transaction_type == 'I') {
                     $data['qty'] = $line->sales_qty;
                     $data['process_name'] = 'SI';
                 } else {
                     // Reverse the transaction for a Credit Note
                     $data['qty'] = bcmul($line->sales_qty, -1);
                     $data['process_name'] = 'S' . $this->transaction_type;
                 }
                 $data['process_id'] = $this->id;
                 $data['stitem_id'] = $line->stitem_id;
                 if (is_null($line->sales_order_id)) {
                     $data['whaction_id'] = $customer->despatch_action;
                 } else {
                     $sorder = DataObjectFactory::Factory('SOrder');
                     $sorder->load($line->sales_order_id);
                     $data['whaction_id'] = $sorder->despatch_action;
                 }
                 $result = false;
                 if (STTransaction::getTransferLocations($data, $errors)) {
                     $st_errors = array();
                     $models = STTransaction::prepareMove($data, $st_errors);
                     if (count($st_errors) === 0) {
                         foreach ($models as $model) {
                             $result = $model->save($st_errors);
                             if ($result === false) {
                                 $stock_errors = true;
                             }
                         }
                     }
                     if (count($st_errors) > 0) {
                         $errors = array_merge($errors, $st_errors);
                     }
                 } else {
                     $errors[] = 'Error getting transfer locations';
                     return false;
                 }
             }
         }
         if ($stock_errors) {
             $errors[] = 'Error updating stock';
             return false;
         }
         return true;
     }
     $errors[] = 'Failed to load Customer details';
     return false;
 }
示例#5
0
 public function updatewip()
 {
     if (!$this->loadData()) {
         $this->dataError();
         sendBack();
     }
     $worksorder = $this->_uses[$this->modeltype];
     $flash = Flash::Instance();
     $errors = array();
     $data = $this->_data[$this->modeltype];
     $id = $data['id'];
     $stitem_id = $data['stitem_id'];
     // Insert transaction pair for WIP Update
     $data['qty'] = $data['book_qty'];
     $data['process_name'] = 'WO';
     $data['process_id'] = $id;
     $db = DB::Instance();
     $db->StartTrans();
     if ($data['qty'] > 0) {
         $models = STTransaction::prepareMove($data, $errors);
     } else {
         $errors[] = 'Quantity must be greater than zero';
     }
     if (count($errors) == 0) {
         foreach ($models as $model) {
             if (!$model->save($errors)) {
                 $errors[] = 'Error transferring stock';
                 break;
             }
         }
     }
     if (count($errors) == 0) {
         $worksorder->status = 'O';
         $worksorder->made_qty = bcadd($worksorder->made_qty, trim($data['book_qty']), 0);
         if (!$worksorder->save()) {
             $errors[] = 'Error updating Works Order';
         }
     }
     if (count($errors) > 0) {
         $db->FailTrans();
     }
     $db->CompleteTrans();
     // If all OK, do backflush; this has to be outside of the above transaction
     // because backflushing can fail, but this is OK as it is handled separately
     if (count($errors) == 0) {
         if (MFStructure::backflush($data, $worksorder->structureitems, $errors)) {
             $flash->addMessage('Transfer completed successfully');
             $flash->addMessage('Works Order Updated');
             if ($worksorder->made_qty >= $worksorder->order_qty) {
                 $flash->addMessage('Order Quantity has been fulfilled');
             }
             sendTo($_SESSION['refererPage']['controller'], $_SESSION['refererPage']['action'], $_SESSION['refererPage']['modules'], isset($_SESSION['refererPage']['other']) ? $_SESSION['refererPage']['other'] : null);
         } else {
             $errors[] = 'Serious error trying to backflush - PLEASE REPORT IMMEDIATELY';
         }
     }
     $errors[] = 'Error booking production';
     $debug = Debug::Instance();
     $body = "MfworkordersController::updatewip\n" . "at " . date(DATE_TIME_FORMAT) . "\n\n" . "User               " . EGS_USERNAME . "\n" . "Works Order Id     " . $worksorder->id . "\n" . "Works Order Number " . $worksorder->wo_number . "\n" . "Stock Item Id      " . $worksorder->stitem_id . "\n" . "Booking Qty        " . $data['book_qty'] . "\n\n";
     foreach ($errors as $error) {
         $body .= $error . "\n";
     }
     $subject = get_config('SYSTEM_STATUS');
     $subject = !empty($subject) ? $subject : 'system';
     system_email($subject . ' Error', $body);
     $flash->addErrors($errors);
     sendTo($this->name, 'bookproduction', $this->_modules, array('id' => $id, 'stitem_id' => $stitem_id));
 }
 public function confirm_despatch()
 {
     if (!$this->checkParams('SODespatchLine')) {
         sendBack();
     }
     $flash = Flash::Instance();
     $db = DB::Instance();
     $db->StartTrans();
     $errors = array();
     foreach ($this->_data['SODespatchLine'] as $key => $value) {
         if (isset($value['confirm_despatch'])) {
             // Check Customer
             if (!isset($value['slmaster_id'])) {
                 $errors['DN' . $key] = 'Cannot find Customer reference for DN' . $key;
                 $db->FailTrans();
                 continue;
             }
             $customer = DataObjectFactory::Factory('SLCustomer');
             $customer->load($value['slmaster_id']);
             if (!$customer->isLoaded()) {
                 $errors['DN' . $key] = 'Cannot find Customer details for DN' . $key;
                 $db->FailTrans();
                 continue;
             } elseif ($customer->accountStopped()) {
                 $errors['DN' . $key] = 'Cannot Confirm Despatch for DN' . $key . ' (' . $customer->name . ') Account Stopped';
                 $db->FailTrans();
                 continue;
             }
             // Get all the despatch lines for this Despatch Note
             $despatches = new SODespatchLineCollection($this->_templateobject);
             $sh = new SearchHandler($despatches, false);
             $sh->addConstraint(new Constraint('despatch_number', '=', $key));
             $despatches->load($sh);
             foreach ($despatches as $despatch) {
                 if ($despatch->stitem_id != '') {
                     // Create transaction pair for Dispatch
                     $data = array();
                     $data['qty'] = $despatch->despatch_qty;
                     $data['process_name'] = 'D';
                     $data['process_id'] = $despatch->despatch_number;
                     $data['whaction_id'] = $despatch->despatch_action;
                     $data['stitem_id'] = $despatch->stitem_id;
                     $result = false;
                     if (STTransaction::getTransferLocations($data, $errors)) {
                         $models = STTransaction::prepareMove($data, $errors);
                         if (count($errors) === 0) {
                             foreach ($models as $model) {
                                 $result = $model->save($errors);
                                 if ($result === false) {
                                     break;
                                 }
                             }
                         }
                     }
                     if ($result === false) {
                         $flash->addErrors($errors);
                         $flash->addError('Error updating stock');
                         $db->FailTrans();
                         sendBack();
                     }
                 }
                 $despatchline = DataObjectFactory::Factory('SODespatchLine');
                 $result = $despatchline->update($despatch->id, 'status', 'D');
                 if ($result === false) {
                     $flash->addError('Error updating Despatch Note ' . $despatch_note);
                     $db->FailTrans();
                     sendBack();
                 }
                 $orderline = DataObjectFactory::Factory('SOrderLine');
                 $orderline->load($despatch->orderline_id);
                 $data = array();
                 $data['id'] = $despatch->orderline_id;
                 $data['os_qty'] = $orderline->os_qty - $despatch->despatch_qty;
                 $data['del_qty'] = $despatch->despatch_qty;
                 $data['actual_despatch_date'] = date(DATE_FORMAT);
                 $data['status'] = 'D';
                 $orderline = DataObject::Factory($data, $errors, 'SOrderLine');
                 if ($orderline) {
                     $result = $orderline->save();
                 } else {
                     $result = false;
                 }
                 if ($result === false) {
                     $flash->addError('Error updating order line ' . $db->ErrorMsg());
                     $db->FailTrans();
                     sendBack();
                 }
                 $order = DataObjectFactory::Factory('SOrder');
                 if ($order->load($orderline->order_id)) {
                     if (!$order->save()) {
                         $flash->addError('Error updating order ' . $db->ErrorMsg());
                         $db->FailTrans();
                         sendBack();
                     }
                 }
             }
         }
     }
     if (count($errors) === 0 && $db->CompleteTrans()) {
         $flash->addMessage('Despatches confirmed');
         sendTo($this->name, 'index', $this->_modules);
     } else {
         $flash->addErrors($errors);
         $db->FailTrans();
         sendBack();
     }
 }
示例#7
0
 public function save_unpick_list()
 {
     if (!isset($this->_data) || !$this->loadData()) {
         $this->dataError();
         sendBack();
     }
     $sorder = $this->_uses[$this->modeltype];
     $sorder_data = $this->_data[$this->modeltype];
     $sorderline_data = $this->_data['SOrderLine'];
     $flash = Flash::Instance();
     $errors = array();
     $db = DB::Instance();
     $db->startTrans();
     // The value of the $sorder_data[to_location_id] is the whtransfer_rule_id
     // so get the location_ids for the rule_list - note it is the from_location
     // because we are transferring into the location from which the goods
     // will be invoiced/despatched
     $location_ids = $sorder->despatch_from->rules_list('from_whlocation_id');
     $next_line_number = $sorder->getNextLineNumber();
     if (isset($sorderline_data)) {
         foreach ($sorderline_data as $key => $value) {
             if (!isset($value['id'])) {
                 continue;
             }
             $sorderline = DataObjectFactory::Factory('SOrderLine');
             $sorderline->load($key);
             if (!$sorderline) {
                 $errors[] = 'Failed to get order line';
                 break;
             }
             if ($sorderline->revised_qty < $value['del_qty']) {
                 $errors[] = 'Trying to unpick more than was picked!';
                 break;
             } elseif ($sorderline->revised_qty > $value['del_qty']) {
                 $data = array();
                 foreach ($sorderline->getFields() as $field) {
                     if ($field->type == 'date' && $field->value != '') {
                         $data[$field->name] = un_fix_date($field->value);
                     } else {
                         $data[$field->name] = $field->value;
                     }
                 }
                 $data['line_number'] = $next_line_number;
                 $next_line_number++;
                 unset($data['id']);
                 $data['status'] = $sorderline->newStatus();
                 $data['os_qty'] = $data['revised_qty'] = $data['order_qty'] = $value['del_qty'];
                 $data['net_value'] = round(bcmul($data['revised_qty'], $data['price'], 4), 2);
                 $data['twin_currency_id'] = $sorderline->twin_currency_id;
                 $data['twin_rate'] = $sorderline->twin_rate;
                 $data['base_net_value'] = round(bcdiv($data['net_value'], $data['rate'], 4), 2);
                 $data['twin_net_value'] = round(bcmul($data['base_net_value'], $data['twin_rate'], 4), 2);
                 $neworderline = SOrderLine::Factory($sorder, $data, $errors);
                 if (count($errors) > 0 || !$neworderline || !$neworderline->save()) {
                     $errors[] = 'Failed to unpick required amount';
                 } else {
                     $sorderline->os_qty = $sorderline->order_qty = $sorderline->revised_qty = $sorderline->revised_qty - $value['del_qty'];
                     $sorder->net_value = bcsub($sorder->net_value, $sorderline->net_value);
                     $sorder->base_net_value = bcsub($sorder->base_net_value, $sorderline->base_net_value);
                     $sorder->twin_net_value = bcsub($sorder->twin_net_value, $sorderline->twin_net_value);
                     $sorderline->net_value = round(bcmul($sorderline->revised_qty, $sorderline->price, 4), 2);
                     $sorderline->base_net_value = round(bcdiv($sorderline->net_value, $sorderline->rate, 4), 2);
                     $sorderline->twin_net_value = round(bcmul($sorderline->base_net_value, $sorderline->twin_rate, 4), 2);
                     $sorder->net_value = bcadd($sorder->net_value, $sorderline->net_value);
                     $sorder->base_net_value = bcadd($sorder->base_net_value, $sorderline->base_net_value);
                     $sorder->twin_net_value = bcadd($sorder->twin_net_value, $sorderline->twin_net_value);
                 }
             } else {
                 // $sorderline->os_qty+=$value['del_qty'];
                 $sorderline->status = $sorderline->newStatus();
             }
             if (!$sorderline->save()) {
                 $errors[] = 'Failed to unpick item ';
                 break;
             }
             if (!is_null($sorderline->stitem_id)) {
                 if (!empty($value['whlocation_id']) && !empty($sorder_data['from_location_id'])) {
                     $data = array();
                     $data['stitem_id'] = $sorderline->stitem_id;
                     $data['qty'] = $value['del_qty'];
                     $data['process_name'] = 'SO';
                     $data['process_id'] = $sorderline->order_id;
                     $data['whaction_id'] = '';
                     if ($value['whlocation_id'] == $location_ids[$sorder_data['from_location_id']]) {
                         $errors['whlocation_id'] = 'Cannot transfer from/to the same location';
                         break;
                     }
                     $data['to_whlocation_id'] = $value['whlocation_id'];
                     $data['from_whlocation_id'] = $location_ids[$sorder_data['from_location_id']];
                     $models = STTransaction::prepareMove($data, $errors);
                     if (count($errors) == 0) {
                         foreach ($models as $model) {
                             if (!$model || !$model->save($errors)) {
                                 $errors[] = 'Error updating stock';
                                 break;
                             }
                         }
                     }
                 } else {
                     $errors[] = 'Cannot move stock - missing location';
                 }
             }
             // Save header to update status/values
             if (count($errors) == 0 && !$sorder->save()) {
                 $errors[] = 'Failed to unpick item ';
                 break;
             }
         }
     } else {
         $errors[] = 'No lines confirmed';
     }
     if (count($errors) > 0) {
         $flash->addErrors($errors);
         $db->FailTrans();
         $db->CompleteTrans();
         $this->refresh();
     } else {
         $flash->addMessage('Unpick action successfully completed');
         $db->CompleteTrans();
         sendTo($this->name, 'view', $this->_modules, array('id' => $sorder->id));
     }
 }
示例#8
0
 static function backflush($data, $elements, &$errors)
 {
     $db = DB::Instance();
     //$db->StartTrans();
     $success = true;
     // Get the required action for the Item if enabled on Item Product Type
     $stitem = DataObjectFactory::Factory('STItem');
     if ($stitem->load($data['stitem_id'])) {
         // TODO: need a check to ensure that there is only one transfer rule for action
         $staction = $stitem->getAction('backflush');
         if (!is_null($staction)) {
             // Get the transfer rule for the action
             $data['whaction_id'] = $staction;
             $transrule = DataObjectFactory::Factory('WHTransferrule');
             $cc = new ConstraintChain();
             $cc->add(new Constraint('whaction_id', '=', $staction));
             $transrule->loadBy($cc);
             foreach ($elements as $structure) {
                 // Insert transaction pair for WIP Update
                 $data['from_whlocation_id'] = $transrule->from_whlocation_id;
                 $data['to_whlocation_id'] = $transrule->to_whlocation_id;
                 // Currently cannot define bins for backflushing
                 $data['from_whbin_id'] = '';
                 $data['to_whbin_id'] = '';
                 // Calculate the quantity used of the sub-component
                 $data['qty'] = $data['book_qty'] * $structure->qty * 100 / (100 - $structure->waste_pc);
                 $data['stitem_id'] = $structure->ststructure_id;
                 // Status is initially OK
                 $data['status'] = 'O';
                 $stitem = DataObjectFactory::Factory('STItem');
                 if ($stitem->load($structure->ststructure_id)) {
                     $converted = $stitem->convertToUoM($structure->uom_id, $stitem->uom_id, $data['qty']);
                     if ($converted === false) {
                         $errors[] = 'UoM Conversion Error on item ' . $stitem->item_code . ' - ' . $stitem->description;
                     } else {
                         // Validate the data
                         $data['qty'] = round($converted, $stitem->qty_decimals);
                         $models = STTransaction::prepareMove($data, $errors);
                     }
                 } else {
                     $errors[] = 'Cannot find structure Item';
                 }
                 // If errors occurred creating transaction pair then exit loop
                 if (count($errors) > 0) {
                     $success = false;
                     break;
                 }
                 // Save transaction pair
                 $success = true;
                 $db->StartTrans();
                 foreach ($models as $model) {
                     $ignored_errors = array();
                     // If transaction was saved then go to next transaction
                     if ($model->save($ignored_errors) !== false) {
                         continue;
                     }
                     // Error saving transaction
                     $success = false;
                     $db->FailTrans();
                     break;
                 }
                 $db->CompleteTrans();
                 // If transactions were saved then go to next transaction pair
                 if ($success) {
                     continue;
                 }
                 // Save transaction pair with error status
                 $success = true;
                 $db->StartTrans();
                 foreach ($models as $model) {
                     $model->error_qty = $model->qty;
                     $model->qty = 0;
                     $model->status = 'E';
                     // If transaction was saved then go to next transaction
                     if ($model->save($errors) !== false) {
                         continue;
                     }
                     // Error saving transaction
                     $success = false;
                     $db->FailTrans();
                     break;
                 }
                 $db->CompleteTrans();
                 // If errors occurred saving transaction pairs then exit loop
                 if (!$success) {
                     break;
                 }
             }
         }
     } else {
         $errors[] = 'Cannot find stock item';
         $success = false;
     }
     return $success;
     //return $db->completeTrans();
 }