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();
     }
 }
 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));
 }