xmlNodePtr
gnc_owner_to_dom_tree (const char* tag, const GncOwner* owner)
{
    xmlNodePtr ret;
    const char* type_str;

    switch (gncOwnerGetType (owner))
    {
    case GNC_OWNER_CUSTOMER:
        type_str = GNC_ID_CUSTOMER;
        break;
    case GNC_OWNER_JOB:
        type_str = GNC_ID_JOB;
        break;
    case GNC_OWNER_VENDOR:
        type_str = GNC_ID_VENDOR;
        break;
    case GNC_OWNER_EMPLOYEE:
        type_str = GNC_ID_EMPLOYEE;
        break;
    default:
        PWARN ("Invalid owner type: %d", gncOwnerGetType (owner));
        return NULL;
    }

    ret = xmlNewNode (NULL, BAD_CAST tag);
    xmlSetProp (ret, BAD_CAST "version", BAD_CAST owner_version_string);

    xmlAddChild (ret, text_to_dom_tree (owner_type_string, type_str));
    xmlAddChild (ret, guid_to_dom_tree (owner_id_string,
                                        gncOwnerGetGUID (owner)));

    return ret;
}
Beispiel #2
0
static void
gnc_invoice_select_search_set_label(GncISI* isi)
{
    GncOwnerType owner_type;
    char *label;

    g_assert(isi);
    if (!isi->label) return;

    owner_type = gncOwnerGetType(gncOwnerGetEndOwner(&isi->owner));

    /* Translators:  See comments in dialog-invoice.c:gnc_invoice_search() */
    switch (owner_type)
    {
    case GNC_OWNER_VENDOR:
        label = _("Bill");
        break;
    case GNC_OWNER_EMPLOYEE:
        label = _("Voucher");
        break;
    default:
        label = _("Invoice");
        break;
    }

    gtk_label_set_text(GTK_LABEL(isi->label), label);
}
Beispiel #3
0
static void load_payment_type_cells (GncEntryLedger *ledger)
{
    ComboCell *cell;
    const GncOwner *owner;
    GncEmployee *employee;

    cell = (ComboCell *) gnc_table_layout_get_cell (ledger->table->layout,
            ENTRY_PAYMENT_CELL);
    if (!cell) return;

    if (!ledger->invoice) return;

    owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (ledger->invoice));
    if (gncOwnerGetType (owner) != GNC_OWNER_EMPLOYEE)
        return;

    employee = gncOwnerGetEmployee (owner);
    g_return_if_fail (employee);

    gnc_combo_cell_clear_menu (cell);
    gnc_combo_cell_add_menu_item (cell, _("Cash"));

    if (gncEmployeeGetCCard (employee))
        gnc_combo_cell_add_menu_item (cell, _("Charge"));
}
Beispiel #4
0
static void gncJobFree (GncJob *job)
{
    if (!job) return;

    qof_event_gen (&job->inst, QOF_EVENT_DESTROY, NULL);

    CACHE_REMOVE (job->id);
    CACHE_REMOVE (job->name);
    CACHE_REMOVE (job->desc);

    switch (gncOwnerGetType (&(job->owner)))
    {
    case GNC_OWNER_CUSTOMER:
        gncCustomerRemoveJob (gncOwnerGetCustomer(&job->owner), job);
        break;
    case GNC_OWNER_VENDOR:
        gncVendorRemoveJob (gncOwnerGetVendor(&job->owner), job);
        break;
    default:
        break;
    }

    /* qof_instance_release (&job->inst); */
    g_object_unref (job);
}
Beispiel #5
0
void gncJobSetOwner (GncJob *job, GncOwner *owner)
{
    if (!job) return;
    if (!owner) return;
    if (gncOwnerEqual (owner, &(job->owner))) return;

    switch (gncOwnerGetType (owner))
    {
    case GNC_OWNER_CUSTOMER:
    case GNC_OWNER_VENDOR:
        break;
    default:
        PERR("Unsupported Owner type: %d", gncOwnerGetType(owner));
        return;
    }

    gncJobBeginEdit (job);

    switch (gncOwnerGetType (&(job->owner)))
    {
    case GNC_OWNER_CUSTOMER:
        gncCustomerRemoveJob (gncOwnerGetCustomer(&job->owner), job);
        break;
    case GNC_OWNER_VENDOR:
        gncVendorRemoveJob (gncOwnerGetVendor(&job->owner), job);
        break;
    default:
        break;
    }

    gncOwnerCopy (owner, &(job->owner));

    switch (gncOwnerGetType (&(job->owner)))
    {
    case GNC_OWNER_CUSTOMER:
        gncCustomerAddJob (gncOwnerGetCustomer(&job->owner), job);
        break;
    case GNC_OWNER_VENDOR:
        gncVendorAddJob (gncOwnerGetVendor(&job->owner), job);
        break;
    default:
        break;
    }

    mark_job (job);
    gncJobCommitEdit (job);
}
Beispiel #6
0
JobWindow *
gnc_ui_job_new (GncOwner *ownerp, QofBook *bookp)
{
    JobWindow *jw;
    GncOwner owner;

    /* Make sure required options exist */
    if (!bookp) return NULL;

    if (ownerp)
    {
        g_return_val_if_fail ((gncOwnerGetType (ownerp) == GNC_OWNER_CUSTOMER) ||
                              (gncOwnerGetType (ownerp) == GNC_OWNER_VENDOR),
                              NULL);
        gncOwnerCopy (ownerp, &owner);
    }
    else
        gncOwnerInitCustomer (&owner, NULL); /* XXX */

    jw = gnc_job_new_window (bookp, &owner, NULL);
    return jw;
}
Beispiel #7
0
void gncOwnerAttachToLot (const GncOwner *owner, GNCLot *lot)
{
     if (!owner || !lot)
        return;

    gnc_lot_begin_edit (lot);

    qof_instance_set (QOF_INSTANCE (lot),
		      "owner-type", (gint64)gncOwnerGetType (owner),
		      "owner-guid", gncOwnerGetGUID (owner),
		      NULL);
    gnc_lot_commit_edit (lot);
}
static void
gnc_plugin_page_owner_tree_cmd_new_invoice (GtkAction *action,
        GncPluginPageOwnerTree *page)
{
    GncPluginPageOwnerTreePrivate *priv;
    GncOwner current_owner;

    ENTER("action %p, page %p", action, page);

    priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
    switch (priv->owner_type)
    {
    case GNC_OWNER_NONE :
    case GNC_OWNER_UNDEFINED :
        gncOwnerInitUndefined(&current_owner, NULL);
        break;
    case GNC_OWNER_CUSTOMER :
    {
        gncOwnerInitCustomer(&current_owner,
                             gncOwnerGetCustomer(gnc_plugin_page_owner_tree_get_current_owner (page)) );
        break;
    }
    case GNC_OWNER_JOB :
    {
        gncOwnerInitJob(&current_owner,
                        gncOwnerGetJob(gnc_plugin_page_owner_tree_get_current_owner (page)) );
        break;
    }
    case GNC_OWNER_VENDOR :
    {
        gncOwnerInitVendor(&current_owner,
                           gncOwnerGetVendor(gnc_plugin_page_owner_tree_get_current_owner (page)) );
        break;
    }
    case GNC_OWNER_EMPLOYEE :
    {
        gncOwnerInitEmployee(&current_owner,
                             gncOwnerGetEmployee(gnc_plugin_page_owner_tree_get_current_owner (page)) );
        break;
    }
    }

    if (gncOwnerGetType(&current_owner) != GNC_OWNER_UNDEFINED)
        gnc_ui_invoice_new (&current_owner, gnc_get_current_book());

    LEAVE(" ");
}
Beispiel #9
0
GList *
gncOwnerGetAccountTypesList (const GncOwner *owner)
{
    g_return_val_if_fail (owner, NULL);

    switch (gncOwnerGetType (owner))
    {
    case GNC_OWNER_CUSTOMER:
        return (g_list_prepend (NULL, (gpointer)ACCT_TYPE_RECEIVABLE));
    case GNC_OWNER_VENDOR:
    case GNC_OWNER_EMPLOYEE:
        return (g_list_prepend (NULL, (gpointer)ACCT_TYPE_PAYABLE));
        break;
    default:
        return (g_list_prepend (NULL, (gpointer)ACCT_TYPE_NONE));
    }
}
Beispiel #10
0
/* XXX This code is a cut-n-paste job from the SplitRegister code;
 * the split-register should be generalized to the point where a cut-n-paste
 * like this isn't required, and this should be trashed.
 */
