Beispiel #1
0
 public function action_invoiceprocess()
 {
     $purchases = array();
     foreach ($this->request->post() as $key => $value) {
         if ($value == "purchase-key") {
             $purchases[] = (object) array('id' => $key, 'so_number' => $this->request->post('purchase-so_number-' . $key), 'date_billed' => $this->request->post('purchase-date_billed-' . $key) ? $this->request->post('purchase-date_billed-' . $key) : date("Y-m-d"), 'invoice_number' => $this->request->post('purchase-invoice_number-' . $key), 'invoice_amount' => $this->request->post('purchase-invoice_amount-' . $key), 'adjustment_description' => $this->request->post('purchase-adjustment_description-' . $key), 'adjustment_account_id' => $this->request->post('purchase-adjustment_account_id-' . $key));
         }
     }
     if (!count($purchases)) {
         return $this->_return_error("Please include at least one purchase to invoice.");
     }
     // Validate
     foreach ($purchases as $purchase) {
         $vendor_purchase_invoice_validate = new Beans_Vendor_Purchase_Invoice($this->_beans_data_auth((object) array('id' => $purchase->id, 'so_number' => $purchase->so_number, 'date_billed' => $purchase->date_billed, 'invoice_number' => $purchase->invoice_number, 'invoice_amount' => $purchase->invoice_amount, 'adjustment_description' => $purchase->adjustment_description, 'adjustment_account_id' => $purchase->adjustment_account_id, 'validate_only' => TRUE)));
         $vendor_purchase_invoice_validate_result = $vendor_purchase_invoice_validate->execute();
         if (!$vendor_purchase_invoice_validate_result->success) {
             return $this->_return_error($this->_beans_result_get_error($vendor_purchase_invoice_validate_result));
         }
     }
     $this->_return_object->data->purchases = array();
     // Go
     foreach ($purchases as $purchase) {
         $vendor_purchase_invoice_validate = new Beans_VEndor_Purchase_Invoice($this->_beans_data_auth((object) array('id' => $purchase->id, 'so_number' => $purchase->so_number, 'date_billed' => $purchase->date_billed, 'invoice_number' => $purchase->invoice_number, 'invoice_amount' => $purchase->invoice_amount, 'adjustment_description' => $purchase->adjustment_description, 'adjustment_account_id' => $purchase->adjustment_account_id)));
         $vendor_purchase_invoice_validate_result = $vendor_purchase_invoice_validate->execute();
         // Unexpected
         if (!$vendor_purchase_invoice_validate_result->success) {
             return $this->_return_error("An unexpected error has occurred:<br>" . $this->_beans_result_get_error($vendor_purchase_invoice_validate_result));
         }
         $html = new View_Partials_Vendors_Invoices_Purchase();
         $html->purchase = $vendor_purchase_invoice_validate_result->data->purchase;
         $vendor_purchase_invoice_validate_result->data->purchase->html = $html->render();
         $this->_return_object->data->purchases[] = $vendor_purchase_invoice_validate_result->data->purchase;
     }
 }
