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; }
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); }
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")); }
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); }
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); }
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; }
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(¤t_owner, NULL); break; case GNC_OWNER_CUSTOMER : { gncOwnerInitCustomer(¤t_owner, gncOwnerGetCustomer(gnc_plugin_page_owner_tree_get_current_owner (page)) ); break; } case GNC_OWNER_JOB : { gncOwnerInitJob(¤t_owner, gncOwnerGetJob(gnc_plugin_page_owner_tree_get_current_owner (page)) ); break; } case GNC_OWNER_VENDOR : { gncOwnerInitVendor(¤t_owner, gncOwnerGetVendor(gnc_plugin_page_owner_tree_get_current_owner (page)) ); break; } case GNC_OWNER_EMPLOYEE : { gncOwnerInitEmployee(¤t_owner, gncOwnerGetEmployee(gnc_plugin_page_owner_tree_get_current_owner (page)) ); break; } } if (gncOwnerGetType(¤t_owner) != GNC_OWNER_UNDEFINED) gnc_ui_invoice_new (¤t_owner, gnc_get_current_book()); LEAVE(" "); }
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)); } }
/* 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); }
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); }
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); }
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; }
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 ); } }
/** 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; }
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(" "); }