~tristan957/harvest-almanac

04ab2efe6831da8e028654e2580e253b1be5c3a5 — Tristan Partin 1 year, 9 months ago 2926de1
harvest-glib: figured out how gnome.mkenums_simple works
A harvest-glib/harvest-company.c => harvest-glib/harvest-company.c +289 -0
@@ 0,0 1,289 @@
#include "config.h"

#define G_LOG_DOMAIN "HarvestCompany"

#include <limits.h>

#include <glib-object.h>
#include <glib/gi18n.h>

#include "harvest-company.h"
#include "harvest-enum-types.h"

struct _HarvestCompany
{
	char *base_uri;
	char *full_domain;
	char *name;
	gboolean is_active : 1;
	HarvestWeekStartDay week_start_day;
	gboolean wants_timestamp_timers : 1;
	HarvestTimeFormat time_format;
	HarvestPlanType plan_type;
	HarvestClock clock;
	char *decimal_symbol;
	char *thousands_operator;
	char *color_scheme;
	unsigned int weekly_capacity;
	gboolean exepnse_feature : 1;
	gboolean invoice_feature : 1;
	gboolean estimate_feature : 1;
	gboolean approval_feature : 1;
};

G_DEFINE_TYPE(HarvestCompany, harvest_company, G_TYPE_OBJECT)

enum HarvestCompanyProps
{
	PROP_0,
	PROP_BASE_URI,
	PROP_FULL_DOMAIN,
	PROP_NAME,
	PROP_IS_ACTIVE,
	PROP_WEEK_START_DAY,
	PROP_WANTS_TIMESTAMP_TIMERS,
	PROP_TIME_FORMAT,
	PROP_PLAN_TYPE,
	PROP_CLOCK,
	PROP_DECIMAL_SYMBOL,
	PROP_THOUSANDS_OPERATOR,
	PROP_COLOR_SCHEME,
	PROP_WEEKLY_CAPACITY,
	PROP_EXPENSE_FEATURE,
	PROP_INVOICE_FEATURE,
	PROP_ESTIMATE_FEATURE,
	PROP_APPROVAL_FEATURE,
	N_PROPS,
};

static GParamSpec *obj_properties[N_PROPS];

static void
harvest_company_finalize(GObject *obj)
{
	HarvestCompany *self = HARVEST_COMPANY(obj);

	g_free(self->base_uri);
	g_free(self->full_domain);
	g_free(self->name);
	g_free(self->decimal_symbol);
	g_free(self->thousands_operator);
	g_free(self->color_scheme);

	G_OBJECT_CLASS(harvest_company_parent_class)->finalize(obj);
}

static void
harvest_company_get_property(GObject *obj, guint prop_id, GValue *val, GParamSpec *pspec)
{
	HarvestCompany *self = HARVEST_COMPANY(obj);

	switch (prop_id) {
	case PROP_BASE_URI:
		g_value_set_string(val, self->base_uri);
		break;
	case PROP_FULL_DOMAIN:
		g_value_set_string(val, self->full_domain);
		break;
	case PROP_NAME:
		g_value_set_string(val, self->name);
		break;
	case PROP_IS_ACTIVE:
		g_value_set_boolean(val, self->is_active);
		break;
	case PROP_WEEK_START_DAY:
		g_value_set_enum(val, (int) self->week_start_day);
		break;
	case PROP_WANTS_TIMESTAMP_TIMERS:
		g_value_set_boolean(val, self->wants_timestamp_timers);
		break;
	case PROP_TIME_FORMAT:
		g_value_set_enum(val, (int) self->time_format);
		break;
	case PROP_PLAN_TYPE:
		g_value_set_enum(val, (int) self->plan_type);
		break;
	case PROP_CLOCK:
		g_value_set_enum(val, (int) self->clock);
		break;
	case PROP_DECIMAL_SYMBOL:
		g_value_set_string(val, self->decimal_symbol);
		break;
	case PROP_THOUSANDS_OPERATOR:
		g_value_set_string(val, self->thousands_operator);
		break;
	case PROP_COLOR_SCHEME:
		g_value_set_string(val, self->color_scheme);
		break;
	case PROP_WEEKLY_CAPACITY:
		g_value_set_uint(val, self->weekly_capacity);
		break;
	case PROP_EXPENSE_FEATURE:
		g_value_set_boolean(val, self->exepnse_feature);
		break;
	case PROP_INVOICE_FEATURE:
		g_value_set_boolean(val, self->invoice_feature);
		break;
	case PROP_ESTIMATE_FEATURE:
		g_value_set_boolean(val, self->estimate_feature);
		break;
	case PROP_APPROVAL_FEATURE:
		g_value_set_boolean(val, self->approval_feature);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
	}
}

