public function save($pay_data, &$errors) { $db = DB::Instance(); $db->StartTrans(); // Save the Payment Header if (!parent::save()) { $errors[] = 'Failed to save Payment Header'; $db->FailTrans(); return false; } $flash = Flash::Instance(); // Validate and write purchase ledger, cashbook and general ledger transactions $progressbar = new progressBar('creating_pl_transactions'); $payment_id = $this->id; $callback = function ($data, $key) use(&$pay_data, &$errors, $payment_id) { $data['cb_account_id'] = $pay_data['cb_account_id']; $data['reference'] = $pay_data['reference']; $data['cross_ref'] = $data['ext_reference'] = $payment_id; $data['description'] = $pay_data['description']; $data['transaction_type'] = 'P'; $data['transaction_date'] = $pay_data['transaction_date']; $data['source'] = $pay_data['source']; $supplier = DataObjectFactory::Factory('PLSupplier'); $supplier->load($data['plmaster_id']); $data['payment_term_id'] = $supplier->payment_term_id; if (PLTransaction::saveTransaction($data, $errors) === false) { $errors[] = 'Failed to save payments'; return false; } $pay_data['PLTransaction'][$key]['ledger_transaction_id'] = $data['ledger_transaction_id']; }; if ($progressbar->process($pay_data['PLTransaction'], $callback) === FALSE) { $db->FailTrans(); $db->CompleteTrans(); return FALSE; } // Match and update purchase ledger payments $payment_total = 0; $progressbar = new progressBar('allocate_payments'); $callback = function ($data, $key) use(&$pay_data, &$errors, $payment_id, &$payment_total) { $db = DB::Instance(); // Get the payment transaction and update it to paid $pltransaction = DataObjectFactory::Factory('PLTransaction'); $pltransaction->load($data['ledger_transaction_id']); if (!$pltransaction->update($pltransaction->id, array('status', 'os_value', 'twin_os_value', 'base_os_value'), array('P', '0.00', '0.00', '0.00'))) { $errors[] = 'Error updating payment status : ' . $db->ErrorMsg(); return false; } // get all the transactions linked for payment to the payment transaction $pltransactions = new PLTransactionCollection(DataObjectFactory::Factory('PLTransaction'), 'pl_allocation_overview'); $pltransactions->getPaid($data); // the allocation amount is the gross payment value $allocations = array($pltransaction->id => $pltransaction->gross_value); $trans_total = 0; $trans_base_total = $pltransaction->base_gross_value; foreach ($pltransactions as $trans) { // now mark all the linked transactions as paid // update the invoices linked to thes transactions as paid $trans_total = bcadd($trans->gross_value, $trans_total); $trans_base_total = bcadd($trans->base_gross_value, $trans_base_total); if (!$trans->update($trans->id, array('status', 'for_payment', 'os_value', 'twin_os_value', 'base_os_value'), array($trans->Paid(), false, '0.00', '0.00', '0.00'))) { $errors[] = 'Error updating transaction status : ' . $db->ErrorMsg(); return false; } if ($trans->transaction_type == 'C' || $trans->transaction_type == 'I') { $invoice = DataObjectFactory::Factory('PInvoice'); if (!$invoice->updateStatus($trans->our_reference, 'P')) { $errors[] = 'Error updating Invoice : ' . $db->ErrorMsg(); return false; } } $allocations[$trans->id] = $trans->gross_value; // Save settlement discount if present? if ($trans->settlement_discount > 0 && $trans->include_discount == 't') { // Create GL Journal for settlement discount $discount = array(); $discount['gross_value'] = $discount['net_value'] = $trans->settlement_discount; $discount['glaccount_id'] = $trans->pl_discount_glaccount_id; $discount['glcentre_id'] = $trans->pl_discount_glcentre_id; $discount['transaction_date'] = date(DATE_FORMAT); $discount['tax_value'] = '0.00'; $discount['source'] = 'P'; $discount['transaction_type'] = 'SD'; $discount['our_reference'] = $trans->our_reference; $discount['ext_reference'] = $trans->ext_reference; $discount['currency_id'] = $trans->currency_id; $discount['rate'] = $trans->rate; $discount['description'] = !is_null($trans->pl_discount_description) ? $trans->pl_discount_description . ' ' : ''; $discount['description'] .= !is_null($trans->description) ? $trans->description : $trans->ext_reference; $discount['payment_term_id'] = $trans->payment_term_id; $discount['plmaster_id'] = $trans->plmaster_id; $discount['status'] = 'P'; $pldiscount = PLTransaction::Factory($discount, $errors, 'PLTransaction'); if ($pldiscount && $pldiscount->save('', $errors) && $pldiscount->saveGLTransaction($discount, $errors)) { $allocations[$pldiscount->{$pldiscount->idField}] = bcadd($discount['net_value'], 0); $trans_total = bcadd($trans_total, $pldiscount->gross_value); $trans_base_total = bcadd($trans_base_total, $pldiscount->base_gross_value); } else { $errors[] = 'Errror saving PL Transaction Discount : ' . $db->ErrorMsg(); } } } if ($data['net_value'] != $pltransaction->gross_value * -1 || $data['net_value'] != $trans_total) { $errors[] = 'Transaction Payment mismatch ' . $data['net_value'] . ' ' . $pltransaction->gross_value * -1 . ' ' . $trans_total . ' for ' . $trans->supplier; return false; } // save the allocations if (!PLAllocation::saveAllocation($allocations, $payment_id, $errors)) { return false; } if ($trans_base_total != 0) { $adj_data = array(); $errors = array(); $adj_data['docref'] = $pltransaction->plmaster_id; $adj_data['original_source'] = 'P'; $adj_data['reference'] = ''; $adj_data['value'] = $trans_base_total * -1; $adj_data['comment'] = 'Purchase Allocation Currency Adjustment'; if (!GLTransaction::currencyAdjustment($adj_data, $errors)) { return false; } } $payment_total = bcadd($payment_total, $trans_total); }; if ($progressbar->process($pay_data['PLTransaction'], $callback) === FALSE) { $db->FailTrans(); $db->CompleteTrans(); return FALSE; } if ($payment_total != $pay_data['payment_total']) { $errors[] = 'Payment Mismatch - Total ' . $pay_data['payment_total'] . ' not equal sum Transaction Payments ' . $payment_total; $db->FailTrans(); $db->CompleteTrans(); return false; } return $db->CompleteTrans(); }
public function save_contras() { if (!$this->loadData()) { $this->dataError(); sendBack(); } $db = DB::Instance(); $db->StartTrans(); $flash = Flash::Instance(); $errors = array(); $transactions = array(); $contras_sessionobject = new SessionData('pl_contras'); foreach ($this->_data['PLTransaction'] as $id => $data) { $data['contra'] = isset($data['contra']) && $data['contra'] == 'on'; $contras_sessionobject->updatePageData($id, $data, $errors); } $contra_total = isset($this->_data['contra_total']) ? $this->_data['contra_total'] : '0.00'; $contra_sum = 0; foreach ($contras_sessionobject->getPageData($errors) as $id => $data) { if (isset($data['contra']) && $data['contra'] == 'on') { // using bcadd to format value $transactions[$id] = bcadd($data['os_value'], 0); $contra_sum = bcadd($contra_sum, $data['os_value']); } } if (count($transactions) == 0) { $errors[] = 'You must select at least one transaction'; } elseif ($contra_total == $contra_sum) { $pl_journal_seq = $db->GenID('pl_journals_id_seq'); $sl_journal_seq = $db->GenID('sl_journals_id_seq'); // Create the PL and SL contra journals $pltransaction = DataObjectFactory::Factory('PLTransaction'); $pltransaction->load($id); $plcontra = array(); $plcontra['gross_value'] = $plcontra['net_value'] = bcmul($contra_sum, -1); $glparams = DataObjectFactory::Factory('GLParams'); $plcontra['glaccount_id'] = $glparams->contras_control_account(); $plcontra['glcentre_id'] = $glparams->balance_sheet_cost_centre(); $plcontra['transaction_date'] = date(DATE_FORMAT); $plcontra['tax_value'] = '0.00'; $plcontra['source'] = 'P'; $plcontra['transaction_type'] = 'J'; $plcontra['our_reference'] = $pl_journal_seq; $plcontra['currency_id'] = $this->_data['PLSupplier']['currency_id']; $plcontra['rate'] = $this->_data['PLSupplier']['rate']; $plcontra['payment_term_id'] = $this->_data['PLSupplier']['payment_term_id']; $slcontra = $plcontra; $plcontra['plmaster_id'] = $this->_data['PLSupplier']['id']; $plcontra['description'] = 'Contra Purchase Ledger - SL Ref:' . $sl_journal_seq; $pltrans = PLTransaction::Factory($plcontra, $errors, 'PLTransaction'); if ($pltrans && $pltrans->save('', $errors) && $pltrans->saveGLTransaction($plcontra, $errors)) { $transactions[$pltrans->{$pltrans->idField}] = bcadd($plcontra['net_value'], 0); } else { $errors[] = 'Errror saving PL Transaction Contra : ' . $db->ErrorMsg(); $flash->addErrors($errors); } $slcontra['source'] = 'S'; $slcontra['our_reference'] = $sl_journal_seq; $slcontra['description'] = 'Contra Sales Ledger - PL Ref:' . $pl_journal_seq; $slcontra['gross_value'] = $slcontra['net_value'] = bcmul($contra_sum, -1); $customer = DataObjectFactory::Factory('SLCustomer'); $customer->loadBy('company_id', $this->_data['PLSupplier']['company_id']); if ($customer->isLoaded()) { $slcontra['slmaster_id'] = $customer->{$customer->idField}; $sltrans = SLTransaction::Factory($slcontra, $errors, 'SLTransaction'); } else { $sltrans = FALSE; } if (!$sltrans || !$sltrans->save('', $errors) || !$sltrans->saveGLTransaction($slcontra, $errors)) { $errors[] = 'Errror saving SL Transaction Contra : ' . $db->ErrorMsg(); $flash->addErrors($errors); } } else { $errors[] = 'Transactions sum mismatch Sum: ' . $contra_sum . ' Control Total: ' . $contra_total; } if (count($errors) > 0 || !PLTransaction::allocatePayment($transactions, $this->_data['id'], $errors) || !PLAllocation::saveAllocation($transactions, null, $errors)) { $db->FailTrans(); } if ($db->CompleteTrans()) { $contras_sessionobject->clear(); $flash->addMessage('Contra Transactions matched'); sendTo($this->name, 'view', $this->_modules, array('id' => $this->_data['id'])); } $flash->addErrors($errors); $this->outstanding_transactions(); }