Beispiel #2
0
 protected function _execute()
 {
     if (!$this->_transaction_purchase_account_id) {
         throw new Exception("INTERNAL ERROR: Could not find default PO account.");
     }
     if (!$this->_transaction_purchase_line_account_id) {
         throw new Exception("INTERNAL ERROR: Could not find default PO Line account.");
     }
     if (!$this->_transaction_purchase_prepaid_purchase_account_id) {
         throw new Exception("INTERNAL ERROR: Could not find default deferred asset account.");
     }
     if (!$this->_transaction->loaded()) {
         throw new Exception("Transaction could not be found.");
     }
     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.");
     }
     // Formulate data request object for Beans_Account_Transaction_Create
     $update_transaction_data = new stdClass();
     $update_transaction_data->code = $this->_transaction->code;
     $update_transaction_data->description = isset($this->_data->description) ? $this->_data->description : NULL;
     $update_transaction_data->date = isset($this->_data->date) ? $this->_data->date : $this->_transaction->date;
     $update_transaction_data->reference = isset($this->_data->check_number) ? $this->_data->check_number : $this->_transaction->reference;
     $update_transaction_data->payment = "vendor";
     $purchase_account_transfers = array();
     $purchase_account_transfers_forms = array();
     $purchase_account_transfer_total = 0.0;
     $writeoff_account_transfer_total = 0.0;
     $writeoff_account_transfers_forms = array();
     // Write once for cleaner code
     $purchase_account_transfers[$this->_transaction_purchase_account_id] = 0.0;
     $purchase_account_transfers_forms[$this->_transaction_purchase_account_id] = array();
     $purchase_account_transfers[$this->_transaction_purchase_line_account_id] = 0.0;
     $purchase_account_transfers_forms[$this->_transaction_purchase_line_account_id] = array();
     $purchase_account_transfers[$this->_transaction_purchase_prepaid_purchase_account_id] = 0.0;
     $purchase_account_transfers_forms[$this->_transaction_purchase_prepaid_purchase_account_id] = array();
     if (!$this->_data->purchases or !count($this->_data->purchases)) {
         throw new Exception("Please provide at least one purchase for this payment.");
     }
     $vendor_id = FALSE;
     $handles_purchases_ids = array();
     foreach ($this->_data->purchases as $purchase_payment) {
         if (!isset($purchase_payment->purchase_id) or !$purchase_payment->purchase_id) {
             throw new Exception("Invalid payment purchase ID: none provided.");
         }
         $purchase = $this->_load_vendor_purchase($purchase_payment->purchase_id);
         if (!$purchase->loaded()) {
             throw new Exception("Invalid payment purchase: purchase not found.");
         }
         if (!$purchase_payment->amount) {
             throw new Exception("Invalid payment purchase amount: none provided.");
         }
         if (in_array($purchase->id, $handles_purchases_ids)) {
             throw new Exception("Invalid payment purchase: PO ID " . $purchase->id . " cannot be in payment more than once.");
         }
         $handles_purchases_ids[] = $purchase->id;
         if (!$vendor_id) {
             $vendor_id = $purchase->entity_id;
         } else {
             if ($vendor_id != $purchase->entity_id) {
                 throw new Exception("Invalid payment purchase " . $purchase->code . " included: vendor mismatch. All purchase purchases must belong to the same vendor.");
             }
         }
         if (!$purchase->date_billed and !$purchase->invoice_transaction_id and (isset($purchase_payment->invoice_number) and $purchase_payment->invoice_number or isset($purchase_payment->date_billed) and $purchase_payment->date_billed)) {
             $vendor_purchase_invoice = new Beans_Vendor_Purchase_Invoice($this->_beans_data_auth((object) array('id' => $purchase->id, 'invoice_number' => $purchase_payment->invoice_number, 'date_billed' => $purchase_payment->date_billed, 'validate_only' => $this->_validate_only)));
             $vendor_purchase_invoice_result = $vendor_purchase_invoice->execute();
             if (!$vendor_purchase_invoice_result->success) {
                 throw new Exception("Invalid purchase order invoice information for " . $purchase->code . ": " . $vendor_purchase_invoice_result->error);
             }
             // Reload the purchase
             $purchase = $this->_load_vendor_purchase($purchase_payment->purchase_id);
         } else {
             if ($purchase->date_billed and $purchase->invoice_transaction_id and (isset($purchase_payment->invoice_number) and $purchase_payment->invoice_number)) {
                 $vendor_purchase_update_invoice = new Beans_Vendor_Purchase_Update_Invoice($this->_beans_data_auth((object) array('id' => $purchase->id, 'invoice_number' => $purchase_payment->invoice_number, 'validate_only' => $this->_validate_only)));
                 $vendor_purchase_update_invoice_result = $vendor_purchase_update_invoice->execute();
                 if (!$vendor_purchase_update_invoice_result->success) {
                     throw new Exception("Invalid purchase order invoice information for " . $purchase->code . ": " . $vendor_purchase_update_invoice_result->error);
                 }
                 // Reload the purchase
                 $purchase = $this->_load_vendor_purchase($purchase_payment->purchase_id);
             }
         }
         if ($this->_validate_only) {
             return (object) array();
         }
         $purchase_id = $purchase->id;
         $purchase_balance = $this->_get_form_effective_balance($purchase, $update_transaction_data->date, $this->_transaction->id);
         $purchase_transfer_amount = $purchase_payment->amount;
         $purchase_writeoff_amount = (isset($purchase_payment->writeoff_balance) and $purchase_payment->writeoff_balance) ? $this->_beans_round($purchase_balance - $purchase_transfer_amount) : FALSE;
         $purchase_payment_amount = $purchase_writeoff_amount ? $this->_beans_round($purchase_transfer_amount + $purchase_writeoff_amount) : $purchase_transfer_amount;
         // Apply to Realized Accounts
         if ($purchase->date_billed and $purchase->invoice_transaction_id and strtotime($purchase->date_billed) <= strtotime($update_transaction_data->date) or $purchase->date_cancelled and $purchase->cancel_transaction_id and strtotime($purchase->date_cancelled) <= strtotime($update_transaction_data->date)) {
             // AP
             if (!isset($purchase_account_transfers[$purchase->account_id])) {
                 $purchase_account_transfers[$purchase->account_id] = 0.0;
             }
             if (!isset($purchase_account_transfers_forms[$purchase->account_id])) {
                 $purchase_account_transfers_forms[$purchase->account_id] = array();
             }
             $purchase_account_transfers[$purchase->account_id] = $this->_beans_round($purchase_account_transfers[$purchase->account_id] + $purchase_payment_amount);
             // Writeoff
             if ($purchase_writeoff_amount) {
                 $writeoff_account_transfer_total = $this->_beans_round($writeoff_account_transfer_total + $purchase_writeoff_amount);
             }
             $purchase_account_transfers_forms[$purchase->account_id][] = (object) array("form_id" => $purchase_id, "amount" => $purchase_payment_amount * -1, "writeoff_amount" => $purchase_writeoff_amount ? $purchase_writeoff_amount * -1 : NULL);
         } else {
             // Pending AP
             $purchase_account_transfers[$this->_transaction_purchase_account_id] = $this->_beans_round($purchase_account_transfers[$this->_transaction_purchase_account_id] + $purchase_payment_amount);
             // Pending AP
             $purchase_account_transfers[$this->_transaction_purchase_line_account_id] = $this->_beans_round($purchase_account_transfers[$this->_transaction_purchase_line_account_id] - $purchase_payment_amount);
             // Pending COGS
             $purchase_account_transfers[$this->_transaction_purchase_prepaid_purchase_account_id] = $this->_beans_round($purchase_account_transfers[$this->_transaction_purchase_prepaid_purchase_account_id] + $purchase_payment_amount);
             // Writeoff
             if ($purchase_writeoff_amount) {
                 $writeoff_account_transfer_total = $this->_beans_round($writeoff_account_transfer_total + $purchase_writeoff_amount);
             }
             $purchase_account_transfers_forms[$this->_transaction_purchase_account_id][] = (object) array("form_id" => $purchase_id, "amount" => $purchase_payment_amount * -1, "writeoff_amount" => $purchase_writeoff_amount ? $purchase_writeoff_amount * -1 : NULL);
         }
     }
     $vendor = $this->_load_vendor($vendor_id);
     // Keep the description clean.
     if ($update_transaction_data->description) {
         $update_transaction_data->description = strpos($update_transaction_data->description, "Vendor Payment Recorded: ") !== FALSE ? $update_transaction_data->description : "Vendor Payment Recorded: " . $update_transaction_data->description;
     } else {
         $update_transaction_data->description = "Vendor Payment Recorded: " . $vendor->company_name;
     }
     $writeoff_account = FALSE;
     if ($writeoff_account_transfer_total != 0.0) {
         // We need to add in a write-off.
         if (!isset($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($purchase_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.");
         }
         $purchase_account_transfers[$writeoff_account->id] = $writeoff_account_transfer_total;
         $purchase_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($purchase_account_transfers[$adjustment_account->id])) {
             throw new Exception("Invalid adjustment account ID: account cannot be tied to any other transaction in the payment.");
         }
         $purchase_account_transfers[$adjustment_account->id] = $this->_data->adjustment_amount * -1;
     }
     // All of the accounts on purchases are Accounts Payable and should be assets.
     // But to be on the safe side we're going to do table sign adjustments to be on the safe side.
     foreach ($purchase_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);
         }
         $purchase_account_transfers[$account_id] = ($writeoff_account and $writeoff_account->id == $account_id or $adjustment_account and $adjustment_account->id == $account_id) ? $transfer_amount * -1 * $payment_account->account_type->table_sign : $transfer_amount * $payment_account->account_type->table_sign;
     }
     $purchase_account_transfers[$payment_account->id] = $this->_data->amount * -1 * $payment_account->account_type->table_sign;
     if ($payment_account->account_type->table_sign > 0) {
         foreach ($purchase_account_transfers as $account_id => $transfer_amount) {
             $purchase_account_transfers[$account_id] = $transfer_amount * -1;
         }
     }
     $update_transaction_data->account_transactions = array();
     foreach ($purchase_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 == $payment_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($purchase_account_transfers_forms[$account_id])) {
             $account_transaction->forms = array();
             foreach ($purchase_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);
             }
         }
         $update_transaction_data->account_transactions[] = $account_transaction;
     }
     $update_transaction_data->id = $this->_transaction->id;
     $update_transaction_data->payment_type_handled = 'vendor';
     $update_transaction_data->entity_id = $vendor_id;
     $update_transaction = new Beans_Account_Transaction_Update($this->_beans_data_auth($update_transaction_data));
     $update_transaction_result = $update_transaction->execute();
     if (!$update_transaction_result->success) {
         throw new Exception("Update failure - could not convert transaction to payment: " . $update_transaction_result->error);
     }
     // Recalibrate Vendor Invoices / Cancellations
     $vendor_purchase_calibrate_invoice = new Beans_Vendor_Purchase_Calibrate_Invoice($this->_beans_data_auth((object) array('ids' => $handles_purchases_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' => $handles_purchases_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' => $handles_purchases_ids, 'after_payment_id' => $update_transaction_result->data->transaction->id)));
     $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("payment" => $this->_return_vendor_payment_element($this->_load_vendor_payment($update_transaction_result->data->transaction->id)));
 }