static void
harvest_company_set_property(GObject *obj, guint prop_id, const GValue *val, GParamSpec *pspec)
{
	HarvestCompany *self = HARVEST_COMPANY(obj);

	switch (prop_id) {
	case PROP_BASE_URI:
		g_free(self->base_uri);
		self->base_uri = g_value_dup_string(val);
		break;
	case PROP_FULL_DOMAIN:
		g_free(self->base_uri);
		self->base_uri = g_value_dup_string(val);
		break;
	case PROP_NAME:
		g_free(self->base_uri);
		self->base_uri = g_value_dup_string(val);
		break;
	case PROP_IS_ACTIVE:
		self->is_active = g_value_get_boolean(val);
		break;
	case PROP_WEEK_START_DAY:
		self->week_start_day = (HarvestWeekStartDay) g_value_get_enum(val);
		break;
	case PROP_WANTS_TIMESTAMP_TIMERS:
		self->wants_timestamp_timers = g_value_get_boolean(val);
		break;
	case PROP_TIME_FORMAT:
		self->time_format = (HarvestTimeFormat) g_value_get_enum(val);
		break;
	case PROP_PLAN_TYPE:
		self->plan_type = (HarvestPlanType) g_value_get_enum(val);
		break;
	case PROP_CLOCK:
		self->clock = (HarvestClock) g_value_get_enum(val);
		break;
	case PROP_DECIMAL_SYMBOL:
		g_free(self->decimal_symbol);
		self->decimal_symbol = g_value_dup_string(val);
		break;
	case PROP_THOUSANDS_OPERATOR:
		g_free(self->thousands_operator);
		self->thousands_operator = g_value_dup_string(val);
		break;
	case PROP_COLOR_SCHEME:
		g_free(self->color_scheme);
		self->color_scheme = g_value_dup_string(val);
		break;
	case PROP_WEEKLY_CAPACITY:
		self->weekly_capacity = g_value_get_uint(val);
		break;
	case PROP_EXPENSE_FEATURE:
		self->exepnse_feature = g_value_get_boolean(val);
		break;
	case PROP_INVOICE_FEATURE:
		self->invoice_feature = g_value_get_boolean(val);
		break;
	case PROP_ESTIMATE_FEATURE:
		self->estimate_feature = g_value_get_boolean(val);
		break;
	case PROP_APPROVAL_FEATURE:
		self->approval_feature = g_value_get_boolean(val);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
	}
}