void gnc_entry_ledger_load (GncEntryLedger *ledger, GList *entry_list)
{
    GncEntry *blank_entry, *find_entry;
    CursorBuffer *cursor_buffer;
    Table *table;

    GList *node;
    CellBlock *cursor_header, *cursor;
    VirtualCellLocation vcell_loc;
    VirtualLocation save_loc;
    gboolean start_primary_color = TRUE;

    int new_entry_row = -1;

    if (!ledger) return;

    /* Load up cells */
    load_discount_type_cells (ledger);
    load_discount_how_cells (ledger);
    gnc_entry_ledger_load_xfer_cells (ledger);

    blank_entry = gnc_entry_ledger_get_blank_entry (ledger);

    if (blank_entry == NULL && ledger->invoice == NULL && entry_list == NULL)
        return;

    if (blank_entry == NULL && ledger->invoice)
    {
        switch (ledger->type)
        {
        case GNCENTRY_ORDER_ENTRY:
        case GNCENTRY_INVOICE_ENTRY:
        case GNCENTRY_BILL_ENTRY:
        case GNCENTRY_EXPVOUCHER_ENTRY:
        case GNCENTRY_CUST_CREDIT_NOTE_ENTRY:
        case GNCENTRY_VEND_CREDIT_NOTE_ENTRY:
        case GNCENTRY_EMPL_CREDIT_NOTE_ENTRY:

            gnc_suspend_gui_refresh ();

            blank_entry = gncEntryCreate (ledger->book);
            gncEntrySetDateGDate (blank_entry, &ledger->last_date_entered);
            ledger->blank_entry_guid = *gncEntryGetGUID (blank_entry);

            gnc_resume_gui_refresh ();

            /* The rest of this does not apply to expense vouchers */
            if (ledger->type != GNCENTRY_EXPVOUCHER_ENTRY)
            {
                const GncOwner *owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (ledger->invoice));
                GncTaxTable *table = NULL;
                GncTaxIncluded taxincluded_p = GNC_TAXINCLUDED_USEGLOBAL;
                gboolean taxincluded = FALSE;
                gnc_numeric discount = gnc_numeric_zero ();
                gnc_numeric price = gnc_numeric_zero ();

                /* Determine the Price from Customer's or Vendor's Job */
                switch (gncOwnerGetType (gncInvoiceGetOwner (ledger->invoice)))
                {
                case GNC_OWNER_JOB:
                    price = gncJobGetRate( gncOwnerGetJob (gncInvoiceGetOwner (ledger->invoice)));
                    break;
                default:
                    break;
                }

                /* Determine the TaxIncluded and Discount values */
                switch (gncOwnerGetType (owner))
                {
                case GNC_OWNER_CUSTOMER:
                    taxincluded_p = gncCustomerGetTaxIncluded (owner->owner.customer);
                    discount = gncCustomerGetDiscount (owner->owner.customer);
                    break;
                case GNC_OWNER_VENDOR:
                    taxincluded_p = gncVendorGetTaxIncluded (owner->owner.vendor);
                    break;
                default:
                    break;
                }

                /* Compute the default taxincluded */
                switch (taxincluded_p)
                {
                case GNC_TAXINCLUDED_YES:
                    taxincluded = TRUE;
                    break;
                case GNC_TAXINCLUDED_NO:
                    taxincluded = FALSE;
                    break;
                case GNC_TAXINCLUDED_USEGLOBAL:
                    if (ledger->prefs_group)
                    {
                        taxincluded = gnc_prefs_get_bool (ledger->prefs_group, GNC_PREF_TAX_INCL);
                    }
                    else
                    {
                        taxincluded = FALSE;
                    }
                    break;
                }

                /* Compute the proper taxtable */
                switch (gncOwnerGetType (owner))
                {
                case GNC_OWNER_CUSTOMER:
                    table = gnc_business_get_default_tax_table (ledger->book,
                            GNC_OWNER_CUSTOMER);

                    if (gncCustomerGetTaxTableOverride (owner->owner.customer))
                        table = gncCustomerGetTaxTable (owner->owner.customer);
                    break;

                case GNC_OWNER_VENDOR:
                    table = gnc_business_get_default_tax_table (ledger->book,
                            GNC_OWNER_VENDOR);

                    if (gncVendorGetTaxTableOverride (owner->owner.vendor))
                        table = gncVendorGetTaxTable (owner->owner.vendor);
                    break;

                default:
                    break;
                }

                if (ledger->is_cust_doc)
                {
                    gncEntrySetInvTaxTable (blank_entry, table);
                    gncEntrySetInvTaxIncluded (blank_entry, taxincluded);
                    gncEntrySetInvDiscount (blank_entry, discount);
                    gncEntrySetInvPrice (blank_entry, price);
                }
                else
                {
                    gncEntrySetBillTaxTable (blank_entry, table);
                    gncEntrySetBillTaxIncluded (blank_entry, taxincluded);
                    gncEntrySetBillPrice (blank_entry, price);
                }
            }

            break;
        default:
            ledger->blank_entry_guid = *guid_null ();
            break;
        }
        ledger->blank_entry_edited = FALSE;
    }

    table = ledger->table;

    gnc_table_leave_update (table, table->current_cursor_loc);
    save_loc = table->current_cursor_loc;

    /* Figure out where we are going to */
    if (ledger->traverse_to_new)
    {
        find_entry = blank_entry;
    }
    else if (ledger->hint_entry)
    {
        find_entry = ledger->hint_entry;
    }
    else
    {
        find_entry = gnc_entry_ledger_get_current_entry(ledger);
        /* XXX: get current entry (cursor_hint_xxx) */
    }

    /* If the current cursor has changed we save the values for later
     * possible restoration. */
    if (gnc_table_current_cursor_changed (table, TRUE) &&
            (find_entry == gnc_entry_ledger_get_current_entry (ledger)))
    {
        cursor_buffer = gnc_cursor_buffer_new ();
        gnc_table_save_current_cursor (table, cursor_buffer);
    }
    else
        cursor_buffer = NULL;

    /* disable move callback -- we don't want the cascade of
     * callbacks while we are fiddling with loading the register */
    gnc_table_control_allow_move (table->control, FALSE);

    /* invalidate the cursor */
    {
        VirtualLocation virt_loc;

        virt_loc.vcell_loc.virt_row = -1;
        virt_loc.vcell_loc.virt_col = -1;
        virt_loc.phys_row_offset = -1;
        virt_loc.phys_col_offset = -1;

        gnc_table_move_cursor_gui (table, virt_loc);
    }

    /* make sure that the header is loaded */
    vcell_loc.virt_row = 0;
    vcell_loc.virt_col = 0;
    cursor_header = gnc_table_layout_get_cursor (table->layout, CURSOR_HEADER);
    gnc_table_set_vcell (table, cursor_header, NULL, TRUE, TRUE, vcell_loc);
    vcell_loc.virt_row++;

    /* get the current time and reset the dividing row */
    table->model->dividing_row_upper = -1;
    table->model->dividing_row = -1;
    table->model->dividing_row_lower = -1;
    cursor = gnc_table_layout_get_cursor (table->layout, "cursor");

    /* Populate the table */
    for (node = entry_list; node; node = node->next)
    {
        GncEntry *entry = node->data;

        /* Don't load the blank entry */
        if (entry == blank_entry)
            continue;

        /* If this is the first load of the ledger, fill the quickfill cells */
        {
            /* XXX */
        }

        if (entry == find_entry)
            new_entry_row = vcell_loc.virt_row;

        gnc_table_set_vcell (table, cursor, gncEntryGetGUID (entry),
                             TRUE, start_primary_color, vcell_loc);
        vcell_loc.virt_row++;

        /* Flip color for the next guy */
        start_primary_color = !start_primary_color;
    }

    /* Add the blank entry at the end. */
    if (blank_entry)
    {
        gnc_table_set_vcell (table, cursor, gncEntryGetGUID (blank_entry),
                             TRUE, start_primary_color, vcell_loc);

        if (find_entry == blank_entry)
            new_entry_row = vcell_loc.virt_row;

        vcell_loc.virt_row++;
    }

    /* Resize the table */
    gnc_table_set_size (table, vcell_loc.virt_row, 1);

    /* Restore the cursor to its rightful position */
    if (new_entry_row > 0)
        save_loc.vcell_loc.virt_row = new_entry_row;

    if (gnc_table_find_close_valid_cell (table, &save_loc, FALSE))
    {
        gnc_table_move_cursor_gui (table, save_loc);

        if (find_entry == gnc_entry_ledger_get_current_entry (ledger))
            gnc_table_restore_current_cursor (table, cursor_buffer);
    }

    gnc_cursor_buffer_destroy (cursor_buffer);
    cursor_buffer = NULL;

    /* Reset the ledger */
    ledger->traverse_to_new = FALSE;
    ledger->hint_entry = NULL;

    /* Set the cell fractions */


    gnc_table_refresh_gui (table, TRUE);
    gnc_entry_ledger_show_entry (ledger, table->current_cursor_loc.vcell_loc);

    /* Set completion character */
    gnc_combo_cell_set_complete_char
    ((ComboCell *)
     gnc_table_layout_get_cell (table->layout, ENTRY_IACCT_CELL),
     gnc_get_account_separator ());

    gnc_combo_cell_set_complete_char
    ((ComboCell *)
     gnc_table_layout_get_cell (table->layout, ENTRY_BACCT_CELL),
     gnc_get_account_separator ());

    /* enable callback for cursor user-driven moves */
    gnc_table_control_allow_move (table->control, TRUE);
}
Beispiel #11
0
gboolean gncOwnerEqual (const GncOwner *a, const GncOwner *b)
{
    if (!a || !b) return FALSE;
    if (gncOwnerGetType (a) != gncOwnerGetType (b)) return FALSE;
    return (a->owner.undefined == b->owner.undefined);
}
Beispiel #12
0
void
gnc_payment_ok_cb (GtkWidget *widget, gpointer data)
{
    PaymentWindow *pw = data;
    const char *text = NULL;

    if (!pw)
        return;

    /* The gnc_payment_window_check_payment function
     * ensures we have valid owner, post account, transfer account
     * and amount so we can proceed with the payment.
     * Note: make sure it's called before all entry points to this function !
     */
    gnc_suspend_gui_refresh ();
    {
        const char *memo, *num;
        Timespec date;
        gnc_numeric exch = gnc_numeric_create(1, 1); //default to "one to one" rate
        GList *selected_lots = NULL;
        GtkTreeSelection *selection;
        gboolean auto_pay;

        /* Obtain all our ancillary information */
        memo = gtk_entry_get_text (GTK_ENTRY (pw->memo_entry));
        num = gtk_entry_get_text (GTK_ENTRY (pw->num_entry));
        date = gnc_date_edit_get_date_ts (GNC_DATE_EDIT (pw->date_edit));

        /* Obtain the list of selected lots (documents/payments) from the dialog */
        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(pw->docs_list_tree_view));
        gtk_tree_selection_selected_foreach (selection, get_selected_lots, &selected_lots);

        /* When the payment amount is 0, the selected documents cancel each other out
         * so no money is actually transferred.
         * For non-zero payments money will be transferred between the post account
         * and the transfer account. In that case if these two accounts don't have
         * the same currency the user is asked to enter the exchange rate.
         */
        if (!gnc_numeric_zero_p (pw->amount_tot) &&
            !gnc_commodity_equal(xaccAccountGetCommodity(pw->xfer_acct), xaccAccountGetCommodity(pw->post_acct)))
        {
            XferDialog* xfer;

            text = _("The transfer and post accounts are associated with different currencies. Please specify the conversion rate.");

            xfer = gnc_xfer_dialog(pw->dialog, pw->xfer_acct);
            gnc_info_dialog(pw->dialog, "%s", text);

            gnc_xfer_dialog_select_to_account(xfer, pw->post_acct);
            gnc_xfer_dialog_set_amount(xfer, pw->amount_tot);

            /* All we want is the exchange rate so prevent the user from thinking
               it makes sense to mess with other stuff */
            gnc_xfer_dialog_set_from_show_button_active(xfer, FALSE);
            gnc_xfer_dialog_set_to_show_button_active(xfer, FALSE);
            gnc_xfer_dialog_hide_from_account_tree(xfer);
            gnc_xfer_dialog_hide_to_account_tree(xfer);
            gnc_xfer_dialog_is_exchange_dialog(xfer, &exch);
            gnc_xfer_dialog_run_until_done(xfer);
        }

        /* Perform the payment */
        if (gncOwnerGetType (&(pw->owner)) == GNC_OWNER_CUSTOMER)
            auto_pay = gnc_prefs_get_bool (GNC_PREFS_GROUP_INVOICE, GNC_PREF_AUTO_PAY);
        else
            auto_pay = gnc_prefs_get_bool (GNC_PREFS_GROUP_BILL, GNC_PREF_AUTO_PAY);

        gncOwnerApplyPayment (&pw->owner, pw->pre_existing_txn, selected_lots,
                              pw->post_acct, pw->xfer_acct, pw->amount_tot,
                              exch, date, memo, num, auto_pay);
    }
    gnc_resume_gui_refresh ();

    /* Save the transfer account, xfer_acct */
    gnc_payment_dialog_remember_account(pw, pw->xfer_acct);

    gnc_ui_payment_window_destroy (pw);
}
Beispiel #13
0
static PaymentWindow *
new_payment_window (GncOwner *owner, QofBook *book, GncInvoice *invoice)
{
    PaymentWindow *pw;
    GtkBuilder *builder;
    GtkWidget *box, *label, *credit_box, *debit_box;
    GtkTreeSelection *selection;
    GtkTreeViewColumn *column;
    GtkCellRenderer *renderer;
    char * cm_class = (gncOwnerGetType (owner) == GNC_OWNER_CUSTOMER ?
                       DIALOG_PAYMENT_CUSTOMER_CM_CLASS :
                       DIALOG_PAYMENT_VENDOR_CM_CLASS);

    /*
     * Find an existing payment window.  If found, bring it to
     * the front.  If we have an actual owner, then set it in
     * the window.
     */

    pw = gnc_find_first_gui_component (cm_class, find_handler, NULL);
    if (pw)
    {
        if (gncOwnerIsValid(owner))
            gnc_payment_set_owner (pw, owner);

        // Reset the setting about the pre-existing TXN
        pw->pre_existing_txn = NULL;

        gtk_window_present (GTK_WINDOW(pw->dialog));
        return(pw);
    }

    /* Ok, we need a new window */

    pw = g_new0 (PaymentWindow, 1);
    pw->book = book;
    gncOwnerCopy (owner, &(pw->owner));

    /* Compute the post-to account types */
    pw->acct_types = gncOwnerGetAccountTypesList (owner);

    if (gncOwnerIsValid(owner))
        pw->acct_commodities = gncOwnerGetCommoditiesList (owner);

    /* Open and read the Glade File */
    builder = gtk_builder_new();
    gnc_builder_add_from_file (builder, "dialog-payment.glade", "docs_list_hor_adj");
    gnc_builder_add_from_file (builder, "dialog-payment.glade", "docs_list_vert_adj");
    gnc_builder_add_from_file (builder, "dialog-payment.glade", "docs_list_model");
    gnc_builder_add_from_file (builder, "dialog-payment.glade", "post_combo_model");
    gnc_builder_add_from_file (builder, "dialog-payment.glade", "Payment Dialog");
    pw->dialog = GTK_WIDGET (gtk_builder_get_object (builder, "Payment Dialog"));

    /* Grab the widgets and build the dialog */
    pw->payment_warning = GTK_WIDGET (gtk_builder_get_object (builder, "payment_warning"));
    pw->ok_button = GTK_WIDGET (gtk_builder_get_object (builder, "okbutton"));
    pw->num_entry = GTK_WIDGET (gtk_builder_get_object (builder, "num_entry"));
    pw->memo_entry = GTK_WIDGET (gtk_builder_get_object (builder, "memo_entry"));
    pw->post_combo = GTK_WIDGET (gtk_builder_get_object (builder, "post_combo"));
    gtk_combo_box_set_entry_text_column( GTK_COMBO_BOX( pw->post_combo ), 0 );
    gnc_cbwe_require_list_item(GTK_COMBO_BOX(pw->post_combo));

    label = GTK_WIDGET (gtk_builder_get_object (builder, "owner_label"));
    box = GTK_WIDGET (gtk_builder_get_object (builder, "owner_box"));
    pw->owner_choice = gnc_owner_select_create (label, box, book, owner);

    /* Some terminology:
     * Invoices are paid, credit notes are refunded.
     * A customer payment is a credit action, paying a vendor is debit
     *
     * So depending on the owner the payment amount should be considered
     * credit (customer) or debit (vendor/employee) and refunds should be
     * considered debit (customer) or credit (vendor/employee).
     * For visual consistency, the dialog box will always show a payment and
     * a refund field. Internally they are treated as credit or debit depending
     * on the owner type.
     */
    if (gncOwnerGetType (owner) == GNC_OWNER_CUSTOMER)
    {
        debit_box = GTK_WIDGET (gtk_builder_get_object (builder, "amount_refund_box"));
        credit_box = GTK_WIDGET (gtk_builder_get_object (builder, "amount_payment_box"));
    }
    else
    {
        debit_box = GTK_WIDGET (gtk_builder_get_object (builder, "amount_payment_box"));
        credit_box = GTK_WIDGET (gtk_builder_get_object (builder, "amount_refund_box"));
    }

    pw->amount_debit_edit = gnc_amount_edit_new ();
    gtk_box_pack_start (GTK_BOX (debit_box), pw->amount_debit_edit, TRUE, TRUE, 0);
    gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (pw->amount_debit_edit),
                                           TRUE);
    gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (pw->amount_debit_edit), gnc_numeric_zero());
    g_signal_connect(G_OBJECT(gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(pw->amount_debit_edit))),
                     "focus-out-event",
                     G_CALLBACK(gnc_payment_leave_amount_cb), pw);

    pw->amount_credit_edit = gnc_amount_edit_new ();
    gtk_box_pack_start (GTK_BOX (credit_box), pw->amount_credit_edit, TRUE, TRUE, 0);
    gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (pw->amount_credit_edit),
                                           TRUE);
    gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (pw->amount_credit_edit), gnc_numeric_zero());
    g_signal_connect(G_OBJECT(gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(pw->amount_credit_edit))),
                     "focus-out-event",
                     G_CALLBACK(gnc_payment_leave_amount_cb), pw);

    box = GTK_WIDGET (gtk_builder_get_object (builder, "date_box"));
    pw->date_edit = gnc_date_edit_new (time(NULL), FALSE, FALSE);
    gtk_box_pack_start (GTK_BOX (box), pw->date_edit, TRUE, TRUE, 0);

    pw->docs_list_tree_view = GTK_WIDGET (gtk_builder_get_object (builder, "docs_list_tree_view"));
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(pw->docs_list_tree_view));
    gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);

    /* Configure date column */
    renderer = gtk_cell_renderer_text_new ();
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (pw->docs_list_tree_view), 0);
    gtk_tree_view_column_pack_start (column, renderer, TRUE);
    tree_view_column_set_default_width (GTK_TREE_VIEW (pw->docs_list_tree_view),
                                        column, "31-12-2013");
    gtk_tree_view_column_set_cell_data_func (column, renderer,
                                             (GtkTreeCellDataFunc) print_date,
                                             NULL, NULL);

    /* Configure document number column */
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (pw->docs_list_tree_view), 1);
    tree_view_column_set_default_width (GTK_TREE_VIEW (pw->docs_list_tree_view),
                                        column, "INV2013-016");

    /* Configure document type column */
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (pw->docs_list_tree_view), 2);
    tree_view_column_set_default_width (GTK_TREE_VIEW (pw->docs_list_tree_view),
                                        column, _("Credit Note"));

    /* Configure debit column */
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (pw->docs_list_tree_view), 3);
    tree_view_column_set_default_width (GTK_TREE_VIEW (pw->docs_list_tree_view),
                                        column, "11,999.00");

    /* Configure credit column */
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (pw->docs_list_tree_view), 4);
    tree_view_column_set_default_width (GTK_TREE_VIEW (pw->docs_list_tree_view),
                                        column, "11,999.00");

    gtk_tree_sortable_set_sort_column_id (
        GTK_TREE_SORTABLE (gtk_tree_view_get_model (GTK_TREE_VIEW (pw->docs_list_tree_view))),
        0, GTK_SORT_ASCENDING);


    box = GTK_WIDGET (gtk_builder_get_object (builder, "acct_window"));
    pw->acct_tree = GTK_WIDGET(gnc_tree_view_account_new (FALSE));
    gtk_container_add (GTK_CONTAINER (box), pw->acct_tree);
    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(pw->acct_tree), FALSE);
    gnc_payment_set_account_types (GNC_TREE_VIEW_ACCOUNT (pw->acct_tree));

    /* Set the dialog for the 'new' owner.
     * Note that this also sets the post account tree. */
    gnc_payment_dialog_owner_changed(pw);

    /* Set the dialog for the 'new' invoice */
    pw->invoice = invoice;
    if (invoice)
    {
        Account *postacct = gncInvoiceGetPostedAcc (invoice);
        if (postacct)
        {
            gchar *acct_string = gnc_account_get_full_name (postacct);
            gnc_cbwe_set_by_string(GTK_COMBO_BOX(pw->post_combo), acct_string);
            gnc_payment_dialog_post_to_changed_cb (pw->post_combo, pw);
            g_free(acct_string);
        }
    }

    /* Setup signals */
    gtk_builder_connect_signals_full( builder,
                                      gnc_builder_connect_full_func,
                                      pw);

    g_signal_connect (G_OBJECT (pw->owner_choice), "changed",
                      G_CALLBACK (gnc_payment_dialog_owner_changed_cb), pw);

    g_signal_connect (G_OBJECT (pw->acct_tree), "row-activated",
                      G_CALLBACK (gnc_payment_acct_tree_row_activated_cb), pw);

    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(pw->acct_tree));
    g_signal_connect (G_OBJECT (selection), "changed",
                      G_CALLBACK (gnc_payment_dialog_xfer_acct_changed_cb), pw);


    /* Register with the component manager */
    pw->component_id =
        gnc_register_gui_component (cm_class,
                                    gnc_payment_window_refresh_handler,
                                    gnc_payment_window_close_handler,
                                    pw);

    /* Watch for any new or changed accounts */
    gnc_gui_component_watch_entity_type (pw->component_id,
                                         GNC_ID_ACCOUNT,
                                         QOF_EVENT_CREATE | QOF_EVENT_MODIFY |
                                         QOF_EVENT_DESTROY);

    /* Show it all */
    gtk_widget_show_all (pw->dialog);
    g_object_unref(G_OBJECT(builder));

    // The customer choice widget should have keyboard focus
    if (GNC_IS_GENERAL_SEARCH(pw->owner_choice))
    {
        gnc_general_search_grab_focus(GNC_GENERAL_SEARCH(pw->owner_choice));
    }

    /* Reflect if the payment could complete now */
    gnc_payment_window_check_payment (pw);

    /* Warn the user if they have no valid post-to accounts */
    {
        const gchar *text;
        const char *acct_type;

        text = gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (GTK_COMBO_BOX(pw->post_combo)))));

        if (!text || g_strcmp0 (text, "") == 0)
        {

            /* The code below assumes there will only be one account type.
             * Let's assert this to protect from potential future changes. */
            g_assert (g_list_length (pw->acct_types) == 1);
            acct_type = xaccAccountGetTypeStr(GPOINTER_TO_INT(pw->acct_types->data));
            gnc_warning_dialog(pw->dialog,
                               _("You have no valid \"Post To\" accounts. "
                                 "Please create an account of type \"%s\" "
                                 "before you continue to process this payment. "
                                 "Perhaps you want to create an Invoice or "
                                 "Bill first?"),
                               acct_type);
        }
    }

    return pw;
}
static gboolean
owner_id_handler (xmlNodePtr node, gpointer owner_pdata)
{
    struct owner_pdata* pdata = static_cast<decltype (pdata)> (owner_pdata);
    GncGUID* guid;

    guid = dom_tree_to_guid (node);
    g_return_val_if_fail (guid, FALSE);

    switch (gncOwnerGetType (pdata->owner))
    {
    case GNC_OWNER_CUSTOMER:
    {
        GncCustomer* cust = gncCustomerLookup (pdata->book, guid);
        if (!cust)
        {
            cust = gncCustomerCreate (pdata->book);
            gncCustomerSetGUID (cust, guid);
        }
        gncOwnerInitCustomer (pdata->owner, cust);
        break;
    }
    case GNC_OWNER_JOB:
    {
        GncJob* job = gncJobLookup (pdata->book, guid);
        if (!job)
        {
            job = gncJobCreate (pdata->book);
            gncJobSetGUID (job, guid);
        }
        gncOwnerInitJob (pdata->owner, job);
        break;
    }
    case GNC_OWNER_VENDOR:
    {
        GncVendor* vendor = gncVendorLookup (pdata->book, guid);
        if (!vendor)
        {
            vendor = gncVendorCreate (pdata->book);
            gncVendorSetGUID (vendor, guid);
        }
        gncOwnerInitVendor (pdata->owner, vendor);
        break;
    }
    case GNC_OWNER_EMPLOYEE:
    {
        GncEmployee* employee = gncEmployeeLookup (pdata->book, guid);
        if (!employee)
        {
            employee = gncEmployeeCreate (pdata->book);
            gncEmployeeSetGUID (employee, guid);
        }
        gncOwnerInitEmployee (pdata->owner, employee);
        break;
    }
    default:
        PWARN ("Invalid owner type: %d\n", gncOwnerGetType (pdata->owner));
        g_free (guid);
        return FALSE;
    }

    g_free (guid);
    return TRUE;
}
Beispiel #15
0
static void
add_gvalue_owner_to_slist( const GncSqlBackend* be, QofIdTypeConst obj_name,
                           const gpointer pObject, const GncSqlColumnTableEntry* table_row, GSList** pList )
{
    GValue* subfield_value;
    GncOwner* owner;
    gchar* buf;
    const GncGUID* guid;
    gchar guid_buf[GUID_ENCODING_LENGTH+1];
    GncOwnerType type;
    QofInstance* inst = NULL;
    OwnerGetterFunc getter;

    g_return_if_fail( be != NULL );
    g_return_if_fail( obj_name != NULL );
    g_return_if_fail( pObject != NULL );
    g_return_if_fail( table_row != NULL );

    getter = (OwnerGetterFunc)gnc_sql_get_getter( obj_name, table_row );
    owner = (*getter)( pObject );

    if ( owner != NULL )
    {
        buf = g_strdup_printf( "%s_type", table_row->col_name );
        subfield_value = g_new0( GValue, 1 );
        g_value_init( subfield_value, G_TYPE_INT );
        type = gncOwnerGetType( owner );
        g_value_set_int( subfield_value, type );
        (*pList) = g_slist_append( (*pList), subfield_value );
        g_free( buf );

        buf = g_strdup_printf( "%s_guid", table_row->col_name );
        subfield_value = g_new0( GValue, 1 );
        switch ( type )
        {
        case GNC_OWNER_CUSTOMER:
            inst = QOF_INSTANCE(gncOwnerGetCustomer( owner ));
            break;

        case GNC_OWNER_JOB:
            inst = QOF_INSTANCE(gncOwnerGetJob( owner ));
            break;

        case GNC_OWNER_VENDOR:
            inst = QOF_INSTANCE(gncOwnerGetVendor( owner ));
            break;

        case GNC_OWNER_EMPLOYEE:
            inst = QOF_INSTANCE(gncOwnerGetEmployee( owner ));
            break;

        default:
            PWARN("Invalid owner type: %d\n", type );
        }
        g_value_init( subfield_value, G_TYPE_STRING );
        if ( inst != NULL )
        {
            guid = qof_instance_get_guid( inst );
            if ( guid != NULL )
            {
                (void)guid_to_string_buff( guid, guid_buf );
                g_value_take_string( subfield_value, g_strdup_printf( "%s", guid_buf ) );
            }
        }
        (*pList) = g_slist_append( (*pList), subfield_value );
        g_free( buf );
    }
    else
    {
        subfield_value = g_new0( GValue, 1 );
        g_value_init( subfield_value, G_TYPE_STRING );
        g_value_set_string( subfield_value, "NULL" );
        (*pList) = g_slist_append( (*pList), subfield_value );
        subfield_value = g_new0( GValue, 1 );
        g_value_init( subfield_value, G_TYPE_STRING );
        g_value_set_string( subfield_value, "NULL" );
        (*pList) = g_slist_append( (*pList), subfield_value );
    }
}
Beispiel #16
0
/** This function is the handler for all event messages from the
 *  engine.  Its purpose is to update the owner tree model any time
 *  an owner is added to the engine or deleted from the engine.
 *  This change to the model is then propagated to any/all overlying
 *  filters and views.  This function listens to the ADD, REMOVE, and
 *  DESTROY events.
 *
 *  @internal
 *
 *  @warning There is a "Catch 22" situation here.
 *  gtk_tree_model_row_deleted() can't be called until after the item
 *  has been deleted from the real model (which is the engine's
 *  owner tree for us), but once the owner has been deleted from
 *  the engine we have no way to determine the path to pass to
 *  row_deleted().  This is a PITA, but the only other choice is to
 *  have this model mirror the engine's owners instead of
 *  referencing them directly.
 *
 *  @param entity The guid of the affected item.
 *
 *  @param type The type of the affected item.  This function only
 *  cares about items of type "owner".
 *
 *  @param event type The type of the event. This function only cares
 *  about items of type ADD, REMOVE, MODIFY, and DESTROY.
 *
 *  @param user_data A pointer to the owner tree model.
 */