Beispiel #3
0
 protected function _execute()
 {
     if (!$this->_transaction_purchase_account_id) {
         throw new Exception("INTERNAL ERROR: Could not find default PO account.");
     }
     if (!$this->_transaction_purchase_line_account_id) {
         throw new Exception("INTERNAL ERROR: Could not find default PO Line account.");
     }
     if (!$this->_transaction_purchase_prepaid_purchase_account_id) {
         throw new Exception("INTERNAL ERROR: Could not find default deferred asset account.");
     }
     // Independently validate $this->_date_billed and $this->_invoice_number
     if ($this->_date_billed and $this->_date_billed != date("Y-m-d", strtotime($this->_date_billed))) {
         throw new Exception("Invalid invoice date: must be in YYYY-MM-DD format.");
     }
     if ($this->_invoice_number and strlen($this->_invoice_number) > 16) {
         throw new Exception("Invalid invoice number: maxmimum length of 16 characters.");
     }
     if ($this->_invoice_number and !$this->_date_billed) {
         throw new Exception("An invoice date is required if an invoice number is provided.");
     }
     $this->_purchase->entity_id = isset($this->_data->vendor_id) ? $this->_data->vendor_id : NULL;
     $this->_purchase->account_id = isset($this->_data->account_id) ? $this->_data->account_id : NULL;
     $this->_purchase->refund_form_id = isset($this->_data->refund_purchase_id) ? $this->_data->refund_purchase_id : NULL;
     $this->_purchase->sent = isset($this->_data->sent) ? $this->_data->sent : NULL;
     $this->_purchase->date_created = isset($this->_data->date_created) ? $this->_data->date_created : NULL;
     $this->_purchase->code = (isset($this->_data->purchase_number) and $this->_data->purchase_number) ? $this->_data->purchase_number : "AUTOGENERATE";
     $this->_purchase->reference = isset($this->_data->so_number) ? $this->_data->so_number : NULL;
     $this->_purchase->alt_reference = isset($this->_data->quote_number) ? $this->_data->quote_number : NULL;
     $this->_purchase->remit_address_id = isset($this->_data->remit_address_id) ? (int) $this->_data->remit_address_id : NULL;
     $this->_purchase->shipping_address_id = isset($this->_data->shipping_address_id) ? (int) $this->_data->shipping_address_id : NULL;
     if ($this->_date_billed and strtotime($this->_date_billed) < strtotime($this->_purchase->date_created)) {
         throw new Exception("Invalid invoice date: must be on or after the creation date of " . $this->_purchase->date_created . ".");
     }
     // Handle Default Account Payable
     // Vendor Default Account Payable
     if ($this->_purchase->account_id === NULL) {
         $vendor = $this->_load_vendor($this->_purchase->entity_id);
         if ($vendor->loaded() and $vendor->default_account_id) {
             $this->_purchase->account_id = $vendor->default_account_id;
         }
     }
     // Default Account Payable
     if ($this->_purchase->account_id === NULL) {
         $this->_purchase->account_id = $this->_beans_setting_get('account_default_payable');
     }
     // Make sure we have good purchase information before moving on.
     $this->_validate_vendor_purchase($this->_purchase);
     $this->_purchase->total = 0.0;
     $this->_purchase->amount = 0.0;
     if (!isset($this->_data->lines) or !is_array($this->_data->lines) or !count($this->_data->lines)) {
         throw new Exception("Invalid purchase lines: none provided.");
     }
     foreach ($this->_data->lines as $purchase_line) {
         $new_purchase_line = $this->_default_form_line();
         $new_purchase_line->account_id = isset($purchase_line->account_id) ? (int) $purchase_line->account_id : NULL;
         $new_purchase_line->description = isset($purchase_line->description) ? $purchase_line->description : NULL;
         $new_purchase_line->amount = isset($purchase_line->amount) ? $this->_beans_round($purchase_line->amount) : NULL;
         $new_purchase_line->quantity = isset($purchase_line->quantity) ? (double) $purchase_line->quantity : NULL;
         // Handle Default Cost of Goods
         if ($new_purchase_line->account_id === NULL) {
             $new_purchase_line->account_id = $this->_beans_setting_get('account_default_costofgoods');
         }
         $this->_validate_form_line($new_purchase_line);
         $new_purchase_line->total = $this->_beans_round($new_purchase_line->amount * $new_purchase_line->quantity);
         $new_purchase_line_total = $new_purchase_line->total;
         $this->_purchase->amount = $this->_beans_round($this->_purchase->amount + $new_purchase_line->total);
         $this->_purchase_lines[] = $new_purchase_line;
     }
     $this->_purchase->total = $this->_beans_round($this->_purchase->total + $this->_purchase->amount);
     // Validate Totals
     if ($this->_purchase->refund_form_id) {
         $refund_form = $this->_load_vendor_purchase($this->_purchase->refund_form_id);
         if (!$refund_form->loaded()) {
             throw new Exception("That refund_purchase_id was not found.");
         }
         $original_purchase = $refund_form;
         $refund_purchase = $this->_purchase;
         if ($original_purchase->total > 0.0 and $refund_purchase->total > 0.0 or $original_purchase->total < 0.0 and $refund_purchase->total < 0.0) {
             throw new Exception("Refund and original purchase totals must offset each other ( they cannot both be positive or negative ).");
         }
         if (abs($refund_purchase->total) > abs($original_purchase->total)) {
             throw new Exception("The refund total cannot be greater than the original purchase total.");
         }
     }
     // Save Purchase + Children
     $this->_purchase->save();
     if ($this->_purchase->code == "AUTOGENERATE") {
         $this->_purchase->code = $this->_purchase->id;
     }
     foreach ($this->_purchase_lines as $j => $purchase_line) {
         $purchase_line->form_id = $this->_purchase->id;
         $purchase_line->save();
     }
     $this->_purchase->save();
     $purchase_calibrate = new Beans_Vendor_Purchase_Calibrate($this->_beans_data_auth((object) array('ids' => array($this->_purchase->id))));
     $purchase_calibrate_result = $purchase_calibrate->execute();
     if (!$purchase_calibrate_result->success) {
         // We've had an account transaction failure and need to delete the purchase we just created.
         $delete_purchase = new Beans_Vendor_Purchase_Delete($this->_beans_data_auth((object) array('id' => $this->_purchase->id)));
         $delete_purchase_result = $delete_purchase->execute();
         // V2Item
         // Fatal error!  Ensure coverage or ascertain 100% success.
         if (!$delete_purchase_result->success) {
             throw new Exception("Error creating account transaction for purchase purchase. " . "COULD NOT DELETE PURCHASE ORDER! " . $delete_purchase_result->error);
         }
         throw new Exception("Error trying to create purchase: " . $purchase_calibrate_result->error);
     }
     // Reload the sale.
     $this->_purchase = $this->_load_vendor_purchase($this->_purchase->id);
     if ($this->_date_billed) {
         $vendor_purchase_invoice = new Beans_Vendor_Purchase_Invoice($this->_beans_data_auth((object) array('id' => $this->_purchase->id, 'date_billed' => $this->_date_billed, 'invoice_number' => $this->_invoice_number)));
         $vendor_purchase_invoice_result = $vendor_purchase_invoice->execute();
         // If it fails - we undo everything.
         if (!$vendor_purchase_invoice_result->success) {
             $vendor_purchase_delete = new Beans_Vendor_Purchase_Delete($this->_beans_data_auth((object) array('id' => $this->_purchase->id)));
             $vendor_purchase_delete_result = $vendor_purchase_delete->execute();
             if (!$vendor_purchase_delete_result->success) {
                 throw new Exception("Error creating account transaction for purchase invoice." . "COULD NOT DELETE PURCHASE! " . $vendor_purchase_delete_result->error . ' ' . $vendor_purchase_invoice_result->error);
             }
             throw new Exception("Error creating purchase invoice transaction: " . $vendor_purchase_invoice_result->error);
         }
         return $this->_beans_return_internal_result($vendor_purchase_invoice_result);
     }
     // We need to reload the purchase so that we can get the correct balance, etc.
     $this->_purchase = $this->_load_vendor_purchase($this->_purchase->id);
     return (object) array("purchase" => $this->_return_vendor_purchase_element($this->_purchase));
 }