static void
harvest_company_class_init(HarvestCompanyClass *klass)
{
	GObjectClass *obj_class = G_OBJECT_CLASS(klass);

	obj_class->finalize		= harvest_company_finalize;
	obj_class->get_property = harvest_company_get_property;
	obj_class->set_property = harvest_company_set_property;

	obj_properties[PROP_BASE_URI]
		= g_param_spec_string("base-uri", _("Base URI"), _("The Harvest URL for the company."),
			NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_FULL_DOMAIN] = g_param_spec_string("full-domain", _("Full Domain"),
		_("The Harvest domain for the company."), NULL,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_NAME]
		= g_param_spec_string("name", _("Name"), _("The name of the company."), NULL,
			G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_IS_ACTIVE]		= g_param_spec_boolean("is-active", _("Is Active"),
		 _("Whether the company is active or archived."), FALSE,
		 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_WEEK_START_DAY] = g_param_spec_enum("week-start-day", _("Week Start Day"),
		_("The week day used as the start of the week. Returns one of: Saturday, Sunday, or "
		  "Monday."),
		HARVEST_TYPE_WEEK_START_DAY, HARVEST_WEEK_START_DAY_SUNDAY,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_WANTS_TIMESTAMP_TIMERS]
		= g_param_spec_boolean("wants-timestamp-timers", _("Wants Timestamp Timers"),
			_("Whether time is tracked via duration or start and end times."), FALSE,
			G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_TIME_FORMAT]	= g_param_spec_enum("time-format", _("Time Format"),
		   _("The format used to display time in Harvest. Returns either decimal or hours_minutes."),
		   HARVEST_TYPE_TIME_FORMAT, HARVEST_TIME_FORMAT_HOURS_MINUTES,
		   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_PLAN_TYPE]		= g_param_spec_enum("plan-type", _("Plan Type"),
		 _("The type of plan the company is on. Examples: trial, free, or simple-v4"),
		 HARVEST_TYPE_PLAN_TYPE, HARVEST_PLAN_TYPE_FREE,
		 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CLOCK]			= g_param_spec_enum("clock", _("Clock"),
		 _("Used to represent whether the company is using a 12-hour or 24-hour clock. Returns "
		   "either 12h or 24h."),
		 HARVEST_TYPE_CLOCK, HARVEST_CLOCK_12H,
		 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_DECIMAL_SYMBOL] = g_param_spec_string("decimal-symbol", _("Decimal Symbol"),
		_("Symbol used when formatting decimals."), NULL,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_THOUSANDS_OPERATOR] = g_param_spec_string("thousands-operator",
		_("Thousands Operator"), _("Separator used when formatting numbers."), NULL,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_COLOR_SCHEME]		= g_param_spec_string("color-scheme", _("Color Scheme"),
		  _("The color scheme being used in the Harvest web client."), NULL,
		  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_WEEKLY_CAPACITY]	= g_param_spec_uint("weekly-capacity",
		   _("Weekly Capacity"), _("The weekly capacity in seconds."), 0, UINT_MAX, 0,
		   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_EXPENSE_FEATURE]	= g_param_spec_boolean("expense-feature", _(" Feature"),
		   _("Whether the expense module is enabled."), FALSE,
		   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_INVOICE_FEATURE]	= g_param_spec_boolean("invoice-feature", _(" Feature"),
		   _("Whether the invoice module is enabled."), FALSE,
		   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_ESTIMATE_FEATURE] = g_param_spec_boolean("estimate-feature", _(" Feature"),
		_("Whether the estimate module is enabled."), FALSE,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_APPROVAL_FEATURE] = g_param_spec_boolean("approval-feature", _(" Feature"),
		_("Whether the approval module is enabled."), FALSE,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
}

static void
harvest_company_init(G_GNUC_UNUSED HarvestCompany *self)
{}

const char *
harvest_company_get_full_domain(HarvestCompany *self)
{
	return self->full_domain;
}

const char *
harvest_company_get_name(HarvestCompany *self)
{
	return self->name;
}

A harvest-glib/harvest-company.h => harvest-glib/harvest-company.h +43 -0
@@ 0,0 1,43 @@
#pragma once

#if !defined(__HARVEST_HEADER_INTERNAL__) && !defined(__HARVEST_COMPILATION__)
#	error "Only <harvest-glib/harvest.h> can be included directly."
#endif

#include <glib-object.h>

G_BEGIN_DECLS

#define HARVEST_TYPE_COMPANY (harvest_company_get_type())
G_DECLARE_FINAL_TYPE(HarvestCompany, harvest_company, HARVEST, COMPANY, GObject)

typedef enum
{
	HARVEST_WEEK_START_DAY_SATURDAY,
	HARVEST_WEEK_START_DAY_SUNDAY,
	HARVEST_WEEK_START_DAY_MONDAY,
} HarvestWeekStartDay;

typedef enum
{
	HARVEST_TIME_FORMAT_DECIMAL,
	HARVEST_TIME_FORMAT_HOURS_MINUTES,
} HarvestTimeFormat;

typedef enum
{
	HARVEST_PLAN_TYPE_TRIAL,
	HARVEST_PLAN_TYPE_FREE,
	HARVEST_PLAN_TYPE_SIMPLE_V4,
} HarvestPlanType;

typedef enum
{
	HARVEST_CLOCK_12H,
	HARVEST_CLOCK_24H,
} HarvestClock;

const char *harvest_company_get_full_domain(HarvestCompany *self);
const char *harvest_company_get_name(HarvestCompany *self);

G_END_DECLS

M harvest-glib/harvest-estimate.c => harvest-glib/harvest-estimate.c +33 -48
@@ 11,6 11,7 @@
#include "harvest-client.h"
#include "harvest-common.h"
#include "harvest-creator.h"
#include "harvest-enum-types.h"
#include "harvest-estimate-line-item.h"
#include "harvest-estimate.h"



@@ 98,7 99,7 @@ harvest_estimate_deserialize_property(JsonSerializable *serializable, const gcha

		return TRUE;
	} else if (g_strcmp0(prop_name, "line_items") == 0) {
		JsonArray *arr	 = json_node_get_array(prop_node);
		JsonArray *arr	   = json_node_get_array(prop_node);
		const guint length = json_array_get_length(arr);
		GPtrArray *roles   = g_ptr_array_sized_new(length);
		json_array_foreach_element(arr, line_items_for_each, roles);


@@ 110,22 111,6 @@ harvest_estimate_deserialize_property(JsonSerializable *serializable, const gcha
		g_value_set_object(val, obj);

		return TRUE;
	} else if (g_strcmp0(prop_name, "state") == 0) {
		const char *state = json_node_get_string(prop_node);

		if (g_strcmp0(state, "accepted") == 0) {
			g_value_set_int(val, HARVEST_ESTIMATE_STATE_ACCEPTED);
		} else if (g_strcmp0(state, "declined") == 0) {
			g_value_set_int(val, HARVEST_ESTIMATE_STATE_DECLINED);
		} else if (g_strcmp0(state, "draft") == 0) {
			g_value_set_int(val, HARVEST_ESTIMATE_STATE_DRAFT);
		} else if (g_strcmp0(state, "sent")) {
			g_value_set_int(val, HARVEST_ESTIMATE_STATE_SENT);
		} else {
			g_warn_if_reached();
		}

		return TRUE;
	} else if (g_strcmp0(prop_name, "issue_date") == 0) {
		const GDateTime *dt
			= g_date_time_new_from_abbreviated_date(json_node_get_string(prop_node));


@@ 256,7 241,7 @@ harvest_estimate_get_property(GObject *obj, guint prop_id, GValue *val, GParamSp
		g_value_set_string(val, self->currency);
		break;
	case PROP_STATE:
		g_value_set_int(val, self->state);
		g_value_set_enum(val, (int) self->state);
		break;
	case PROP_ISSUE_DATE:
		g_value_set_boxed(val, self->issue_date);


@@ 364,7 349,7 @@ harvest_estimate_set_property(GObject *obj, guint prop_id, const GValue *val, GP
		self->currency = g_value_dup_string(val);
		break;
	case PROP_STATE:
		self->state = g_value_get_int(val);
		self->state = (HarvestEstimateState) g_value_get_enum(val);
		break;
	case PROP_ISSUE_DATE:
		if (self->issue_date != NULL)


@@ 411,79 396,79 @@ harvest_estimate_class_init(HarvestEstimateClass *klass)
	obj_class->set_property = harvest_estimate_set_property;

	obj_properties[PROP_ID] = g_param_spec_int("id", _("ID"), _("Unique ID for the estimate."), 0,
		INT_MAX, 0, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		INT_MAX, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CLIENT] = g_param_spec_object("client", _("Client"),
		_("An object containing estimate’s client id and name."), HARVEST_TYPE_CLIENT,
		G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_LINE_ITEMS]
		= g_param_spec_boxed("line_items", _("Line Items"), _("Array of estimate line items."),
			G_TYPE_PTR_ARRAY, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
			G_TYPE_PTR_ARRAY, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CREATOR]		= g_param_spec_object("creator", _("Creator"),
		   _("An object containing the id and name of the person that created the estimate."),
		   HARVEST_TYPE_CREATOR, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		   HARVEST_TYPE_CREATOR, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CLIENT_KEY]		= g_param_spec_string("client_key", _("Client Key"),
		_("Used to build a URL to the public web invoice for your client: "
		  "https://{ACCOUNT_SUBDOMAIN}.harvestapp.com/client/estimates/abc123456"),
		NULL, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_NUMBER]			= g_param_spec_string("number", _("Number"),
		_("If no value is set, the number will be automatically generated."), NULL,
		G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_PURCHASE_ORDER] = g_param_spec_string("purchase_order", _("Purshase Order"),
		_("The purchase order number."), NULL,
		G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_AMOUNT]			= g_param_spec_double("amount", _("Amount"),
		_("The total amount for the estimate, including any discounts and taxes."), 0, DBL_MAX, 0,
		G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_TAX]			= g_param_spec_double("tax", _("Tax"),
		   _("This percentage is applied to the subtotal, including line items and discounts."), 0,
		   DBL_MAX, 0, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		   DBL_MAX, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_TAX_AMOUNT]		= g_param_spec_double("tax_amount", _("Tax Amount"),
		_("The first amount of tax included, calculated from tax. If no tax is defined, this value "
		  "will be null."),
		0, DBL_MAX, 0, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		0, DBL_MAX, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_TAX2]			= g_param_spec_double("tax2", _("Tax 2"),
		  _("This percentage is applied to the subtotal, including line items and discounts."), 0,
		  DBL_MAX, 0, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		  DBL_MAX, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_TAX2_AMOUNT]	= g_param_spec_double("tax2_amount", _("Tax2 Amount"),
		   _("The amount calculated from tax2."), 0, DBL_MAX, 0,
		   G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_DISCOUNT]		= g_param_spec_double("discount", _("Discount"),
		  _("This percentage is subtracted from the subtotal."), 0, DBL_MAX, 0,
		  G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		  G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_DISCOUNT_AMOUNT] = g_param_spec_double("discount_amount",
		_("Discount Amount"), _("The amount calcuated from discount."), 0, DBL_MAX, 0,
		G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_SUBJECT]
		= g_param_spec_string("subject", _("Subject"), _("The estimate subject."), NULL,
			G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_NOTES]	= g_param_spec_string("notes", _("Notes"),
			G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_NOTES]	  = g_param_spec_string("notes", _("Notes"),
		   _("Any additional notes included on the estimate."), NULL,
		   G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CURRENCY] = g_param_spec_string("currency", _("Currency"),
		_("The currency code associated with this estimate."), NULL,
		G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_STATE]	= g_param_spec_int("state", _("State"),
		G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_STATE]	  = g_param_spec_enum("state", _("State"),
		   _("The current state of the estimate: draft, sent, accepted, or declined."),
		   HARVEST_ESTIMATE_STATE_DRAFT, HARVEST_ESTIMATE_STATE_DECLINED, HARVEST_ESTIMATE_STATE_DRAFT,
		   G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		   HARVEST_TYPE_ESTIMATE_STATE, HARVEST_ESTIMATE_STATE_ACCEPTED,
		   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_ISSUE_DATE]
		= g_param_spec_boxed("issue_date", _("Issue Date"), _("Date the estimate was issued."),
			G_TYPE_DATE_TIME, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
			G_TYPE_DATE_TIME, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_SENT_AT]
		= g_param_spec_boxed("sent_at", _("Sent At"), _("Date and time the estimate was sent."),
			G_TYPE_DATE_TIME, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
			G_TYPE_DATE_TIME, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_ACCEPTED_AT] = g_param_spec_boxed("accepted_at", _("Accepted At"),
		_("Date and time the estimate was accepted."), G_TYPE_DATE_TIME,
		G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_DECLINED_AT] = g_param_spec_boxed("declined_at", _("Declined At"),
		_("Date and time the estimate was declined."), G_TYPE_DATE_TIME,
		G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CREATED_AT]  = g_param_spec_boxed("created_at", _("Created At"),
		G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CREATED_AT]	 = g_param_spec_boxed("created_at", _("Created At"),
		 _("Date and time the estimate was created."), G_TYPE_DATE_TIME,
		 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_UPDATED_AT]  = g_param_spec_boxed("updated_at", _("Updated At"),
		 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_UPDATED_AT]	 = g_param_spec_boxed("updated_at", _("Updated At"),
		 _("Date and time the estimate was last updated."), G_TYPE_DATE_TIME,
		 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
		 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);

	g_object_class_install_properties(obj_class, N_PROPS, obj_properties);
}

M harvest-glib/harvest-invoice.c => harvest-glib/harvest-invoice.c +45 -44
@@ 1,4 1,5 @@
#include "config.h"

#define G_LOG_DOMAIN "HarvestInvoice"

#include <float.h>


@@ 11,6 12,7 @@
#include "harvest-client.h"
#include "harvest-common.h"
#include "harvest-creator.h"
#include "harvest-enum-types.h"
#include "harvest-estimate-line-item.h"
#include "harvest-estimate.h"
#include "harvest-invoice-line-item.h"


@@ 116,7 118,7 @@ harvest_invoice_deserialize_property(JsonSerializable *serializable, const gchar

		return TRUE;
	} else if (g_strcmp0(prop_name, "line_items") == 0) {
		JsonArray *arr	 = json_node_get_array(prop_node);
		JsonArray *arr	   = json_node_get_array(prop_node);
		const guint length = json_array_get_length(arr);
		GPtrArray *roles   = g_ptr_array_sized_new(length);
		json_array_foreach_element(arr, line_items_for_each, roles);


@@ 318,7 320,7 @@ harvest_invoice_get_property(GObject *obj, guint prop_id, GValue *val, GParamSpe
		g_value_set_string(val, self->currency);
		break;
	case PROP_STATE:
		g_value_set_int(val, self->state);
		g_value_set_enum(val, (int) self->state);
		break;
	case PROP_PERIOD_START:
		g_value_set_boxed(val, self->period_start);


@@ 333,7 335,7 @@ harvest_invoice_get_property(GObject *obj, guint prop_id, GValue *val, GParamSpe
		g_value_set_boxed(val, self->due_date);
		break;
	case PROP_PAYMENT_TERM:
		g_value_set_int(val, self->payment_term);
		g_value_set_enum(val, (int) self->payment_term);
		break;
	case PROP_SENT_AT:
		g_value_set_boxed(val, self->sent_at);


@@ 451,7 453,7 @@ harvest_invoice_set_property(GObject *obj, guint prop_id, const GValue *val, GPa
		self->currency = g_value_dup_string(val);
		break;
	case PROP_STATE:
		self->state = g_value_get_int(val);
		self->state = (HarvestInvoiceState) g_value_get_enum(val);
		break;
	case PROP_PERIOD_START:
		if (self->period_start != NULL)


@@ 474,7 476,7 @@ harvest_invoice_set_property(GObject *obj, guint prop_id, const GValue *val, GPa
		self->due_date = g_value_dup_boxed(val);
		break;
	case PROP_PAYMENT_TERM:
		self->payment_term = g_value_get_int(val);
		self->payment_term = (HarvestInvoicePaymentTerm) g_value_get_enum(val);
		break;
	case PROP_SENT_AT:
		if (self->sent_at != NULL)


@@ 521,104 523,103 @@ harvest_invoice_class_init(HarvestInvoiceClass *klass)
	obj_class->set_property = harvest_invoice_set_property;

	obj_properties[PROP_ID] = g_param_spec_int("id", _("ID"), _("Unique ID for the invoice."), 0,
		INT_MAX, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		INT_MAX, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CLIENT] = g_param_spec_object("client", _("Client"),
		_("An object containing invoice’s client id and name."), HARVEST_TYPE_CLIENT,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_LINE_ITEMS]
		= g_param_spec_boxed("line_items", _("Line Items"), _("Array of invoice line items."),
			G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
			G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_ESTIMATE]		= g_param_spec_object("estimate", _("Estimate"),
		  _("An object containing the associated estimate’s id."), HARVEST_TYPE_ESTIMATE,
		  G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_RETAINER]		= NULL;
	obj_properties[PROP_CREATOR]		= g_param_spec_object("creator", _("Creator"),
		   _("An object containing the id and name of the person that created the invoice."),
		   HARVEST_TYPE_CREATOR, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		   HARVEST_TYPE_CREATOR, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CLIENT_KEY]		= g_param_spec_string("client_key", _("Client Key"),
		_("Used to build a URL to the public web invoice for your client: "
		  "https://{ACCOUNT_SUBDOMAIN}.harvestapp.com/client/invoices/abc123456"),
		NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_NUMBER]			= g_param_spec_string("number", _("Number"),
		_("If no value is set, the number will be automatically generated."), NULL,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_PURCHASE_ORDER] = g_param_spec_string("purchase_order", _("purchase_order"),
		_("The purchase order number."), NULL,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_AMOUNT]			= g_param_spec_double("amount", _("Amount"),
		_("The total amount for the invoice, including any discounts and taxes."), 0, DBL_MAX, 0,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_DUE_AMOUNT]		= g_param_spec_double("due_amount", _("Due Amount"),
		_("The total amount due at this time for this invoice."), 0, DBL_MAX, 0,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_TAX]			= g_param_spec_double("tax", _("Tax"),
		   _("This percentage is applied to the subtotal, including line items and discounts."), 0,
		   DBL_MAX, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		   DBL_MAX, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_TAX_AMOUNT]		= g_param_spec_double("tax_amount", _("Tax Amount"),
		_("The first amount of tax included, calculated from tax. If no tax is defined, this value "
		  "will be null."),
		0, DBL_MAX, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		0, DBL_MAX, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_TAX2]			= g_param_spec_double("tax2", _("Tax2"),
		  _("This percentage is applied to the subtotal, including line items and discounts."), 0,
		  DBL_MAX, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		  DBL_MAX, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_TAX2_AMOUNT]	= g_param_spec_double("tax2_amount", _("Tax2 Amount"),
		   _("The amount calculated from tax2."), 0, DBL_MAX, 0,
		   G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_DISCOUNT]		= g_param_spec_double("discount", _("Discount"),
		  _("This percentage is subtracted from the subtotal."), 0, DBL_MAX, 0,
		  G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_DISCOUNT_AMOUNT] = g_param_spec_double("discount_amount",
		_("Discount Amount"), _("The amount calcuated from discount."), 0, DBL_MAX, 0,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_SUBJECT]
		= g_param_spec_string("subject", _("Subject"), _("The invoice subject."), NULL,
			G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
			G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_NOTES]		  = g_param_spec_string("notes", _("Notes"),
		   _("Any additional notes included on the invoice."), NULL,
		   G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CURRENCY]	 = g_param_spec_string("currency", _("Currency"),
		   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CURRENCY]	  = g_param_spec_string("currency", _("Currency"),
		_("The currency code associated with this invoice."), NULL,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_STATE]		  = g_param_spec_int("payment_term", _("State"),
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_STATE]		  = g_param_spec_enum("payment_term", _("State"),
		   _("The current payment_term of the invoice: draft, open, paid, or closed."),
		   HARVEST_INVOICE_STATE_DRAFT, HARVEST_INVOICE_STATE_CLOSED, HARVEST_INVOICE_STATE_DRAFT,
		   G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		   HARVEST_TYPE_INVOICE_STATE, HARVEST_INVOICE_STATE_OPEN,
		   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_PERIOD_START] = g_param_spec_boxed("period_start", _("Period Start"),
		_("Start of the period during which time entries were added to this invoice."),
		G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_PERIOD_END]   = g_param_spec_boxed("period_end", _("Period End"),
		G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_PERIOD_END]	  = g_param_spec_boxed("period_end", _("Period End"),
		  _("End of the period during which time entries were added to this invoice."),
		  G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		  G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_ISSUE_DATE]
		= g_param_spec_boxed("issue_date", _("Issue Date"), _("Date the invoice was issued."),
			G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
			G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_DUE_DATE]
		= g_param_spec_boxed("due_date", _("Due Date"), _("Date the invoice is due."),
			G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_PAYMENT_TERM] = g_param_spec_int("payment_term", _("Payment Term"),
			G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_PAYMENT_TERM] = g_param_spec_enum("payment_term", _("Payment Term"),
		_("The timeframe in which the invoice should be paid. Options: upon receipt, net 15, net "
		  "30, net 45, net 60, or custom."),
		HARVEST_INVOICE_PAYMENT_TERM_UPON_RECEIPT, HARVEST_INVOICE_PAYMENT_TERM_CUSTOM,
		HARVEST_INVOICE_PAYMENT_TERM_UPON_RECEIPT,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		HARVEST_TYPE_INVOICE_PAYMENT_TERM, HARVEST_INVOICE_PAYMENT_TERM_CUSTOM,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_SENT_AT]
		= g_param_spec_boxed("sent_at", _("Sent At"), _("Date and time the invoice was sent."),
			G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
			G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_PAID_AT]
		= g_param_spec_boxed("paid_at", _("Paid At"), _("Date and time the invoice was paid."),
			G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
			G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_PAID_DATE]
		= g_param_spec_boxed("paid_date", _("Paid Date"), _("Date the invoice was paid."),
			G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CLOSED_AT]  = g_param_spec_boxed("clcosed_at", _("Closed At"),
			G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CLOSED_AT]	= g_param_spec_boxed("clcosed_at", _("Closed At"),
		 _("Date and time the invoice was closed."), G_TYPE_DATE_TIME,
		 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_CREATED_AT] = g_param_spec_boxed("created_at", _("Created At"),
		_("Date and time the invoice was created."), G_TYPE_DATE_TIME,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
	obj_properties[PROP_UPDATED_AT] = g_param_spec_boxed("updated_at", _("Updated At"),
		_("Date and time the invoice was last updated."), G_TYPE_DATE_TIME,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);

	g_object_class_install_properties(obj_class, N_PROPS, obj_properties);
}

M harvest-glib/meson.build => harvest-glib/meson.build +13 -0
@@ 14,6 14,7 @@ harvest_glib_sources = [
    'harvest-api-client.c',
    'harvest-client.c',
    'harvest-common.c',
    'harvest-company.c',
    'harvest-creator.c',
    'harvest-estimate.c',
    'harvest-estimate-item-category.c',


@@ 42,6 43,7 @@ harvest_glib_public_headers = [
    'harvest-api-client.h',
    'harvest-client.h',
    'harvest-common.h',
    'harvest-company.h',
    'harvest-creator.h',
    'harvest-estimate.h',
    'harvest-estimate-item-category.h',


@@ 66,6 68,16 @@ harvest_glib_public_headers = [
    'harvest-users-me-request.h',
]

enums = gnome.mkenums_simple(
    'harvest-enum-types',
    sources: [
        'harvest-company.h',
        'harvest-estimate.h',
        'harvest-http.h',
        'harvest-invoice.h',
    ]
)

install_headers(harvest_glib_public_headers, subdir: 'harvest-glib')

harvest_glib_c_args = [


@@ 93,6 105,7 @@ harvest_glib_dependencies = [
harvest_glib = library(
    'harvest-glib',
    harvest_glib_sources,
    enums,
    version: harvest_glib_version,
    c_args: harvest_glib_c_args,
    dependencies: harvest_glib_dependencies,