Esempio n. 1
0
 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();
 }
Esempio n. 2
0
 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();
 }
Esempio n. 3
0
 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();
 }
Esempio n. 4
0
 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();
 }
Esempio n. 5
0
 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();
 }
Esempio n. 6
0
 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());
 }
Esempio n. 7
0
 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;
 }
Esempio n. 8
0
 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));
 }
Esempio n. 9
0
 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));
 }
Esempio n. 10
0
 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;
 }
Esempio n. 11
0
 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));
 }