static void
gnc_tree_model_owner_event_handler (QofInstance *entity,
                                    QofEventId event_type,
                                    GncTreeModelOwner *model,
                                    GncEventData *ed)
{
    GncTreeModelOwnerPrivate *priv;
    GtkTreePath *path = NULL;
    GtkTreeIter iter;
    GncOwner owner;

    g_return_if_fail(model);         /* Required */

    if (!GNC_IS_OWNER(entity))
        return;

    ENTER("entity %p of type %d, model %p, event_data %p",
          entity, event_type, model, ed);
    priv = GNC_TREE_MODEL_OWNER_GET_PRIVATE(model);

    qofOwnerSetEntity (&owner, entity);
    if (gncOwnerGetType(&owner) != priv->owner_type)
    {
        LEAVE("model type and owner type differ");
        return;
    }

    if (qof_instance_get_book (entity) != priv->book)
    {
        LEAVE("not in this book");
        return;
    }

    /* What to do, that to do. */
    switch (event_type)
    {
    case QOF_EVENT_ADD:
        /* Tell the filters/views where the new owner was added. */
        DEBUG("add owner %p (%s)", &owner, gncOwnerGetName(&owner));
        /* First update our copy of the owner list. This isn't done automatically */
        priv->owner_list = gncBusinessGetOwnerList (priv->book,
                           gncOwnerTypeToQofIdType(priv->owner_type), TRUE);
        increment_stamp(model);
        if (!gnc_tree_model_owner_get_iter_from_owner (model, &owner, &iter))
        {
            LEAVE("can't generate iter");
            break;
        }
        path = gnc_tree_model_owner_get_path(GTK_TREE_MODEL(model), &iter);
        if (!path)
        {
            DEBUG("can't generate path");
            break;
        }
        gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, &iter);
        break;

    case QOF_EVENT_REMOVE:
        if (!ed) /* Required for a remove. */
            break;
        DEBUG("remove owner %d (%s) from owner_list %p", ed->idx,
              gncOwnerGetName(&owner), priv->owner_list);
        path = gtk_tree_path_new();
        if (!path)
        {
            DEBUG("can't generate path");
            break;
        }
        increment_stamp(model);
        gtk_tree_path_append_index (path, ed->idx);
        gtk_tree_model_row_deleted (GTK_TREE_MODEL(model), path);
        break;

    case QOF_EVENT_MODIFY:
        DEBUG("modify  owner %p (%s)", &owner, gncOwnerGetName(&owner));
        if (!gnc_tree_model_owner_get_iter_from_owner (model, &owner, &iter))
        {
            LEAVE("can't generate iter");
            return;
        }
        path = gnc_tree_model_owner_get_path(GTK_TREE_MODEL(model), &iter);
        if (!path)
        {
            DEBUG("can't generate path");
            break;
        }
        gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter);
        break;

    default:
        LEAVE("unknown event type");
        return;
    }

    if (path)
        gtk_tree_path_free(path);
    LEAVE(" ");
    return;
}
Beispiel #17
0
static void
gnc_tree_model_owner_get_value (GtkTreeModel *tree_model,
                                GtkTreeIter *iter,
                                int column,
                                GValue *value)
{
    GncTreeModelOwner *model = GNC_TREE_MODEL_OWNER (tree_model);
    GncOwner *owner;
    gboolean negative; /* used to set "deficit style" also known as red numbers */
    gchar *string = NULL;

    g_return_if_fail (GNC_IS_TREE_MODEL_OWNER (model));
    g_return_if_fail (iter != NULL);
    g_return_if_fail (iter->user_data != NULL);
    g_return_if_fail (iter->stamp == model->stamp);

    ENTER("model %p, iter %s, col %d", tree_model,
          iter_to_string(iter), column);

    owner = (GncOwner *) iter->user_data;

    switch (column)
    {
    case GNC_TREE_MODEL_OWNER_COL_NAME:
        g_value_init (value, G_TYPE_STRING);
        g_value_set_string (value, gncOwnerGetName (owner));
        break;
    case GNC_TREE_MODEL_OWNER_COL_TYPE:
        g_value_init (value, G_TYPE_STRING);
        g_value_set_string (value,
                            gncOwnerTypeToQofIdType (gncOwnerGetType (owner)));
        break;
    case GNC_TREE_MODEL_OWNER_COL_ID:
        g_value_init (value, G_TYPE_STRING);
        g_value_set_string (value, gncOwnerGetID (owner));
        break;
    case GNC_TREE_MODEL_OWNER_COL_CURRENCY:
        g_value_init (value, G_TYPE_STRING);
        g_value_set_string (value,
                            gnc_commodity_get_fullname(gncOwnerGetCurrency (owner)));
        break;
    case GNC_TREE_MODEL_OWNER_COL_ADDRESS_NAME:
        g_value_init (value, G_TYPE_STRING);
        string = g_strdup (gncAddressGetName (gncOwnerGetAddr (owner)));
        if (string)
            g_value_take_string (value, string);
        else
            g_value_set_static_string (value, "");
        break;
    case GNC_TREE_MODEL_OWNER_COL_ADDRESS_1:
        g_value_init (value, G_TYPE_STRING);
        string = g_strdup (gncAddressGetAddr1 (gncOwnerGetAddr (owner)));
        if (string)
            g_value_take_string (value, string);
        else
            g_value_set_static_string (value, "");
        break;
    case GNC_TREE_MODEL_OWNER_COL_ADDRESS_2:
        g_value_init (value, G_TYPE_STRING);
        string = g_strdup (gncAddressGetAddr2 (gncOwnerGetAddr (owner)));
        if (string)
            g_value_take_string (value, string);
        else
            g_value_set_static_string (value, "");
        break;
    case GNC_TREE_MODEL_OWNER_COL_ADDRESS_3:
        g_value_init (value, G_TYPE_STRING);
        string = g_strdup (gncAddressGetAddr3 (gncOwnerGetAddr (owner)));
        if (string)
            g_value_take_string (value, string);
        else
            g_value_set_static_string (value, "");
        break;
    case GNC_TREE_MODEL_OWNER_COL_ADDRESS_4:
        g_value_init (value, G_TYPE_STRING);
        string = g_strdup (gncAddressGetAddr4 (gncOwnerGetAddr (owner)));
        if (string)
            g_value_take_string (value, string);
        else
            g_value_set_static_string (value, "");
        break;
    case GNC_TREE_MODEL_OWNER_COL_PHONE:
        g_value_init (value, G_TYPE_STRING);
        string = g_strdup (gncAddressGetPhone (gncOwnerGetAddr (owner)));
        if (string)
            g_value_take_string (value, string);
        else
            g_value_set_static_string (value, "");
        break;
    case GNC_TREE_MODEL_OWNER_COL_FAX:
        g_value_init (value, G_TYPE_STRING);
        string = g_strdup (gncAddressGetFax (gncOwnerGetAddr (owner)));
        if (string)
            g_value_take_string (value, string);
        else
            g_value_set_static_string (value, "");
        break;
    case GNC_TREE_MODEL_OWNER_COL_EMAIL:
        g_value_init (value, G_TYPE_STRING);
        string = g_strdup (gncAddressGetEmail (gncOwnerGetAddr (owner)));
        if (string)
            g_value_take_string (value, string);
        else
            g_value_set_static_string (value, "");
        break;

    case GNC_TREE_MODEL_OWNER_COL_BALANCE:
        g_value_init (value, G_TYPE_STRING);
        string = gnc_ui_owner_get_print_balance(owner, &negative);
        g_value_take_string (value, string);
        break;

    case GNC_TREE_MODEL_OWNER_COL_BALANCE_REPORT:
        g_value_init (value, G_TYPE_STRING);
        string = gnc_ui_owner_get_print_report_balance(owner, &negative);
        g_value_take_string (value, string);
        break;
    case GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE:
        g_value_init (value, G_TYPE_STRING);
        string = gnc_ui_owner_get_print_balance(owner, &negative);
        gnc_tree_model_owner_set_color(model, negative, value);
        g_free(string);
        break;

    case GNC_TREE_MODEL_OWNER_COL_NOTES:
        g_value_init (value, G_TYPE_STRING);
        switch (gncOwnerGetType (owner))
        {
        case GNC_OWNER_NONE:
        case GNC_OWNER_UNDEFINED:
        case GNC_OWNER_EMPLOYEE:
        case GNC_OWNER_JOB:
        default:
            g_value_set_static_string (value, "");
            break;
        case GNC_OWNER_VENDOR:
            g_value_set_string (value, gncVendorGetNotes (gncOwnerGetVendor (owner)));
            break;
        case GNC_OWNER_CUSTOMER:
            g_value_set_string (value, gncCustomerGetNotes (gncOwnerGetCustomer (owner)));
            break;
        }
        break;

    case GNC_TREE_MODEL_OWNER_COL_ACTIVE:
        g_value_init (value, G_TYPE_BOOLEAN);
        g_value_set_boolean (value, gncOwnerGetActive (owner));
        break;

    default:
        g_assert_not_reached ();
    }
    LEAVE(" ");
}