Esempio n. 1
0
 protected function _execute()
 {
     $customer_sale_calibrate_create = new Beans_Customer_Sale_Calibrate_Create($this->_beans_data_auth((object) array('ids' => isset($this->_data->ids) ? $this->_data->ids : NULL, 'date_after' => isset($this->_data->date_after) ? $this->_data->date_after : NULL, 'date_before' => isset($this->_data->date_before) ? $this->_data->date_before : NULL)));
     $customer_sale_calibrate_create_result = $customer_sale_calibrate_create->execute();
     if (!$customer_sale_calibrate_create_result->success) {
         throw new Exception("Unexpected error - could not calibrate sales: " . $customer_sale_calibrate_create_result->error);
     }
     $customer_sale_calibrate_invoice = new Beans_Customer_Sale_Calibrate_Invoice($this->_beans_data_auth((object) array('ids' => isset($this->_data->ids) ? $this->_data->ids : NULL, 'date_after' => isset($this->_data->date_after) ? $this->_data->date_after : NULL, 'date_before' => isset($this->_data->date_before) ? $this->_data->date_before : NULL)));
     $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 invoiced sales: " . $customer_sale_calibrate_invoice_result->error);
     }
     $customer_sale_calibrate_cancel = new Beans_Customer_Sale_Calibrate_Cancel($this->_beans_data_auth((object) array('ids' => isset($this->_data->ids) ? $this->_data->ids : NULL, 'date_after' => isset($this->_data->date_after) ? $this->_data->date_after : NULL, 'date_before' => isset($this->_data->date_before) ? $this->_data->date_before : NULL)));
     $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 cancelled sales: " . $customer_sale_calibrate_cancel_result->error);
     }
     return (object) array();
 }
