Pass Customfields from Quotes to Invoice


#1

Hi everyone

First I would like to thank Kovah for this amazing project. Keep up the good work.

I want to give you some background information about what i need invoiceplane for and which use-case I want to cover:

We generally create an offer for each order. Since we rent material I have added two custom fields. One for the start of the rental period and one for the end of the rental period. The fields are displayed online (webview) as well as in PDF - so far so good.

When an order is confirmed we create the invoice directly from the offer (modal_quote_to_invoice). The invoice has the same custom fields as the offer, but these fields are not taken over - I want to automate this now.

My first approach was passing the value of the custom field(s) to the corresponding site. I did this in the file: modal_quote_to_invoice.php like this: (see the last field)

        // Creates the invoice
        $('#quote_to_invoice_confirm').click(function () {
            $.post("<?php echo site_url('quotes/ajax/quote_to_invoice'); ?>", {
                    quote_id: <?php echo $quote_id; ?>,
                    client_id: $('#client_id').val(),
                    invoice_date_created: $('#invoice_date_created').val(),
                    invoice_time_created: '<?php echo date('H:i:s') ?>',
                    invoice_group_id: $('#invoice_group_id').val(),
                    invoice_password: $('#invoice_password').val(),
                    user_id: $('#user_id').val(),
                    miete_von: $('[name="custom[1]"]').val()
                },

And surprisingly this seems to work just fine.
fieldsend

From now on I’m a bit lost. I think the data is passed tho this method in the file: Ajax.php under application/modules/quotes/controllers

    public function quote_to_invoice()
    {
        $this->load->model(
            array(
                'invoices/mdl_invoices',
                'invoices/mdl_items',
                'quotes/mdl_quotes',
                'quotes/mdl_quote_items',
                'invoices/mdl_invoice_tax_rates',
                'quotes/mdl_quote_tax_rates'
            )
        );

        if ($this->mdl_invoices->run_validation()) {
            // Get the quote
            $quote = $this->mdl_quotes->get_by_id($this->input->post('quote_id'));

            $invoice_id = $this->mdl_invoices->create(null, false);

            // Update the discounts
            $this->db->where('invoice_id', $invoice_id);
            $this->db->set('invoice_discount_amount', $quote->quote_discount_amount);
            $this->db->set('invoice_discount_percent', $quote->quote_discount_percent);
            $this->db->update('ip_invoices');

            // Save the invoice id to the quote
            $this->db->where('quote_id', $this->input->post('quote_id'));
            $this->db->set('invoice_id', $invoice_id);
            $this->db->update('ip_quotes');

            $quote_items = $this->mdl_quote_items->where('quote_id', $this->input->post('quote_id'))->get()->result();

            foreach ($quote_items as $quote_item) {
                $db_array = array(
                    'invoice_id' => $invoice_id,
                    'item_tax_rate_id' => $quote_item->item_tax_rate_id,
                    'item_product_id' => $quote_item->item_product_id,
                    'item_name' => $quote_item->item_name,
                    'item_description' => $quote_item->item_description,
                    'item_quantity' => $quote_item->item_quantity,
                    'item_price' => $quote_item->item_price,
                    'item_product_unit_id' => $quote_item->item_product_unit_id,
                    'item_product_unit' => $quote_item->item_product_unit,
                    'item_discount_amount' => $quote_item->item_discount_amount,
                    'item_order' => $quote_item->item_order
                );

                $this->mdl_items->save(null, $db_array);
            }

            $quote_tax_rates = $this->mdl_quote_tax_rates->where('quote_id', $this->input->post('quote_id'))->get()->result();

            foreach ($quote_tax_rates as $quote_tax_rate) {
                $db_array = array(
                    'invoice_id' => $invoice_id,
                    'tax_rate_id' => $quote_tax_rate->tax_rate_id,
                    'include_item_tax' => $quote_tax_rate->include_item_tax,
                    'invoice_tax_rate_amount' => $quote_tax_rate->quote_tax_rate_amount
                );

                $this->mdl_invoice_tax_rates->save(null, $db_array);
            }

            $response = array(
                'success' => 1,
                'invoice_id' => $invoice_id
            );
        } else {
            $this->load->helper('json_error');
            $response = array(
                'success' => 0,
                'validation_errors' => json_errors()
            );
        }

        echo json_encode($response);
    }

So I would have to save the data somehow in the new created invoice. Maybe in a similiar way it is done in the save process. But I pass the data so it wouldn’t be necessary to get it out of the DB.

// Save all custom fields
        if ($this->input->post('custom')) {
            $db_array = array();

            $values = [];
            foreach ($this->input->post('custom') as $custom) {
                if (preg_match("/^(.*)\[\]$/i", $custom['name'], $matches)) {
                    $values[$matches[1]][] = $custom['value'];
                } else {
                    $values[$custom['name']] = $custom['value'];
                }
            }

            foreach ($values as $key => $value) {
                preg_match("/^custom\[(.*?)\](?:\[\]|)$/", $key, $matches);
                if ($matches) {
                    $db_array[$matches[1]] = $value;
                }
            }
            $this->load->model('custom_fields/mdl_quote_custom');
            $result = $this->mdl_quote_custom->save_custom($quote_id, $db_array);
            if ($result !== true) {
                $response = array(
                    'success' => 0,
                    'validation_errors' => $result
                );

                echo json_encode($response);
                exit;
            }
        }

        echo json_encode($response);
    }

Can anyone help me out here? Are ther some working solutions for this use-case? Maybe I’m going for a wrong approach.

Best regards
Ramon


#2

Hi Roman

It may need to be stored in the database along with the other values to ensure that if the Invoice was to be recalled again, it would contain all the correct information, in which case it would need a slight adjustment to the tables within the database to store the value and then display it.

I’d need to confirm this and will get one of the developers to give a better response on it.

Daniel