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