Esempio n. 2
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. 3
0
 protected function _execute()
 {
     if (!$this->_transaction_sale_account_id) {
         throw new Exception("INTERNAL ERROR: Could not find default SO receivable account.");
     }
     if (!$this->_transaction_sale_line_account_id) {
         throw new Exception("INTERNAL ERROR: Could not find default SO line account.");
     }
     if (!$this->_transaction_sale_tax_account_id) {
         throw new Exception("INTERNAL ERROR: Could not find default SO tax account.");
     }
     if (!$this->_transaction_sale_deferred_income_account_id) {
         throw new Exception("INTERNAL ERROR: Could not find default SO deferred income account.");
     }
     if (!$this->_transaction_sale_deferred_liability_account_id) {
         throw new Exception("INTERNAL ERROR: Could not find default SO deferred liability account.");
     }
     // Check for some basic data.
     if (!isset($this->_data->deposit_account_id)) {
         throw new Exception("Invalid payment deposit account ID: none provided.");
     }
     $deposit_account = $this->_load_account($this->_data->deposit_account_id);
     if (!$deposit_account->loaded()) {
         throw new Exception("Invalid payment deposit account ID: not found.");
     }
     if (!$deposit_account->deposit) {
         throw new Exception("Invalid payment deposit account ID: account must be marked as deposit.");
     }
     if (!$this->_data->amount) {
         throw new Exception("Invalid payment amount: none provided.");
     }
     // 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 : NULL;
     $create_transaction_data->description = isset($this->_data->description) ? $this->_data->description : NULL;
     $create_transaction_data->description = "Customer Payment Recorded" . ($create_transaction_data->description ? ': ' . $create_transaction_data->description : '');
     $create_transaction_data->date = isset($this->_data->date) ? $this->_data->date : NULL;
     $create_transaction_data->payment = "customer";
     $sale_account_transfers = array();
     $sale_account_transfers_forms = array();
     $writeoff_account_transfer_total = 0.0;
     $writeoff_account_transfers_forms = array();
     if (!$this->_data->sales or !count($this->_data->sales)) {
         throw new Exception("Please provide at least one sale for this payment.");
     }
     $handled_sales_ids = array();
     foreach ($this->_data->sales as $sale_payment) {
         if (!isset($sale_payment->sale_id) or !$sale_payment->sale_id) {
             throw new Exception("Invalid payment sale ID: none provided.");
         }
         $sale = $this->_load_customer_sale($sale_payment->sale_id);
         if (!$sale->loaded()) {
             throw new Exception("Invalid payment sale: sale not found.");
         }
         if (!$sale_payment->amount) {
             throw new Exception("Invalid payment sale amount: none provided.");
         }
         if (in_array($sale->id, $handled_sales_ids)) {
             throw new Exception("Invalid payment sale: sale " . $sale->code . " cannot be in payment more than once.");
         }
         $handled_sales_ids[] = $sale->id;
         $sale_id = $sale->id;
         // Get the sale total, tax total, and balance as of the payment date.
         $sale_line_total = $sale->amount;
         $sale_tax_total = $this->_beans_round($sale->total - $sale->amount);
         $sale_balance = $this->_get_form_effective_balance($sale, $create_transaction_data->date, NULL);
         // This makes the math a bit easier to read.
         $sale_paid = $sale->total + $sale_balance;
         // Money Received / Paid = Bank
         $sale_transfer_amount = $sale_payment->amount;
         $sale_writeoff_amount = (isset($sale_payment->writeoff_balance) and $sale_payment->writeoff_balance) ? $this->_beans_round(0.0 - $sale_balance - $sale_transfer_amount) : FALSE;
         // AR Adjustment
         $sale_payment_amount = $sale_writeoff_amount ? $this->_beans_round($sale_transfer_amount + $sale_writeoff_amount) : $sale_transfer_amount;
         // Another variable to simplify code.
         $sale_transaction_account_id = FALSE;
         if ($sale->date_billed and $sale->invoice_transaction_id and strtotime($sale->date_billed) <= strtotime($create_transaction_data->date) or $sale->date_cancelled and $sale->cancel_transaction_id and strtotime($sale->date_cancelled) <= strtotime($create_transaction_data->date)) {
             // Sale AR
             $sale_transaction_account_id = $sale->account_id;
             if (!isset($sale_account_transfers[$sale_transaction_account_id])) {
                 $sale_account_transfers[$sale_transaction_account_id] = 0.0;
             }
             $sale_account_transfers[$sale_transaction_account_id] = $this->_beans_round($sale_account_transfers[$sale_transaction_account_id] + $sale_payment_amount);
             if (!isset($sale_account_transfers_forms[$sale_transaction_account_id])) {
                 $sale_account_transfers_forms[$sale_transaction_account_id] = array();
             }
             $sale_account_transfers_forms[$sale_transaction_account_id][] = (object) array("form_id" => $sale_id, "amount" => $sale_payment_amount, "writeoff_amount" => $sale_writeoff_amount ? $sale_writeoff_amount : NULL);
         } else {
             $deferred_amounts = $this->_calculate_deferred_payment($sale_payment_amount, $sale_paid, $sale_line_total, $sale_tax_total);
             $income_transfer_amount = $deferred_amounts->income_transfer_amount;
             $tax_transfer_amount = $deferred_amounts->tax_transfer_amount;
             if ($income_transfer_amount) {
                 if (!isset($sale_account_transfers[$this->_transaction_sale_deferred_income_account_id])) {
                     $sale_account_transfers[$this->_transaction_sale_deferred_income_account_id] = 0.0;
                 }
                 if (!isset($sale_account_transfers[$this->_transaction_sale_line_account_id])) {
                     $sale_account_transfers[$this->_transaction_sale_line_account_id] = 0.0;
                 }
                 $sale_account_transfers[$this->_transaction_sale_deferred_income_account_id] = $this->_beans_round($sale_account_transfers[$this->_transaction_sale_deferred_income_account_id] + $income_transfer_amount);
                 $sale_account_transfers[$this->_transaction_sale_line_account_id] = $this->_beans_round($sale_account_transfers[$this->_transaction_sale_line_account_id] - $income_transfer_amount);
             }
             if ($tax_transfer_amount) {
                 if (!isset($sale_account_transfers[$this->_transaction_sale_deferred_liability_account_id])) {
                     $sale_account_transfers[$this->_transaction_sale_deferred_liability_account_id] = 0.0;
                 }
                 if (!isset($sale_account_transfers[$this->_transaction_sale_tax_account_id])) {
                     $sale_account_transfers[$this->_transaction_sale_tax_account_id] = 0.0;
                 }
                 $sale_account_transfers[$this->_transaction_sale_deferred_liability_account_id] = $this->_beans_round($sale_account_transfers[$this->_transaction_sale_deferred_liability_account_id] + $tax_transfer_amount);
                 $sale_account_transfers[$this->_transaction_sale_tax_account_id] = $this->_beans_round($sale_account_transfers[$this->_transaction_sale_tax_account_id] - $tax_transfer_amount);
             }
             if (!isset($sale_account_transfers[$this->_transaction_sale_account_id])) {
                 $sale_account_transfers[$this->_transaction_sale_account_id] = 0.0;
             }
             $sale_account_transfers[$this->_transaction_sale_account_id] = $this->_beans_round($sale_account_transfers[$this->_transaction_sale_account_id] + $sale_payment_amount);
             if (!isset($sale_account_transfers_forms[$this->_transaction_sale_account_id])) {
                 $sale_account_transfers_forms[$this->_transaction_sale_account_id] = array();
             }
             $sale_account_transfers_forms[$this->_transaction_sale_account_id][] = (object) array("form_id" => $sale_id, "amount" => $sale_payment_amount, "writeoff_amount" => $sale_writeoff_amount ? $sale_writeoff_amount : NULL);
         }
         if ($sale_writeoff_amount) {
             $writeoff_account_transfer_total = $this->_beans_round($writeoff_account_transfer_total + $sale_writeoff_amount);
         }
     }
     $writeoff_account = FALSE;
     if ($writeoff_account_transfer_total != 0.0) {
         // We need a write-off account.
         if (!isset($this->_data->writeoff_account_id) or !$this->_data->writeoff_account_id) {
             throw new Exception("Invalid payment write-off account ID: none provided.");
         }
         $writeoff_account = $this->_load_account($this->_data->writeoff_account_id);
         if (!$writeoff_account->loaded()) {
             throw new Exception("Invalid payment write-off account ID: account not found.");
         }
         if (!$writeoff_account->writeoff) {
             throw new Exception("Invalid payment write-off account ID: account must be marked as write-off.");
         }
         if (isset($sale_account_transfers[$writeoff_account->id])) {
             throw new Exception("Invalid payment write-off account ID: account cannot be tied to any other transaction in the payment.");
         }
         $sale_account_transfers[$writeoff_account->id] = $writeoff_account_transfer_total;
         $sale_account_transfers_forms[$writeoff_account->id] = $writeoff_account_transfers_forms;
     }
     $adjustment_account = FALSE;
     if (isset($this->_data->adjustment_amount) and $this->_data->adjustment_amount != 0.0) {
         if (!isset($this->_data->adjustment_account_id) or !$this->_data->adjustment_account_id) {
             throw new Exception("Invalid adjustment account ID: none provided.");
         }
         $adjustment_account = $this->_load_account($this->_data->adjustment_account_id);
         if (!$adjustment_account->loaded()) {
             throw new Exception("Invalid adjustment account ID: account not found.");
         }
         if (isset($sale_account_transfers[$adjustment_account->id])) {
             throw new Exception("Invalid adjustment account ID: account cannot be tied to any other transaction in the payment.");
         }
         $sale_account_transfers[$adjustment_account->id] = $this->_data->adjustment_amount * -1;
     }
     // All of the accounts on sales are Accounts receivable and should be assets.
     // But to be on the safe side we're going to do table sign adjustments.
     foreach ($sale_account_transfers as $account_id => $transfer_amount) {
         $account = $this->_load_account($account_id);
         if (!$account->loaded()) {
             throw new Exception("System error: could not load account with ID " . $account_id);
         }
         $sale_account_transfers[$account_id] = ($writeoff_account and $writeoff_account->id == $account_id or $adjustment_account and $adjustment_account->id == $account_id) ? $transfer_amount * $deposit_account->account_type->table_sign : $transfer_amount * -1 * $deposit_account->account_type->table_sign;
     }
     // V2Item - Validate amount to avoid funky non-zero errors.
     $sale_account_transfers[$deposit_account->id] = $this->_data->amount * $deposit_account->account_type->table_sign;
     $create_transaction_data->account_transactions = array();
     foreach ($sale_account_transfers as $account_id => $amount) {
         $account_transaction = new stdClass();
         $account_transaction->account_id = $account_id;
         $account_transaction->amount = $amount;
         if ($account_transaction->account_id == $deposit_account->id) {
             $account_transaction->transfer = TRUE;
         }
         if ($writeoff_account and $account_transaction->account_id == $writeoff_account->id) {
             $account_transaction->writeoff = TRUE;
         }
         if ($adjustment_account and $account_transaction->account_id == $adjustment_account->id) {
             $account_transaction->adjustment = TRUE;
         }
         if (isset($sale_account_transfers_forms[$account_id])) {
             $account_transaction->forms = array();
             foreach ($sale_account_transfers_forms[$account_id] as $form) {
                 $account_transaction->forms[] = (object) array('form_id' => $form->form_id, 'amount' => $form->amount, 'writeoff_amount' => $form->writeoff_amount);
             }
         }
         $create_transaction_data->account_transactions[] = $account_transaction;
     }
     if ($this->_validate_only) {
         $create_transaction_data->validate_only = TRUE;
     }
     $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 payment: " . $create_transaction_result->error);
     }
     if ($this->_validate_only) {
         return (object) array();
     }
     // 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, 'after_payment_id' => $create_transaction_result->data->transaction->id)));
     $customer_payment_calibrate_result = $customer_payment_calibrate->execute();
     if (!$customer_payment_calibrate_result->success) {
         throw new Exception("UNEXPECTED ERROR: COULD NOT CALIBRATE CUSTOMER PAYMENTS: " . $customer_sale_calibrate_result->error);
     }
     return (object) array("payment" => $this->_return_customer_payment_element($this->_load_customer_payment($create_transaction_result->data->transaction->id)));
 }