protected function makeGLTransactionLines($gl_data, &$gl_transactions, &$errors = array()) { $newerrors = array(); // EU Acquisitions only applies to Purchases $tax_status = DataObjectFactory::Factory('TaxStatus'); if ($tax_status->load($this->tax_status_id)) { $eu_acquisition = $tax_status->eu_tax == 't'; } else { $errors[] = 'Error getting Tax Status for the Invoice'; return FALSE; } if ($eu_acquisition) { $eu_gl_data = $gl_data; $eu_gl_data['value'] = 0; $eu_gl_data['twinvalue'] = 0; } // Get tax rates $tax_rate = DataObjectFactory::Factory('TaxRate'); $tax_rate->identifierField = 'percentage'; $tax_rates = $tax_rate->getAll(); $gl_params = DataObjectFactory::Factory('GLParams'); $accruals_control_account = $gl_params->accruals_control_account(); $balance_sheet_cost_centre = $gl_data['glcentre_id']; foreach ($this->lines as $line) { // Set common gl data for the line $line->makeGLTransactions($gl_data); if ($accruals_control_account) { // Need to check if there is a GRN for this line // and whether it is accrued and accrual accounting is enabled $poreceivedline = DataObjectFactory::Factory('POReceivedLine'); $poreceivedline->load($line->grn_id); if ($poreceivedline->isLoaded()) { if ($poreceivedline->net_value != $line->net_value) { // Invoice line value differs from received (quantity*price) value // Convert received line net value to base $base_net_value = $poreceivedline->net_value; if ($line->rate != 1) { // Convert to base value $base_net_value = round(bcmul($line->rate, $base_net_value, 4), 2); } $gl_data['base_net_value'] = bcsub($line->base_net_value, $base_net_value); // Need to get the twin value for this value $gl_data['twin_net_value'] = round(bcmul($line->twin_rate, $gl_data['base_net_value'], 4), 2); $original_comment = $gl_data['comment']; $gl_data['comment'] = $gl_data['comment'] . ' - Invoice Variance'; // Make the GL Transaction for the variance of the invoice line against GRN // The variance is posted to the invoice line GL Account/Centre $element = GLTransaction::makeCBLine($gl_data, $newerrors); if ($element !== FALSE) { $gl_transactions[] = $element; } else { $errors += $newerrors; return FALSE; } $gl_data['comment'] = $original_comment; $gl_data['base_net_value'] = $base_net_value; $gl_data['twin_net_value'] = $line->twin_net_value - $gl_data['twin_net_value']; } if ($poreceivedline->isAccrued()) { // The GRN has been accrued so need to post to the accruals control $gl_data['glaccount_id'] = $accruals_control_account; $gl_data['glcentre_id'] = $balance_sheet_cost_centre; } } } // Calculate tax value if EU acquisition if ($eu_acquisition && $line->tax_rate_id) { if (isset($tax_rates[$line->tax_rate_id]) && $tax_rates[$line->tax_rate_id] > 0) { $tax_rate_mult = 1 + $tax_rates[$line->tax_rate_id] / 100; $eu_gl_data['value'] += $line->base_net_value * $tax_rate_mult - $line->base_net_value; $eu_gl_data['twinvalue'] += $line->twin_net_value * $tax_rate_mult - $line->twin_net_value; } } // Make the GL Transaction for the invoice line $element = GLTransaction::makeCBLine($gl_data, $newerrors); if ($element !== FALSE) { $gl_transactions[] = $element; } else { $errors += $newerrors; return FALSE; } } if ($eu_acquisition) { $eu_tax_elements = GLTransaction::makeEuTax($eu_gl_data, $newerrors); foreach ($eu_tax_elements as $eu_tax_element) { if ($eu_tax_element === false) { $errors += $newerrors; return false; } $gl_transactions[] = $eu_tax_element; } } if (count($errors) > 0) { return FALSE; } else { return TRUE; } }
public static function makeFromLedgerTransaction(LedgerTransaction $transaction, Invoice $invoice, &$errors = array()) { $newerrors = array(); $db = DB::Instance(); $db->StartTrans(); // sort out the header details $gl_transactions = array(); $gl_data = array(); // the gl docref is the invoice number $gl_data['docref'] = $invoice->invoice_number; $gl_data['reference'] = $invoice->our_reference; // dates should be the same $gl_data['transaction_date'] = un_fix_date($invoice->invoice_date); // first character of class identifies source $gl_data['source'] = substr(strtoupper(get_class($transaction)), 0, 1); // type depends on Invoice or Credit Note $gl_data['type'] = $invoice->transaction_type; // the description is one from a number of bits of information // (description is compulsory for GL, but the options aren't for SLTransaction and SInvoice) $desc = $invoice->description; $ext_ref = $invoice->ext_reference; $sales_order_id = $invoice->sales_order_id; if (!empty($desc)) { $header_desc = $desc; } elseif (!empty($ext_ref)) { $header_desc = $ext_ref; } elseif (!empty($sales_order_id)) { $header_desc = $sales_order_id; } else { $header_desc = $invoice->invoice_number; } $gl_data['comment'] = $header_desc; // another docref $gl_data['docref2'] = $invoice->sales_order_id; // set the period based on invoice date $glperiod = GLPeriod::getPeriod($invoice->invoice_date); if (!$glperiod || count($glperiod) == 0) { $errors[] = 'No period exists for this date'; $db->FailTrans(); $db->CompleteTrans(); return false; } $gl_data['glperiods_id'] = $glperiod['id']; $gl_data['twin_currency_id'] = $invoice->twin_currency_id; $gl_data['twin_rate'] = $invoice->twin_rate; // there needs to be a tax element $gl_data['base_tax_value'] = $invoice->base_tax_value; $gl_data['twin_tax_value'] = $invoice->twin_tax_value; $vat_element = GLTransaction::makeCBTax($gl_data, $newerrors); if ($vat_element !== false) { $gl_transactions[] = $vat_element; } else { $db->FailTrans(); $db->CompleteTrans(); $errors += $newerrors; return false; } // EU acquisition? $eu_acquisition = false; if ($gl_data['source'] == 'P') { $tax_status = DataObjectFactory::Factory('TaxStatus'); if ($tax_status->load($invoice->tax_status_id)) { $eu_acquisition = $tax_status->eu_tax == 't'; } } $eu_gl_data = $gl_data; $eu_gl_data['value'] = 0; $eu_gl_data['twinvalue'] = 0; // this is the control element (used to balance the tax and lines) $gl_data['base_gross_value'] = $invoice->base_gross_value; $gl_data['twin_gross_value'] = $invoice->twin_gross_value; $control = self::getControlAccount($gl_data['source'], $errors); foreach ($control as $key => $value) { $gl_data[$key] = $value; } $control = GLTransaction::makeCBControl($gl_data, $newerrors); if ($control !== false) { $gl_transactions[] = $control; } else { $db->FailTrans(); $db->CompleteTrans(); $errors += $newerrors; return false; } // then do the invoice lines $lines = $invoice->lines; foreach ($lines as $line) { // provide some alternatives to get a comment $i_desc = $line->item_description; $desc = !empty($i_desc) ? $i_desc : $line->description; $desc = !empty($desc) ? $desc : ''; $gl_data['comment'] = $desc; $gl_data['glaccount_id'] = $line->glaccount_id; $gl_data['glcentre_id'] = $line->glcentre_id; $gl_data['base_net_value'] = $line->base_net_value; $gl_data['twin_net_value'] = $line->twin_net_value; // Calculate tax value if EU acquisition if ($eu_acquisition && $line->tax_rate_id) { $tax_rate = DataObjectFactory::Factory('TaxRate'); if ($tax_rate->load($line->tax_rate_id) && $tax_rate->percentage > 0) { $tax_rate_mult = 1 + $tax_rate->percentage / 100; $eu_gl_data['value'] += $line->base_net_value * $tax_rate_mult - $line->base_net_value; $eu_gl_data['twinvalue'] += $line->twin_net_value * $tax_rate_mult - $line->twin_net_value; } } $element = GLTransaction::makeCBLine($gl_data, $newerrors); if ($element !== false) { $gl_transactions[] = $element; } else { $db->FailTrans(); $db->CompleteTrans(); $errors += $newerrors; return false; } } if ($eu_acquisition) { $eu_tax_elements = GLTransaction::makeEuTax($eu_gl_data, $newerrors); foreach ($eu_tax_elements as $eu_tax_element) { if ($eu_tax_element === false) { $db->FailTrans(); $db->CompleteTrans(); $errors += $newerrors; return false; } $gl_transactions[] = $eu_tax_element; } } $db->CompleteTrans(); return $gl_transactions; }