protected function _execute() { if (!$this->_sale->loaded()) { throw new Exception("Sale could not be found."); } if ($this->_sale->date_cancelled || $this->_sale->cancel_transaction_id) { throw new Exception("Sale could not be deleted - it has already been cancelled."); } // There's a unique use-case that's hard to replicate, but it produces a form that // has no create_transaction - closing the FYE with this form can be frustrating to deal with otherwise. if ($this->_check_books_closed($this->_sale->date_created) && $this->_sale->create_transaction_id && $this->_sale->invoice_transaction_id && $this->_sale->cancel_transaction_id) { throw new Exception("Sale could not be deleted. The financial year has been closed already."); } if ($this->_sale->refund_form_id and $this->_sale->refund_form_id > $this->_sale->id) { throw new Exception("Sale could not be deleted - it has a refund attached to it."); } if ($this->_sale->date_billed || $this->_sale->invoice_transaction_id) { throw new Exception("A sale cannot be deleted after it has been converted to an invoice."); } $transfer_transactions = FALSE; foreach ($this->_sale->account_transaction_forms->find_all() as $account_transaction_form) { if ($account_transaction_form->account_transaction->transaction->payment) { $transfer_transactions = TRUE; } } if ($transfer_transactions) { throw new Exception("A sale cannot be deleted after it has had a payment recorded to it. You can, however, cancel it."); } // Delete the Create Transaction. if ($this->_sale->create_transaction->loaded()) { $account_transaction_delete = new Beans_Account_Transaction_Delete($this->_beans_data_auth((object) array('id' => $this->_sale->create_transaction_id, 'form_type_handled' => 'sale'))); $account_transaction_delete_result = $account_transaction_delete->execute(); if (!$account_transaction_delete_result->success) { throw new Exception("Error deleting account transaction: " . $account_transaction_delete_result->error); } } foreach ($this->_sale->form_lines->find_all() as $sale_line) { $sale_line->delete(); } foreach ($this->_sale->form_taxes->find_all() as $sale_tax) { $sale_tax->delete(); } // If this is a refund for another SO, then we make sure to remove the reference to this form. if ($this->_sale->refund_form->loaded()) { $this->_sale->refund_form->refund_form_id = NULL; $this->_sale->refund_form->save(); } $this->_sale->delete(); return (object) array(); }
protected function _execute() { if (!$this->_purchase->loaded()) { throw new Exception("Purchase purchase could not be found."); } // There's a unique use-case that's hard to replicate, but it produces a form that // has no create_transaction - closing the FYE with this form can be frustrating to deal with otherwise. if ($this->_check_books_closed($this->_purchase->date_created) && $this->_purchase->create_transaction_id && $this->_purchase->invoice_transaction_id && $this->_purchase->cancel_transaction_id) { throw new Exception("Purchase purchase could not be deleted. The financial year has been closed already."); } if ($this->_purchase->date_cancelled) { throw new Exception("A purchase cannot be deleted after it has been cancelled."); } if ($this->_purchase->date_billed or $this->_purchase->invoice_transaction_id) { throw new Exception("Purchase cannot be deleted after it has been converted to an invoice."); } if ($this->_purchase->refund_form_id and $this->_purchase->refund_form_id > $this->_purchase->id) { throw new Exception("Purchase could not be deleted - it has a refund attached to it."); } // Determine if this purchase has a payment attached to it. // This is slow - but it's easy to read and understand. // A giant query wouldn't solve that much more probably. foreach ($this->_purchase->account_transaction_forms->find_all() as $account_transaction_form) { if ($account_transaction_form->account_transaction->transaction->payment) { throw new Exception("Purchase could not be deleted because there are payments attached to it. Are you trying to create a refund?"); } } // Cancel Transaction. if ($this->_purchase->create_transaction_id) { $account_transaction_delete = new Beans_Account_Transaction_Delete($this->_beans_data_auth((object) array('id' => $this->_purchase->create_transaction_id, 'form_type_handled' => 'purchase'))); $account_transaction_delete_result = $account_transaction_delete->execute(); if (!$account_transaction_delete_result->success) { throw new Exception("Error cancelling account transaction: " . $account_transaction_delete_result->error); } $this->_purchase->create_transaction_id = NULL; } foreach ($this->_purchase->form_lines->find_all() as $purchase_line) { $purchase_line->delete(); } // Remove the refund form from the corresponding form. if ($this->_purchase->refund_form->loaded()) { $this->_purchase->refund_form->refund_form_id = NULL; $this->_purchase->refund_form->save(); } $this->_purchase->delete(); return (object) array(); }
protected function _execute() { if (!$this->_payment->loaded()) { throw new Exception("Payment could not be found."); } $account_transaction_delete = new Beans_Account_Transaction_Delete($this->_beans_data_auth((object) array('id' => $this->_payment->transaction->id, 'payment_type_handled' => 'tax'))); $account_transaction_delete_result = $account_transaction_delete->execute(); if (!$account_transaction_delete_result->success) { throw new Exception("Error cancelling tax payment: " . $account_transaction_delete_result->error); } // Update tax $this->_tax_payment_update_balance($this->_payment->tax_id); $paid_tax_items = ORM::Factory('tax_item')->where('tax_payment_id', '=', $this->_payment->id)->find_all(); foreach ($paid_tax_items as $paid_tax_item) { $paid_tax_item->tax_payment_id = NULL; $paid_tax_item->save(); } $this->_payment->delete(); return (object) array(); }
protected function _execute() { if (!$this->_payment->loaded()) { throw new Exception("Payment could not be found."); } $form_ids_query = ' SELECT DISTINCT(account_transaction_forms.form_id) as form_id FROM account_transaction_forms ' . ' INNER JOIN account_transactions ON account_transaction_forms.account_transaction_id = account_transactions.id WHERE ' . ' account_transactions.transaction_id = ' . $this->_payment->id; $form_ids = DB::Query(Database::SELECT, $form_ids_query)->execute()->as_array(); $handled_purchase_ids = array(); foreach ($form_ids as $form_id) { $handled_purchase_ids[] = $form_id['form_id']; } $payment_date = $this->_payment->date; $payment_id = $this->_payment->id; $account_transaction_delete = new Beans_Account_Transaction_Delete($this->_beans_data_auth((object) array('id' => $this->_payment->id, 'payment_type_handled' => 'vendor'))); $account_transaction_delete_result = $account_transaction_delete->execute(); if (!$account_transaction_delete_result->success) { throw new Exception("Error cancelling payment: " . $account_transaction_delete_result->error); } // Recalibrate Vendor Invoices / Cancellations $vendor_purchase_calibrate_invoice = new Beans_Vendor_Purchase_Calibrate_Invoice($this->_beans_data_auth((object) array('ids' => $handled_purchase_ids))); $vendor_purchase_calibrate_invoice_result = $vendor_purchase_calibrate_invoice->execute(); if (!$vendor_purchase_calibrate_invoice_result->success) { throw new Exception("UNEXPECTED ERROR: COULD NOT CALIBRATE VENDOR PURCHASES: " . $vendor_purchase_calibrate_invoice_result->error); } // Recalibrate Vendor Invoices / Cancellations $vendor_purchase_calibrate_cancel = new Beans_Vendor_Purchase_Calibrate_Cancel($this->_beans_data_auth((object) array('ids' => $handled_purchase_ids))); $vendor_purchase_calibrate_cancel_result = $vendor_purchase_calibrate_cancel->execute(); if (!$vendor_purchase_calibrate_cancel_result->success) { throw new Exception("UNEXPECTED ERROR: COULD NOT CALIBRATE VENDOR PURCHASES: " . $vendor_purchase_calibrate_cancel_result->error); } // Recalibrate any payments tied to these purchases AFTER this transaction. $vendor_payment_calibrate = new Beans_Vendor_Payment_Calibrate($this->_beans_data_auth((object) array('form_ids' => $handled_purchase_ids))); $vendor_payment_calibrate_result = $vendor_payment_calibrate->execute(); if (!$vendor_payment_calibrate_result->success) { throw new Exception("UNEXPECTED ERROR: COULD NOT CALIBRATE VENDOR PAYMENTS: " . $vendor_payment_calibrate_result->error); } return (object) array(); }
protected function _execute() { if (!$this->_expense->loaded()) { throw new Exception("Expense could not be found."); } if ($this->_check_books_closed($this->_expense->date_created) && $this->_expense->create_transaction_id && $this->_expense->invoice_transaction_id && $this->_expense->cancel_transaction_id) { throw new Exception("Expense could not be deleted. The financial year has been closed already."); } if ($this->_expense->refund_form_id and $this->_expense->refund_form_id > $this->_expense->id) { throw new Exception("Expense could not be deleted - it has a refund attached to it."); } // Determine if this expense transaction is RECONCILED. foreach ($this->_expense->create_transaction->account_transactions->find_all() as $account_transaction) { if ($account_transaction->account_reconcile_id) { throw new Exception("Expense could not be deleted. The payment has already been reconciled to an account. Are you trying to create a refund?"); } } // Cancel Transaction. if ($this->_expense->create_transaction_id) { $account_transaction_delete = new Beans_Account_Transaction_Delete($this->_beans_data_auth((object) array('id' => $this->_expense->create_transaction_id, 'form_type_handled' => 'expense', 'payment_type_handled' => 'expense'))); $account_transaction_delete_result = $account_transaction_delete->execute(); if (!$account_transaction_delete_result->success) { throw new Exception("Error cancelling account transaction: " . $account_transaction_delete_result->error); } } foreach ($this->_expense->form_lines->find_all() as $expense_line) { $expense_line->delete(); } // Remove the refund form from the corresponding form. if ($this->_expense->refund_form->loaded()) { $this->_expense->refund_form->refund_form_id = NULL; $this->_expense->refund_form->save(); } $this->_expense->delete(); return (object) array(); }
protected function _execute() { if (!$this->_payment->loaded()) { throw new Exception("Payment could not be found."); } $form_ids_query = ' SELECT DISTINCT(account_transaction_forms.form_id) as form_id FROM account_transaction_forms ' . ' INNER JOIN account_transactions ON account_transaction_forms.account_transaction_id = account_transactions.id WHERE ' . ' account_transactions.transaction_id = ' . $this->_payment->id; $form_ids = DB::Query(Database::SELECT, $form_ids_query)->execute()->as_array(); $handled_sales_ids = array(); foreach ($form_ids as $form_id) { $handled_sales_ids[] = $form_id['form_id']; } $payment_date = $this->_payment->date; $payment_id = $this->_payment->id; // Try to cancel payment. $account_transaction_delete = new Beans_Account_Transaction_Delete($this->_beans_data_auth((object) array('id' => $this->_payment->id, 'payment_type_handled' => 'customer'))); $account_transaction_delete_result = $account_transaction_delete->execute(); if (!$account_transaction_delete_result->success) { throw new Exception("Error cancelling payment: " . $account_transaction_delete_result->error); } // Recalibrate Customer Invoices / Cancellations $customer_sale_calibrate_invoice = new Beans_Customer_Sale_Calibrate_Invoice($this->_beans_data_auth((object) array('ids' => $handled_sales_ids))); $customer_sale_calibrate_invoice_result = $customer_sale_calibrate_invoice->execute(); if (!$customer_sale_calibrate_invoice_result->success) { throw new Exception("UNEXPECTED ERROR: COULD NOT CALIBRATE CUSTOMER SALES: " . $customer_sale_calibrate_invoice_result->error); } // Recalibrate Customer Invoices / Cancellations $customer_sale_calibrate_cancel = new Beans_Customer_Sale_Calibrate_Cancel($this->_beans_data_auth((object) array('ids' => $handled_sales_ids))); $customer_sale_calibrate_cancel_result = $customer_sale_calibrate_cancel->execute(); if (!$customer_sale_calibrate_cancel_result->success) { throw new Exception("UNEXPECTED ERROR: COULD NOT CALIBRATE CUSTOMER SALES: " . $customer_sale_calibrate_cancel_result->error); } // Recalibrate any payments tied to these sales AFTER this transaction date. $customer_payment_calibrate = new Beans_Customer_Payment_Calibrate($this->_beans_data_auth((object) array('form_ids' => $handled_sales_ids))); $customer_payment_calibrate_result = $customer_payment_calibrate->execute(); return (object) array("success" => TRUE, "auth_error" => "", "error" => "", "data" => (object) array()); }
private function _calibrate_forms() { $calibrated_form_ids = array(); $calibrate_transaction_ids_query = 'SELECT forms_transactions.* FROM ( ' . ' SELECT transactions.id as transaction_id, ' . ' forms.id as form_id, ' . ' forms.type as form_type, ' . ' forms.create_transaction_id as create_transaction_id, ' . ' forms.invoice_transaction_id as invoice_transaction_id, ' . ' forms.cancel_transaction_id as cancel_transaction_id ' . ' FROM ' . ' transactions INNER JOIN forms ' . ' ON transactions.form_id = forms.id ' . ') forms_transactions ' . 'WHERE ' . 'NOT(forms_transactions.transaction_id <=> forms_transactions.create_transaction_id) AND ' . 'NOT(forms_transactions.transaction_id <=> forms_transactions.invoice_transaction_id) AND ' . 'NOT(forms_transactions.transaction_id <=> forms_transactions.cancel_transaction_id) '; $calibrate_transaction_ids = DB::Query(Database::SELECT, $calibrate_transaction_ids_query)->execute()->as_array(); if ($calibrate_transaction_ids && count($calibrate_transaction_ids)) { foreach ($calibrate_transaction_ids as $calibrate_transaction_id) { // Delete any transactions returned. $account_transaction_delete = new Beans_Account_Transaction_Delete($this->_beans_data_auth((object) array('id' => $calibrate_transaction_id['transaction_id'], 'form_type_handled' => $calibrate_transaction_id['form_type']))); $account_transaction_delete_result = $account_transaction_delete->execute(); if (!$account_transaction_delete_result->success) { throw new Exception("Unexpected error! Could not delete extra form transaction: " . $account_transaction_delete_result->error); } if (!in_array($calibrate_transaction_id['form_id'], $calibrated_form_ids)) { $calibrated_form_ids[] = $calibrate_transaction_id['form_id']; } } } return $calibrated_form_ids; }
protected function _execute() { if (!$this->_old_payment->loaded()) { throw new Exception("Payment could not be found."); } if ($this->_old_payment->transaction->account_transactions->where('account_reconcile_id', 'IS NOT', NULL)->count_all()) { throw new Exception("Payment cannot be changed after it has been reconciled."); } if (!isset($this->_data->tax_id)) { throw new Exception("Invalid tax ID: none provided."); } $tax = $this->_load_tax($this->_data->tax_id); if (!$tax->loaded()) { throw new Exception("Invalid tax ID: not found."); } // Check for some basic data. if (!isset($this->_data->payment_account_id)) { throw new Exception("Invalid payment account ID: none provided."); } $payment_account = $this->_load_account($this->_data->payment_account_id); if (!$payment_account->loaded()) { throw new Exception("Invalid payment account ID: not found."); } if (!$payment_account->payment) { throw new Exception("Invalid payment account ID: account must be marked as payment."); } if (!$this->_data->amount) { throw new Exception("Invalid payment amount: none provided."); } // Payment. $this->_payment->amount = $this->_data->amount; $this->_payment->tax_id = $tax->id; $this->_payment->date = isset($this->_data->date) ? $this->_data->date : $this->_old_payment->date; $this->_payment->date_start = $this->_old_payment->date_start; $this->_payment->date_end = $this->_old_payment->date_end; $this->_payment->writeoff_amount = isset($this->_data->writeoff_amount) ? $this->_data->writeoff_amount : 0.0; $this->_payment->id = $this->_old_payment->id; $this->_validate_tax_payment($this->_payment); $this->_payment->invoiced_line_amount = $this->_old_payment->invoiced_line_amount; $this->_payment->invoiced_line_taxable_amount = $this->_old_payment->invoiced_line_taxable_amount; $this->_payment->invoiced_amount = $this->_old_payment->invoiced_amount; $this->_payment->refunded_line_amount = $this->_old_payment->refunded_line_amount; $this->_payment->refunded_line_taxable_amount = $this->_old_payment->refunded_line_taxable_amount; $this->_payment->refunded_amount = $this->_old_payment->refunded_amount; $this->_payment->net_line_amount = $this->_old_payment->net_line_amount; $this->_payment->net_line_taxable_amount = $this->_old_payment->net_line_taxable_amount; $this->_payment->net_amount = $this->_old_payment->net_amount; if ($this->_payment->net_amount != $this->_beans_round($this->_payment->amount + $this->_payment->writeoff_amount)) { throw new Exception("Payment amount and writeoff amount must total the payment total."); } // Formulate data request object for Beans_Account_Transaction_Create $create_transaction_data = new stdClass(); $create_transaction_data->code = isset($this->_data->number) ? $this->_data->number : $this->_old_payment->transaction->code; $create_transaction_data->description = isset($this->_data->description) ? $this->_data->description : $this->_old_payment->transaction->description; if (!$create_transaction_data->description) { $create_transaction_data->description = "Tax Remittance: " . $tax->name; } else { if (strpos($create_transaction_data->description, "Tax Remittance: ") === FALSE) { $create_transaction_data->description = "Tax Remittance: " . $create_transaction_data->description; } } $create_transaction_data->date = isset($this->_data->date) ? $this->_data->date : $this->_old_payment->transaction->date; $create_transaction_data->reference = isset($this->_data->check_number) ? $this->_data->check_number : $this->_old_payment->transaction->reference; if (!$create_transaction_data->code and $create_transaction_data->reference) { $create_transaction_data->code = $create_transaction_data->reference; } $create_transaction_data->form_type = 'tax_payment'; $create_transaction_data->form_id = $this->_payment->id; // Positive Payment = Negative to Balance $create_transaction_data->account_transactions = array(); // Payment Account $create_transaction_data->account_transactions[] = (object) array('account_id' => $payment_account->id, 'transfer' => TRUE, 'amount' => $this->_payment->amount * -1 * $payment_account->account_type->table_sign); if (isset($this->_data->writeoff_amount) and $this->_data->writeoff_amount != 0.0) { $writeoff_amount = isset($this->_data->writeoff_amount) ? $this->_data->writeoff_amount : NULL; $writeoff_account_id = isset($this->_data->writeoff_account_id) ? $this->_data->writeoff_account_id : NULL; if (!$writeoff_amount) { throw new Exception("That payment will require a specifc writeoff amount - please provide that value."); } if (!$writeoff_account_id) { throw new Exception("That payment will require a writeoff - please provide a writeoff account ID."); } $writeoff_account = $this->_load_account($writeoff_account_id); if (!$writeoff_account->loaded()) { throw new Exception("Invalid writeoff account: not found."); } if (!$writeoff_account->writeoff) { throw new Exception("Invalid writeoff account: must be marked as a valid writeoff account."); } $create_transaction_data->account_transactions[] = (object) array('account_id' => $writeoff_account->id, 'writeoff' => TRUE, 'amount' => $writeoff_amount * -1 * $payment_account->account_type->table_sign); $this->_payment->amount = $this->_beans_round($this->_payment->amount + $writeoff_amount); } // Tax Account $create_transaction_data->account_transactions[] = (object) array('account_id' => $tax->account_id, 'amount' => $this->_payment->amount * $payment_account->account_type->table_sign); // Make sure our data is good. $create_transaction_data->validate_only = TRUE; $validate_transaction = new Beans_Account_Transaction_Create($this->_beans_data_auth($create_transaction_data)); $validate_transaction_result = $validate_transaction->execute(); if (!$validate_transaction_result->success) { throw new Exception("An error occurred when creating that payment: " . $validate_transaction_result->error); } if ($this->_validate_only) { return (object) array(); } $create_transaction_data->validate_only = FALSE; // Delete old transaction $account_transaction_delete = new Beans_Account_Transaction_Delete($this->_beans_data_auth((object) array('id' => $this->_old_payment->transaction_id, 'payment_type_handled' => 'tax'))); $account_transaction_delete_result = $account_transaction_delete->execute(); // Delete Payment $this->_old_payment->delete(); $create_transaction = new Beans_Account_Transaction_Create($this->_beans_data_auth($create_transaction_data)); $create_transaction_result = $create_transaction->execute(); if (!$create_transaction_result->success) { throw new Exception("An error occurred creating that tax payment: " . $create_transaction_result->error); } // Assign transction to payment and save $this->_payment->transaction_id = $create_transaction_result->data->transaction->id; $this->_payment->save(); // Update tax balance $this->_tax_payment_update_balance($this->_payment->tax_id); return (object) array("payment" => $this->_return_tax_payment_element($this->_payment, TRUE)); }
protected function _execute() { if (!$this->_sale->loaded()) { throw new Exception("Sale could not be found."); } // There's a unique use-case that's hard to replicate, but it produces a form that // has no create_transaction - closing the FYE with this form can be frustrating to deal with otherwise. if ($this->_check_books_closed($this->_sale->date_created) && $this->_sale->create_transaction_id && $this->_sale->invoice_transaction_id && $this->_sale->cancel_transaction_id) { throw new Exception("Sale could not be updated. The financial year has been closed already."); } $sale_original_total = $this->_sale->total; if ($this->_sale->date_cancelled) { throw new Exception("A sale cannot be updated after it has been cancelled."); } if (isset($this->_data->account_id)) { $this->_sale->account_id = $this->_data->account_id; } if (isset($this->_data->sent)) { $this->_sale->sent = $this->_data->sent; } if (isset($this->_data->date_created)) { $this->_sale->date_created = $this->_data->date_created; } if (isset($this->_data->sale_number)) { $this->_sale->code = $this->_data->sale_number; } if (isset($this->_data->order_number)) { $this->_sale->reference = $this->_data->order_number; } if (isset($this->_data->quote_number)) { $this->_sale->aux_reference = $this->_data->quote_number; } if (isset($this->_data->po_number)) { $this->_sale->alt_reference = $this->_data->po_number; } if (isset($this->_data->tax_exempt)) { $this->_sale->tax_exempt = $this->_data->tax_exempt ? TRUE : FALSE; } if (isset($this->_data->tax_exempt_reason)) { $this->_sale->tax_exempt_reason = ($this->_sale->tax_exempt and strlen($this->_data->tax_exempt_reason)) ? $this->_data->tax_exempt_reason : NULL; } if (isset($this->_data->billing_address_id)) { $this->_sale->billing_address_id = $this->_data->billing_address_id; } if (isset($this->_data->shipping_address_id)) { $this->_sale->shipping_address_id = $this->_data->shipping_address_id; } // Field that can be updated ONLY after being invoiced. if ($this->_sale->date_billed) { /* if( isset($this->_data->date_billed) AND strtotime($this->_data->date_billed) < strtotime($this->_sale->date_created) ) throw new Exception("Invalid invoice date: must be on or after the creation date of ".$this->_sale->date_created."."); */ if (isset($this->_data->date_billed)) { $this->_sale->date_billed = $this->_data->date_billed; } if (isset($this->_data->date_due)) { $this->_sale->date_due = $this->_data->date_due; } if (strtotime($this->_sale->date_created) > strtotime($this->_sale->date_billed)) { $this->_sale->date_created = $this->_sale->date_billed; } } // Make sure we have good sale information before moving on. $this->_validate_customer_sale($this->_sale); $this->_sale->total = 0.0; $this->_sale->amount = 0.0; if (!isset($this->_data->lines) or !is_array($this->_data->lines) or !count($this->_data->lines)) { throw new Exception("Invalid sale lines: none provided."); } if (isset($this->_data->taxes)) { if (!is_array($this->_data->taxes)) { throw new Exception("Invalid sale taxes: must be an array."); } foreach ($this->_data->taxes as $sale_tax) { $new_sale_tax = $this->_default_form_tax(); $new_sale_tax->tax_id = isset($sale_tax->tax_id) ? (int) $sale_tax->tax_id : NULL; if (!$new_sale_tax->tax_id) { throw new Exception("Invalid sale tax ID: none provided."); } $tax = $this->_load_tax($new_sale_tax->tax_id); if (!$tax->loaded()) { throw new Exception("Invalid sale tax ID: tax not found."); } $new_sale_tax->tax_percent = $tax->percent; $new_sale_tax->form_line_amount = 0.0; $new_sale_tax->form_line_taxable_amount = 0.0; $new_sale_tax->total = 0.0; if (!isset($this->_sale_taxes[$new_sale_tax->tax_id])) { $this->_sale_taxes[$new_sale_tax->tax_id] = $new_sale_tax; } } } foreach ($this->_data->lines as $sale_line) { $new_sale_line = $this->_default_form_line(); $new_sale_line->account_id = isset($sale_line->account_id) ? (int) $sale_line->account_id : NULL; $new_sale_line->tax_exempt = $this->_sale->tax_exempt || (isset($sale_line->tax_exempt) and $sale_line->tax_exempt) ? TRUE : FALSE; $new_sale_line->description = isset($sale_line->description) ? $sale_line->description : NULL; $new_sale_line->amount = isset($sale_line->amount) ? $this->_beans_round($sale_line->amount) : NULL; $new_sale_line->quantity = isset($sale_line->quantity) ? (double) $sale_line->quantity : NULL; // Handle Default Income Account if ($new_sale_line->account_id === NULL) { $new_sale_line->account_id = $this->_beans_setting_get('account_default_income'); } $this->_validate_customer_sale_line($new_sale_line); $new_sale_line->total = $this->_beans_round($new_sale_line->amount * $new_sale_line->quantity); if (!$new_sale_line->tax_exempt) { foreach ($this->_sale_taxes as $tax_id => $sale_tax) { $this->_sale_taxes[$tax_id]->form_line_taxable_amount = $this->_beans_round($this->_sale_taxes[$tax_id]->form_line_taxable_amount + $new_sale_line->total); } } $this->_sale->amount = $this->_beans_round($this->_sale->amount + $new_sale_line->total); $this->_sale_lines[] = $new_sale_line; } $this->_sale->total = $this->_beans_round($this->_sale->total + $this->_sale->amount); foreach ($this->_sale_taxes as $tax_id => $sale_tax) { $this->_sale_taxes[$tax_id]->total = $this->_beans_round($sale_tax->tax_percent * $sale_tax->form_line_taxable_amount); $this->_sale_taxes[$tax_id]->form_line_amount = $this->_sale->amount; $this->_sale->total = $this->_beans_round($this->_sale->total + $this->_sale_taxes[$tax_id]->total); } // Validate Totals if ($this->_sale->refund_form_id) { $refund_form = $this->_load_customer_sale($this->_sale->refund_form_id); $original_sale = $this->_sale; $refund_sale = $refund_form; if ($this->_sale->refund_form_id < $this->_sale->id) { $refund_sale = $this->_sale; $original_sale = $refund_form; } if ($original_sale->total > 0.0 and $refund_sale->total > 0.0 or $original_sale->total < 0.0 and $refund_sale->total < 0.0) { throw new Exception("Refund and original sale totals must offset each other ( they cannot both be positive or negative )."); } if (abs($refund_sale->total) > abs($original_sale->total)) { throw new Exception("The refund total cannot be greater than the original sale total."); } } // Delete Account Transaction if ($this->_sale->create_transaction->loaded()) { $account_transaction_delete = new Beans_Account_Transaction_Delete($this->_beans_data_auth((object) array('id' => $this->_sale->create_transaction_id, 'form_type_handled' => 'sale'))); $account_transaction_delete_result = $account_transaction_delete->execute(); if (!$account_transaction_delete_result->success) { throw new Exception("Error cancelling account transaction: " . $account_transaction_delete_result->error); } $this->_sale->create_transaction_id = NULL; } // Delete all current sale children. foreach ($this->_sale->form_lines->find_all() as $sale_line) { $sale_line->delete(); } foreach ($this->_sale->form_taxes->find_all() as $sale_tax) { $sale_tax->delete(); } // Save Sale + Children $this->_sale->save(); foreach ($this->_sale_lines as $j => $sale_line) { $sale_line->form_id = $this->_sale->id; $sale_line->save(); } foreach ($this->_sale_taxes as $tax_id => $sale_tax) { $this->_sale_taxes[$tax_id]->form_id = $this->_sale->id; $this->_sale_taxes[$tax_id]->save(); } $this->_sale->save(); $sale_calibrate = new Beans_Customer_Sale_Calibrate($this->_beans_data_auth((object) array('ids' => array($this->_sale->id)))); $sale_calibrate_result = $sale_calibrate->execute(); if (!$sale_calibrate_result->success) { throw new Exception("Error trying to create sale transactions: " . $sale_calibrate_result->error); } // Reload the sale. $this->_sale = $this->_load_customer_sale($this->_sale->id); // Upon updating a sale, if the total has changed we change the sent flag. if ($this->_sale->total != $sale_original_total and !isset($this->_data->sent)) { $this->_sale->sent = FALSE; } $customer_payment_calibrate = new Beans_Customer_Payment_Calibrate($this->_beans_data_auth((object) array('form_ids' => array($this->_sale->id)))); $customer_payment_calibrate_result = $customer_payment_calibrate->execute(); if (!$customer_payment_calibrate_result->success) { throw new Exception("Error encountered when calibrating payments: " . $customer_payment_calibrate_result->error); } // Update tax items only if we're successful // AND // Only if we've billed this sales order. if ($this->_sale->date_billed) { $tax_item_action = 'invoice'; if ($this->_sale->refund_form_id && $this->_sale->refund_form_id < $this->_sale->id) { $tax_item_action = 'refund'; } $this->_update_form_tax_items($this->_sale->id, $tax_item_action); } // We need to reload the sale so that we can get the correct balance, etc. $this->_sale = $this->_load_customer_sale($this->_sale->id); return (object) array("sale" => $this->_return_customer_sale_element($this->_sale)); }
public function action_transactiondelete() { $account_transaction_delete = new Beans_Account_Transaction_Delete($this->_beans_data_auth((object) array('id' => $this->request->post('transaction_id')))); $account_transaction_delete_result = $account_transaction_delete->execute(); if (!$account_transaction_delete_result->success) { return $this->_return_error("An error occurred when deleting that transaction: " . $this->_beans_result_get_error($account_transaction_delete_result)); } return; }
protected function _execute() { if (!$this->_expense->loaded()) { throw new Exception("Expense could not be found."); } if ($this->_check_books_closed($this->_expense->date_created) && $this->_expense->create_transaction_id && $this->_expense->invoice_transaction_id && $this->_expense->cancel_transaction_id) { throw new Exception("Expense could not be updated. The financial year has been closed already."); } if (isset($this->_data->vendor_id)) { $this->_expense->entity_id = $this->_data->vendor_id; } if (isset($this->_data->account_id)) { $this->_expense->account_id = $this->_data->account_id; } if (isset($this->_data->sent)) { $this->_expense->sent = $this->_data->sent; } if (isset($this->_data->date_created)) { $this->_expense->date_created = $this->_data->date_created; } if (isset($this->_data->expense_number)) { $this->_expense->code = $this->_data->expense_number; } if (isset($this->_data->invoice_number)) { $this->_expense->reference = $this->_data->invoice_number; } if (isset($this->_data->so_number)) { $this->_expense->alt_reference = $this->_data->so_number; } if (isset($this->_data->remit_address_id)) { $this->_expense->remit_address_id = $this->_data->remit_address_id; } // Make sure we have good expense information before moving on. $this->_validate_vendor_expense($this->_expense); if ($this->_attributes_only) { $this->_expense->save(); return (object) array("success" => TRUE, "auth_error" => "", "error" => "", "data" => (object) array("expense" => $this->_return_vendor_expense_element($this->_expense))); } $this->_expense->total = 0.0; $this->_expense->amount = 0.0; if (!isset($this->_data->lines) or !is_array($this->_data->lines) or !count($this->_data->lines)) { throw new Exception("Invalid expense lines: none provided."); } $i = 0; foreach ($this->_data->lines as $expense_line) { $new_expense_line = $this->_default_form_line(); $new_expense_line->account_id = isset($expense_line->account_id) ? (int) $expense_line->account_id : NULL; $new_expense_line->description = isset($expense_line->description) ? $expense_line->description : NULL; $new_expense_line->amount = isset($expense_line->amount) ? $this->_beans_round($expense_line->amount) : NULL; $new_expense_line->quantity = isset($expense_line->quantity) ? (double) $expense_line->quantity : NULL; $this->_validate_form_line($new_expense_line); $new_expense_line->total = $this->_beans_round($new_expense_line->amount * $new_expense_line->quantity); $new_expense_line_total = $this->_beans_round($new_expense_line->total); $this->_expense->amount = $this->_beans_round($this->_expense->amount + $new_expense_line->total); $this->_expense_lines[$i] = $new_expense_line; $i++; } $this->_expense->total = $this->_beans_round($this->_expense->total + $this->_expense->amount); // Cancel Account Transaction if ($this->_expense->create_transaction_id) { $account_transaction_delete = new Beans_Account_Transaction_Delete($this->_beans_data_auth((object) array('id' => $this->_expense->create_transaction_id, 'form_type_handled' => 'expense', 'payment_type_handled' => 'expense'))); $account_transaction_delete_result = $account_transaction_delete->execute(); if (!$account_transaction_delete_result->success) { throw new Exception("Error cancelling account transaction: " . $account_transaction_delete_result->error); } $this->_expense->create_transaction_id = NULL; } // Delete all current expense children. foreach ($this->_expense->form_lines->find_all() as $expense_line) { $expense_line->delete(); } // Save expense + Children $this->_expense->save(); // We "decrease" the account. $expense_account = $this->_load_account($this->_expense->account_id); $this->_account_transactions[$this->_expense->account_id] = $this->_expense->total; foreach ($this->_expense_lines as $j => $expense_line) { $expense_line->form_id = $this->_expense->id; $expense_line->save(); if (!isset($this->_account_transactions[$expense_line->account_id])) { $this->_account_transactions[$expense_line->account_id] = 0.0; } $this->_account_transactions[$expense_line->account_id] = $this->_beans_round($this->_account_transactions[$expense_line->account_id] + $this->_beans_round($expense_line->amount * $expense_line->quantity)); } // Generate Account Transaction $account_create_transaction_data = new stdClass(); $account_create_transaction_data->code = isset($this->_data->check_number) ? $this->_data->check_number : $this->_expense->create_transaction->code; $account_create_transaction_data->description = "Expense Recorded: " . $this->_expense->entity->company_name; $account_create_transaction_data->date = $this->_expense->date_created; $account_create_transaction_data->account_transactions = array(); $account_create_transaction_data->payment = "expense"; $account_create_transaction_data->reference = isset($this->_data->check_number) ? $this->_data->check_number : $this->_expense->create_transaction->reference; $account_create_transaction_data->form_type = 'expense'; $account_create_transaction_data->form_id = $this->_expense->id; foreach ($this->_account_transactions as $account_id => $amount) { $account_transaction = new stdClass(); $account_transaction->account_id = $account_id; $account_transaction->amount = $account_id == $this->_expense->account_id ? $amount : $amount * -1; $account_transaction->forms = array((object) array("form_id" => $this->_expense->id, "amount" => $account_transaction->amount)); $account_create_transaction_data->account_transactions[] = $account_transaction; } $account_create_transaction = new Beans_Account_Transaction_Create($this->_beans_data_auth($account_create_transaction_data)); $account_create_transaction_result = $account_create_transaction->execute(); if (!$account_create_transaction_result->success) { // We've had an account transaction failure and need to delete the expense we just created. $delete_expense = new Beans_vendor_expense_Delete($this->_beans_data_auth((object) array('id' => $this->_expense->id))); $delete_expense_result = $delete_expense->execute(); // NOW WE HAVE A REALLY BIG PROBLEM ON OUR HANDS. if (!$delete_expense_result->success) { throw new Exception("Error creating account transaction for expense. COULD NOT DELETE EXPENSE! " . $delete_expense_result->error); } throw new Exception("Error creating account transaction: " . $account_create_transaction_result->error); } // We're good! $this->_expense->create_transaction_id = $account_create_transaction_result->data->transaction->id; $this->_expense->save(); $this->_expense = $this->_load_vendor_expense($this->_expense->id); return (object) array("expense" => $this->_return_vendor_expense_element($this->_expense)); }