diff --git a/demo/demo.sql b/demo/demo.sql index 5be2c8b..777d862 100644 --- a/demo/demo.sql +++ b/demo/demo.sql @@ -82,12 +82,11 @@ values (76, 'en', 'Tent') ; alter table campsite_type alter column campsite_type_id restart with 72; -insert into campsite_type (company_id, name, media_id, description) -values (52, 'Parceŀles', 62, '') - , (52, 'Safari Tents', 63, '') - , (52, 'Bungalous', 64, '') - , (52, 'Cabanes de fusta', 65, '') -; +select add_campsite_type(52, 62, 'Parceŀles', '', 6, true); +select add_campsite_type(52, 63, 'Safari Tents', '', 6, false); +select add_campsite_type(52, 64, 'Bungalous', '', 5, false); +select add_campsite_type(52, 65, 'Cabanes de fusta', '', 5, false); + insert into campsite_type_i18n (campsite_type_id, lang_tag, name, description) values (72, 'en', 'Plots', '') , (72, 'es', 'Parcelas', '') diff --git a/deploy/add_campsite_type.sql b/deploy/add_campsite_type.sql index 7472829..7686b4d 100644 --- a/deploy/add_campsite_type.sql +++ b/deploy/add_campsite_type.sql @@ -8,16 +8,16 @@ begin; set search_path to camper, public; -create or replace function add_campsite_type(company integer, media_id integer, name text, description text) returns uuid as +create or replace function add_campsite_type(company integer, media_id integer, name text, description text, max_campers integer, dogs_allowed boolean) returns uuid as $$ - insert into campsite_type (company_id, media_id, name, description) - values (company, media_id, name, xmlparse (content description)) + insert into campsite_type (company_id, media_id, name, description, max_campers, dogs_allowed) + values (company, media_id, name, xmlparse (content description), max_campers, dogs_allowed) returning slug; $$ language sql ; -revoke execute on function add_campsite_type(integer, integer, text, text) from public; -grant execute on function add_campsite_type(integer, integer, text, text) to admin; +revoke execute on function add_campsite_type(integer, integer, text, text, integer, boolean) from public; +grant execute on function add_campsite_type(integer, integer, text, text, integer, boolean) to admin; commit; diff --git a/deploy/campsite_type.sql b/deploy/campsite_type.sql index 7605d72..4b41a87 100644 --- a/deploy/campsite_type.sql +++ b/deploy/campsite_type.sql @@ -16,6 +16,8 @@ create table campsite_type ( name text not null constraint name_not_empty check(length(trim(name)) > 0), media_id integer not null references media, description xml not null default ''::xml, + max_campers integer not null constraint at_least_one_camper check(max_campers > 0), + dogs_allowed boolean not null, active boolean not null default true ); diff --git a/deploy/edit_campsite_type.sql b/deploy/edit_campsite_type.sql index a22c4f5..8c10e5a 100644 --- a/deploy/edit_campsite_type.sql +++ b/deploy/edit_campsite_type.sql @@ -8,12 +8,14 @@ begin; set search_path to camper, public; -create or replace function edit_campsite_type(slug uuid, media_id integer, name text, description text, active boolean) returns uuid as +create or replace function edit_campsite_type(slug uuid, media_id integer, name text, description text, max_campers integer, dogs_allowed boolean, active boolean) returns uuid as $$ update campsite_type set name = edit_campsite_type.name , description = xmlparse(content edit_campsite_type.description) , media_id = coalesce(edit_campsite_type.media_id, campsite_type.media_id) + , max_campers = edit_campsite_type.max_campers + , dogs_allowed = edit_campsite_type.dogs_allowed , active = edit_campsite_type.active where slug = edit_campsite_type.slug returning slug; @@ -21,7 +23,7 @@ $$ language sql ; -revoke execute on function edit_campsite_type(uuid, integer, text, text, boolean) from public; -grant execute on function edit_campsite_type(uuid, integer, text, text, boolean) to admin; +revoke execute on function edit_campsite_type(uuid, integer, text, text, integer, boolean, boolean) from public; +grant execute on function edit_campsite_type(uuid, integer, text, text, integer, boolean, boolean) to admin; commit; diff --git a/pkg/campsite/types/admin.go b/pkg/campsite/types/admin.go index 83015cc..8864e7b 100644 --- a/pkg/campsite/types/admin.go +++ b/pkg/campsite/types/admin.go @@ -183,13 +183,13 @@ func (page *typeIndex) MustRender(w http.ResponseWriter, r *http.Request, user * func addType(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) { f := newTypeForm() processTypeForm(w, r, user, company, conn, f, func(ctx context.Context) { - conn.MustExec(ctx, "select add_campsite_type($1, $2, $3, $4)", company.ID, f.Media, f.Name, f.Description) + conn.MustExec(ctx, "select add_campsite_type($1, $2, $3, $4, $5, $6)", company.ID, f.Media, f.Name, f.Description, f.MaxCampers, f.DogsAllowed) }) } func editType(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, f *typeForm) { processTypeForm(w, r, user, company, conn, f, func(ctx context.Context) { - conn.MustExec(ctx, "select edit_campsite_type($1, $2, $3, $4, $5)", f.Slug, f.Media, f.Name, f.Description, f.Active) + conn.MustExec(ctx, "select edit_campsite_type($1, $2, $3, $4, $5, $6, $7)", f.Slug, f.Media, f.Name, f.Description, f.MaxCampers, f.DogsAllowed, f.Active) }) } @@ -220,6 +220,8 @@ type typeForm struct { Active *form.Checkbox Media *form.Media Name *form.Input + MaxCampers *form.Input + DogsAllowed *form.Checkbox Description *form.Input } @@ -239,6 +241,12 @@ func newTypeForm() *typeForm { Name: &form.Input{ Name: "name", }, + MaxCampers: &form.Input{ + Name: "max_campers", + }, + DogsAllowed: &form.Checkbox{ + Name: "dogs_allowed", + }, Description: &form.Input{ Name: "description", }, @@ -251,11 +259,13 @@ func (f *typeForm) FillFromDatabase(ctx context.Context, conn *database.Conn, sl select name , description , media_id::text + , max_campers::text + , dogs_allowed , active from campsite_type where slug = $1 `, slug) - return row.Scan(&f.Name.Val, &f.Description.Val, &f.Media.Val, &f.Active.Checked) + return row.Scan(&f.Name.Val, &f.Description.Val, &f.Media.Val, &f.MaxCampers.Val, &f.DogsAllowed.Checked, &f.Active.Checked) } func (f *typeForm) Parse(r *http.Request) error { @@ -264,6 +274,8 @@ func (f *typeForm) Parse(r *http.Request) error { } f.Active.FillValue(r) f.Name.FillValue(r) + f.MaxCampers.FillValue(r) + f.DogsAllowed.FillValue(r) f.Description.FillValue(r) f.Media.FillValue(r) return nil @@ -271,12 +283,19 @@ func (f *typeForm) Parse(r *http.Request) error { func (f *typeForm) Valid(ctx context.Context, conn *database.Conn, l *locale.Locale) (bool, error) { v := form.NewValidator(l) - v.CheckRequired(f.Name, l.GettextNoop("Name can not be empty.")) + if v.CheckRequired(f.Name, l.GettextNoop("Name can not be empty.")) { + v.CheckMinLength(f.Name, 1, l.GettextNoop("Name must have at least one letter.")) + } if v.CheckRequired(f.Media.Input, l.GettextNoop("Cover image can not be empty.")) { if _, err := v.CheckImageMedia(ctx, conn, f.Media.Input, l.GettextNoop("Cover image must be an image media type.")); err != nil { return false, err } } + if v.CheckRequired(f.MaxCampers, l.GettextNoop("Maximum number of campers can not be empty.")) { + if v.CheckValidInteger(f.MaxCampers, l.GettextNoop("Maximum number of campers must be an integer number.")) { + v.CheckMinInteger(f.MaxCampers, 1, l.GettextNoop("Maximum number of campers must be one or greater.")) + } + } return v.AllOK, nil } diff --git a/pkg/form/validator.go b/pkg/form/validator.go index cd04d47..d3131e8 100644 --- a/pkg/form/validator.go +++ b/pkg/form/validator.go @@ -38,6 +38,16 @@ func (v *Validator) CheckMinLength(input *Input, min int, message string) bool { return v.Check(input, len(input.Val) >= min, message) } +func (v *Validator) CheckMinInteger(input *Input, min int, message string) bool { + i, _ := strconv.Atoi(input.Val) + return v.Check(input, i >= min, message) +} + +func (v *Validator) CheckValidInteger(input *Input, message string) bool { + _, err := strconv.Atoi(input.Val) + return v.Check(input, err == nil, message) +} + func (v *Validator) CheckValidEmail(input *Input, message string) bool { _, err := mail.ParseAddress(input.Val) return v.Check(input, err == nil, message) diff --git a/po/ca.po b/po/ca.po index c038146..7ebeb5d 100644 --- a/po/ca.po +++ b/po/ca.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: camper\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2023-09-27 02:15+0200\n" +"POT-Creation-Date: 2023-09-29 20:08+0200\n" "PO-Revision-Date: 2023-07-22 23:45+0200\n" "Last-Translator: jordi fita mas \n" "Language-Team: Catalan \n" @@ -137,7 +137,7 @@ msgstr "Hi ha diversos punts on poder anar amb caiac, des de trams del riu Ter c msgid "Campsite Montagut" msgstr "Càmping Montagut" -#: web/templates/public/layout.gohtml:22 web/templates/admin/layout.gohtml:19 +#: web/templates/public/layout.gohtml:22 web/templates/admin/layout.gohtml:18 msgid "Skip to main content" msgstr "Salta al contingut principal" @@ -165,7 +165,7 @@ msgstr "Llegenda" #: web/templates/admin/carousel/form.gohtml:47 #: web/templates/admin/campsite/form.gohtml:70 -#: web/templates/admin/campsite/type/form.gohtml:66 +#: web/templates/admin/campsite/type/form.gohtml:82 #: web/templates/admin/season/form.gohtml:64 #: web/templates/admin/services/form.gohtml:69 #: web/templates/admin/media/form.gohtml:35 @@ -175,7 +175,7 @@ msgstr "Actualitza" #: web/templates/admin/carousel/form.gohtml:49 #: web/templates/admin/campsite/form.gohtml:72 -#: web/templates/admin/campsite/type/form.gohtml:68 +#: web/templates/admin/campsite/type/form.gohtml:84 #: web/templates/admin/season/form.gohtml:66 #: web/templates/admin/services/form.gohtml:71 msgctxt "action" @@ -311,6 +311,16 @@ msgid "Name" msgstr "Nom" #: web/templates/admin/campsite/type/form.gohtml:57 +msgctxt "input" +msgid "Maximum number of campers" +msgstr "Número màxim de persones" + +#: web/templates/admin/campsite/type/form.gohtml:67 +msgctxt "input" +msgid "Dogs allowed" +msgstr "Es permeten gossos" + +#: web/templates/admin/campsite/type/form.gohtml:73 #: web/templates/admin/campsite/type/l10n.gohtml:32 #: web/templates/admin/services/form.gohtml:60 #: web/templates/admin/services/l10n.gohtml:32 @@ -331,7 +341,7 @@ msgid "Add Type" msgstr "Afegeix tipus" #: web/templates/admin/campsite/type/index.gohtml:17 -#: web/templates/admin/season/index.gohtml:17 +#: web/templates/admin/season/index.gohtml:18 msgctxt "header" msgid "Name" msgstr "Nom" @@ -389,7 +399,7 @@ msgctxt "action" msgid "Add Season" msgstr "Afegeix temporada" -#: web/templates/admin/season/index.gohtml:18 +#: web/templates/admin/season/index.gohtml:17 msgctxt "header" msgid "Color" msgstr "Color" @@ -403,41 +413,47 @@ msgctxt "title" msgid "Calendar" msgstr "Calendari" -#: web/templates/admin/season/index.gohtml:47 +#: web/templates/admin/season/calendar.gohtml:16 msgctxt "day" msgid "Mon" msgstr "dl" -#: web/templates/admin/season/index.gohtml:48 +#: web/templates/admin/season/calendar.gohtml:17 msgctxt "day" msgid "Tue" msgstr "dt" -#: web/templates/admin/season/index.gohtml:49 +#: web/templates/admin/season/calendar.gohtml:18 msgctxt "day" msgid "Wed" msgstr "dc" -#: web/templates/admin/season/index.gohtml:50 +#: web/templates/admin/season/calendar.gohtml:19 msgctxt "day" msgid "Thu" msgstr "dj" -#: web/templates/admin/season/index.gohtml:51 +#: web/templates/admin/season/calendar.gohtml:20 msgctxt "day" msgid "Fri" msgstr "dv" -#: web/templates/admin/season/index.gohtml:52 +#: web/templates/admin/season/calendar.gohtml:21 msgctxt "day" msgid "Sat" msgstr "ds" -#: web/templates/admin/season/index.gohtml:53 +#: web/templates/admin/season/calendar.gohtml:22 msgctxt "day" msgid "Sun" msgstr "dg" +#: web/templates/admin/season/calendar.gohtml:49 +#: web/templates/admin/media/picker.gohtml:61 +msgctxt "action" +msgid "Cancel" +msgstr "Canceŀla" + #: web/templates/admin/dashboard.gohtml:6 #: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:68 msgctxt "title" @@ -729,11 +745,6 @@ msgstr "Elecció d’un mèdia existent" msgid "No media uploaded yet." msgstr "No s’ha pujat cap mèdia encara." -#: web/templates/admin/media/picker.gohtml:61 -msgctxt "action" -msgid "Cancel" -msgstr "Canceŀla" - #: web/templates/admin/media/form.gohtml:6 #: web/templates/admin/media/form.gohtml:12 msgctxt "title" @@ -801,7 +812,7 @@ msgid "Automatic" msgstr "Automàtic" #: pkg/app/user.go:249 pkg/campsite/types/l10n.go:82 -#: pkg/campsite/types/admin.go:274 pkg/season/admin.go:301 +#: pkg/campsite/types/admin.go:286 pkg/season/admin.go:335 #: pkg/services/l10n.go:73 pkg/services/admin.go:266 msgid "Name can not be empty." msgstr "No podeu deixar el nom en blanc." @@ -822,24 +833,40 @@ msgstr "El fitxer has de ser una imatge PNG o JPEG vàlida." msgid "Access forbidden" msgstr "Accés prohibit" -#: pkg/campsite/types/admin.go:236 +#: pkg/campsite/types/admin.go:238 msgctxt "input" msgid "Cover image" msgstr "Imatge de portada" -#: pkg/campsite/types/admin.go:237 +#: pkg/campsite/types/admin.go:239 msgctxt "action" msgid "Set campsite type cover" msgstr "Estableix la portada del tipus d’allotjament" -#: pkg/campsite/types/admin.go:275 +#: pkg/campsite/types/admin.go:287 +msgid "Name must have at least one letter." +msgstr "El nom ha de tenir com a mínim una lletra." + +#: pkg/campsite/types/admin.go:289 msgid "Cover image can not be empty." msgstr "No podeu deixar la imatge de portada en blanc." -#: pkg/campsite/types/admin.go:276 +#: pkg/campsite/types/admin.go:290 msgid "Cover image must be an image media type." msgstr "La imatge de portada ha de ser un mèdia de tipus imatge." +#: pkg/campsite/types/admin.go:294 +msgid "Maximum number of campers can not be empty." +msgstr "No podeu deixar el número màxim de persones en blanc." + +#: pkg/campsite/types/admin.go:295 +msgid "Maximum number of campers must be an integer number." +msgstr "El número màxim de persones ha de ser enter." + +#: pkg/campsite/types/admin.go:296 +msgid "Maximum number of campers must be one or greater." +msgstr "El número màxim de persones no pot ser zero." + #: pkg/campsite/admin.go:226 msgid "Selected campsite type is not valid." msgstr "El tipus d’allotjament escollit no és vàlid." @@ -848,74 +875,95 @@ msgstr "El tipus d’allotjament escollit no és vàlid." msgid "Label can not be empty." msgstr "No podeu deixar l’etiqueta en blanc." -#: pkg/season/admin.go:127 +#: pkg/season/admin.go:155 msgctxt "month" msgid "January" msgstr "gener" -#: pkg/season/admin.go:128 +#: pkg/season/admin.go:156 msgctxt "month" msgid "February" msgstr "febrer" -#: pkg/season/admin.go:129 +#: pkg/season/admin.go:157 msgctxt "month" msgid "March" msgstr "març" -#: pkg/season/admin.go:130 +#: pkg/season/admin.go:158 msgctxt "month" msgid "April" msgstr "abril" -#: pkg/season/admin.go:131 +#: pkg/season/admin.go:159 msgctxt "month" msgid "May" msgstr "maig" -#: pkg/season/admin.go:132 +#: pkg/season/admin.go:160 msgctxt "month" msgid "June" msgstr "juny" -#: pkg/season/admin.go:133 +#: pkg/season/admin.go:161 msgctxt "month" msgid "July" msgstr "juliol" -#: pkg/season/admin.go:134 +#: pkg/season/admin.go:162 msgctxt "month" msgid "August" msgstr "agost" -#: pkg/season/admin.go:135 +#: pkg/season/admin.go:163 msgctxt "month" msgid "September" msgstr "setembre" -#: pkg/season/admin.go:136 +#: pkg/season/admin.go:164 msgctxt "month" msgid "October" msgstr "octubre" -#: pkg/season/admin.go:137 +#: pkg/season/admin.go:165 msgctxt "month" msgid "November" msgstr "novembre" -#: pkg/season/admin.go:138 +#: pkg/season/admin.go:166 msgctxt "month" msgid "December" msgstr "desembre" -#: pkg/season/admin.go:302 +#: pkg/season/admin.go:336 msgid "Color can not be empty." msgstr "No podeu deixar el color en blanc." -#: pkg/season/admin.go:303 +#: pkg/season/admin.go:337 msgid "This color is not valid. It must be like #123abc." msgstr "Aquest color no és vàlid. Hauria de ser similar a #123abc." +#: pkg/season/admin.go:413 +msgctxt "action" +msgid "Unset" +msgstr "Desassigna" + +#: pkg/season/admin.go:444 +msgid "Start date can not be empty." +msgstr "No podeu deixar la data d’inici en blanc." + +#: pkg/season/admin.go:445 +msgid "Start date must be a valid date." +msgstr "La data d’inici ha de ser una data vàlida." + +#: pkg/season/admin.go:447 +msgid "End date can not be empty." +msgstr "No podeu deixar la data de fi en blanc." + +#: pkg/season/admin.go:448 +msgid "End date must be a valid date." +msgstr "La data de fi ha de ser una data vàlida." + #: pkg/services/admin.go:265 msgid "Selected icon is not valid." msgstr "La icona escollida no és vàlida." diff --git a/po/es.po b/po/es.po index 4bc7490..cd60386 100644 --- a/po/es.po +++ b/po/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: camper\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2023-09-27 02:15+0200\n" +"POT-Creation-Date: 2023-09-29 20:08+0200\n" "PO-Revision-Date: 2023-07-22 23:46+0200\n" "Last-Translator: jordi fita mas \n" "Language-Team: Spanish \n" @@ -137,7 +137,7 @@ msgstr "Hay diversos puntos dónde podéis ir en kayak, desde tramos del río Te msgid "Campsite Montagut" msgstr "Camping Montagut" -#: web/templates/public/layout.gohtml:22 web/templates/admin/layout.gohtml:19 +#: web/templates/public/layout.gohtml:22 web/templates/admin/layout.gohtml:18 msgid "Skip to main content" msgstr "Saltar al contenido principal" @@ -165,7 +165,7 @@ msgstr "Leyenda" #: web/templates/admin/carousel/form.gohtml:47 #: web/templates/admin/campsite/form.gohtml:70 -#: web/templates/admin/campsite/type/form.gohtml:66 +#: web/templates/admin/campsite/type/form.gohtml:82 #: web/templates/admin/season/form.gohtml:64 #: web/templates/admin/services/form.gohtml:69 #: web/templates/admin/media/form.gohtml:35 @@ -175,7 +175,7 @@ msgstr "Actualizar" #: web/templates/admin/carousel/form.gohtml:49 #: web/templates/admin/campsite/form.gohtml:72 -#: web/templates/admin/campsite/type/form.gohtml:68 +#: web/templates/admin/campsite/type/form.gohtml:84 #: web/templates/admin/season/form.gohtml:66 #: web/templates/admin/services/form.gohtml:71 msgctxt "action" @@ -311,6 +311,16 @@ msgid "Name" msgstr "Nombre" #: web/templates/admin/campsite/type/form.gohtml:57 +msgctxt "input" +msgid "Maximum number of campers" +msgstr "Número máximo de personas" + +#: web/templates/admin/campsite/type/form.gohtml:67 +msgctxt "input" +msgid "Dogs allowed" +msgstr "Se permiten perros" + +#: web/templates/admin/campsite/type/form.gohtml:73 #: web/templates/admin/campsite/type/l10n.gohtml:32 #: web/templates/admin/services/form.gohtml:60 #: web/templates/admin/services/l10n.gohtml:32 @@ -331,7 +341,7 @@ msgid "Add Type" msgstr "Añadir tipo" #: web/templates/admin/campsite/type/index.gohtml:17 -#: web/templates/admin/season/index.gohtml:17 +#: web/templates/admin/season/index.gohtml:18 msgctxt "header" msgid "Name" msgstr "Nombre" @@ -389,7 +399,7 @@ msgctxt "action" msgid "Add Season" msgstr "Añadir temporada" -#: web/templates/admin/season/index.gohtml:18 +#: web/templates/admin/season/index.gohtml:17 msgctxt "header" msgid "Color" msgstr "Color" @@ -403,41 +413,47 @@ msgctxt "title" msgid "Calendar" msgstr "Calendario" -#: web/templates/admin/season/index.gohtml:47 +#: web/templates/admin/season/calendar.gohtml:16 msgctxt "day" msgid "Mon" msgstr "lu" -#: web/templates/admin/season/index.gohtml:48 +#: web/templates/admin/season/calendar.gohtml:17 msgctxt "day" msgid "Tue" msgstr "ma" -#: web/templates/admin/season/index.gohtml:49 +#: web/templates/admin/season/calendar.gohtml:18 msgctxt "day" msgid "Wed" msgstr "mi" -#: web/templates/admin/season/index.gohtml:50 +#: web/templates/admin/season/calendar.gohtml:19 msgctxt "day" msgid "Thu" msgstr "ju" -#: web/templates/admin/season/index.gohtml:51 +#: web/templates/admin/season/calendar.gohtml:20 msgctxt "day" msgid "Fri" msgstr "vi" -#: web/templates/admin/season/index.gohtml:52 +#: web/templates/admin/season/calendar.gohtml:21 msgctxt "day" msgid "Sat" msgstr "sá" -#: web/templates/admin/season/index.gohtml:53 +#: web/templates/admin/season/calendar.gohtml:22 msgctxt "day" msgid "Sun" msgstr "do" +#: web/templates/admin/season/calendar.gohtml:49 +#: web/templates/admin/media/picker.gohtml:61 +msgctxt "action" +msgid "Cancel" +msgstr "Cancelar" + #: web/templates/admin/dashboard.gohtml:6 #: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:68 msgctxt "title" @@ -729,11 +745,6 @@ msgstr "Elección de un medio existente" msgid "No media uploaded yet." msgstr "No se ha subido ningún medio todavía." -#: web/templates/admin/media/picker.gohtml:61 -msgctxt "action" -msgid "Cancel" -msgstr "Cancelar" - #: web/templates/admin/media/form.gohtml:6 #: web/templates/admin/media/form.gohtml:12 msgctxt "title" @@ -801,7 +812,7 @@ msgid "Automatic" msgstr "Automático" #: pkg/app/user.go:249 pkg/campsite/types/l10n.go:82 -#: pkg/campsite/types/admin.go:274 pkg/season/admin.go:301 +#: pkg/campsite/types/admin.go:286 pkg/season/admin.go:335 #: pkg/services/l10n.go:73 pkg/services/admin.go:266 msgid "Name can not be empty." msgstr "No podéis dejar el nombre en blanco." @@ -822,24 +833,40 @@ msgstr "El archivo tiene que ser una imagen PNG o JPEG válida." msgid "Access forbidden" msgstr "Acceso prohibido" -#: pkg/campsite/types/admin.go:236 +#: pkg/campsite/types/admin.go:238 msgctxt "input" msgid "Cover image" msgstr "Imagen de portada" -#: pkg/campsite/types/admin.go:237 +#: pkg/campsite/types/admin.go:239 msgctxt "action" msgid "Set campsite type cover" msgstr "Establecer la portada del tipo de alojamiento" -#: pkg/campsite/types/admin.go:275 +#: pkg/campsite/types/admin.go:287 +msgid "Name must have at least one letter." +msgstr "El nombre tiene que tener como mínimo una letra." + +#: pkg/campsite/types/admin.go:289 msgid "Cover image can not be empty." msgstr "No podéis dejar la imagen de portada en blanco." -#: pkg/campsite/types/admin.go:276 +#: pkg/campsite/types/admin.go:290 msgid "Cover image must be an image media type." msgstr "La imagen de portada tiene que ser un medio de tipo imagen." +#: pkg/campsite/types/admin.go:294 +msgid "Maximum number of campers can not be empty." +msgstr "No podéis dejar el número máximo de personas en blanco." + +#: pkg/campsite/types/admin.go:295 +msgid "Maximum number of campers must be an integer number." +msgstr "El número máximo de personas tiene que ser entero." + +#: pkg/campsite/types/admin.go:296 +msgid "Maximum number of campers must be one or greater." +msgstr "El número máximo de personas no puede ser cero." + #: pkg/campsite/admin.go:226 msgid "Selected campsite type is not valid." msgstr "El tipo de alojamiento escogido no es válido." @@ -848,74 +875,95 @@ msgstr "El tipo de alojamiento escogido no es válido." msgid "Label can not be empty." msgstr "No podéis dejar la etiqueta en blanco." -#: pkg/season/admin.go:127 +#: pkg/season/admin.go:155 msgctxt "month" msgid "January" msgstr "enero" -#: pkg/season/admin.go:128 +#: pkg/season/admin.go:156 msgctxt "month" msgid "February" msgstr "febrero" -#: pkg/season/admin.go:129 +#: pkg/season/admin.go:157 msgctxt "month" msgid "March" msgstr "marzo" -#: pkg/season/admin.go:130 +#: pkg/season/admin.go:158 msgctxt "month" msgid "April" msgstr "abril" -#: pkg/season/admin.go:131 +#: pkg/season/admin.go:159 msgctxt "month" msgid "May" msgstr "mayo" -#: pkg/season/admin.go:132 +#: pkg/season/admin.go:160 msgctxt "month" msgid "June" msgstr "junio" -#: pkg/season/admin.go:133 +#: pkg/season/admin.go:161 msgctxt "month" msgid "July" msgstr "julio" -#: pkg/season/admin.go:134 +#: pkg/season/admin.go:162 msgctxt "month" msgid "August" msgstr "agosto" -#: pkg/season/admin.go:135 +#: pkg/season/admin.go:163 msgctxt "month" msgid "September" msgstr "septiembre" -#: pkg/season/admin.go:136 +#: pkg/season/admin.go:164 msgctxt "month" msgid "October" msgstr "octubre" -#: pkg/season/admin.go:137 +#: pkg/season/admin.go:165 msgctxt "month" msgid "November" msgstr "noviembre" -#: pkg/season/admin.go:138 +#: pkg/season/admin.go:166 msgctxt "month" msgid "December" msgstr "diciembre" -#: pkg/season/admin.go:302 +#: pkg/season/admin.go:336 msgid "Color can not be empty." msgstr "No podéis dejar el color en blanco." -#: pkg/season/admin.go:303 +#: pkg/season/admin.go:337 msgid "This color is not valid. It must be like #123abc." msgstr "Este color no es válido. Tiene que ser parecido a #123abc." +#: pkg/season/admin.go:413 +msgctxt "action" +msgid "Unset" +msgstr "Desasignar" + +#: pkg/season/admin.go:444 +msgid "Start date can not be empty." +msgstr "No podéis dejar la fecha de inicio en blanco." + +#: pkg/season/admin.go:445 +msgid "Start date must be a valid date." +msgstr "La fecha de inicio tiene que ser una fecha válida." + +#: pkg/season/admin.go:447 +msgid "End date can not be empty." +msgstr "No podéis dejar la fecha final en blanco." + +#: pkg/season/admin.go:448 +msgid "End date must be a valid date." +msgstr "La fecha final tiene que ser una fecha válida." + #: pkg/services/admin.go:265 msgid "Selected icon is not valid." msgstr "El icono escogido no es válido." diff --git a/revert/add_campsite_type.sql b/revert/add_campsite_type.sql index 88a5efc..8c02597 100644 --- a/revert/add_campsite_type.sql +++ b/revert/add_campsite_type.sql @@ -2,6 +2,6 @@ begin; -drop function if exists camper.add_campsite_type(integer, integer, text, text); +drop function if exists camper.add_campsite_type(integer, integer, text, text, integer, boolean); commit; diff --git a/revert/edit_campsite_type.sql b/revert/edit_campsite_type.sql index 82b461d..84604cb 100644 --- a/revert/edit_campsite_type.sql +++ b/revert/edit_campsite_type.sql @@ -2,6 +2,6 @@ begin; -drop function if exists camper.edit_campsite_type(uuid, integer, text, text, boolean); +drop function if exists camper.edit_campsite_type(uuid, integer, text, text, integer, boolean, boolean); commit; diff --git a/test/add_campsite.sql b/test/add_campsite.sql index bb18212..6190f7f 100644 --- a/test/add_campsite.sql +++ b/test/add_campsite.sql @@ -43,10 +43,10 @@ values (3, 1, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a , (4, 2, 'cover4.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a"};')) ; -insert into campsite_type (campsite_type_id, company_id, media_id, name) -values (11, 1, 3, 'A') - , (12, 1, 3, 'B') - , (21, 2, 4, 'C') +insert into campsite_type (campsite_type_id, company_id, media_id, name, dogs_allowed, max_campers) +values (11, 1, 3, 'A', false, 5) + , (12, 1, 3, 'B', false, 5) + , (21, 2, 4, 'C', false, 5) ; select lives_ok( diff --git a/test/add_campsite_type.sql b/test/add_campsite_type.sql index 5160a7a..fb2ac06 100644 --- a/test/add_campsite_type.sql +++ b/test/add_campsite_type.sql @@ -9,15 +9,15 @@ set search_path to camper, public; select plan(13); -select has_function('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text']); -select function_lang_is('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text'], 'sql'); -select function_returns('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text'], 'uuid'); -select isnt_definer('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text']); -select volatility_is('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text'], 'volatile'); -select function_privs_are('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text'], 'guest', array[]::text[]); -select function_privs_are('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text'], 'employee', array[]::text[]); -select function_privs_are('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text'], 'admin', array['EXECUTE']); -select function_privs_are('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text'], 'authenticator', array[]::text[]); +select has_function('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text', 'integer', 'boolean']); +select function_lang_is('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text', 'integer', 'boolean'], 'sql'); +select function_returns('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text', 'integer', 'boolean'], 'uuid'); +select isnt_definer('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text', 'integer', 'boolean']); +select volatility_is('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text', 'integer', 'boolean'], 'volatile'); +select function_privs_are('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text', 'integer', 'boolean'], 'guest', array[]::text[]); +select function_privs_are('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text', 'integer', 'boolean'], 'employee', array[]::text[]); +select function_privs_are('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text', 'integer', 'boolean'], 'admin', array['EXECUTE']); +select function_privs_are('camper', 'add_campsite_type', array ['integer', 'integer', 'text', 'text', 'integer', 'boolean'], 'authenticator', array[]::text[]); set client_min_messages to warning; @@ -44,19 +44,19 @@ values (3, 1, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a ; select lives_ok( - $$ select add_campsite_type(1, 3, 'Type A', '

This is what, exactly?

Dunno

') $$, + $$ select add_campsite_type(1, 3, 'Type A', '

This is what, exactly?

Dunno

', 5, true) $$, 'Should be able to add a campsite type to the first company' ); select lives_ok( - $$ select add_campsite_type(2, 4, 'Type B', '') $$, + $$ select add_campsite_type(2, 4, 'Type B', '', 2, false) $$, 'Should be able to add a campsite type to the second company' ); select bag_eq( - $$ select company_id, media_id, name, description::text, active from campsite_type $$, - $$ values (1, 3, 'Type A', '

This is what, exactly?

Dunno

', true) - , (2, 4, 'Type B', '', true) + $$ select company_id, media_id, name, description::text, active, max_campers, dogs_allowed from campsite_type $$, + $$ values (1, 3, 'Type A', '

This is what, exactly?

Dunno

', true, 5, true) + , (2, 4, 'Type B', '', true, 2, false) $$, 'Should have added all two campsite type' ); diff --git a/test/campsite.sql b/test/campsite.sql index 472570f..66d2a57 100644 --- a/test/campsite.sql +++ b/test/campsite.sql @@ -90,9 +90,9 @@ values (6, 2, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a , (8, 4, 'cover4.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a"};')) ; -insert into campsite_type (campsite_type_id, company_id, media_id, name) -values (22, 2, 6, 'Wooden lodge') - , (44, 4, 8, 'Bungalow') +insert into campsite_type (campsite_type_id, company_id, media_id, name, dogs_allowed, max_campers) +values (22, 2, 6, 'Wooden lodge', true, 5) + , (44, 4, 8, 'Bungalow', false, 4) ; insert into campsite (company_id, campsite_type_id, label) diff --git a/test/campsite_type.sql b/test/campsite_type.sql index 1342c62..9da82ea 100644 --- a/test/campsite_type.sql +++ b/test/campsite_type.sql @@ -5,7 +5,7 @@ reset client_min_messages; begin; -select plan(56); +select plan(65); set search_path to camper, public; @@ -54,6 +54,16 @@ select col_not_null('campsite_type', 'description'); select col_has_default('campsite_type', 'description'); --select col_default_is('campsite_type', 'description', ''); +select has_column('campsite_type', 'max_campers'); +select col_type_is('campsite_type', 'max_campers', 'integer'); +select col_not_null('campsite_type', 'max_campers'); +select col_hasnt_default('campsite_type', 'max_campers'); + +select has_column('campsite_type', 'dogs_allowed'); +select col_type_is('campsite_type', 'dogs_allowed', 'boolean'); +select col_not_null('campsite_type', 'dogs_allowed'); +select col_hasnt_default('campsite_type', 'dogs_allowed'); + select has_column('campsite_type', 'active'); select col_type_is('campsite_type', 'active', 'boolean'); select col_not_null('campsite_type', 'active'); @@ -100,9 +110,9 @@ values (6, 2, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a , (8, 4, 'cover4.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a"};')) ; -insert into campsite_type (company_id, name, media_id) -values (2, 'Wooden lodge', 6) - , (4, 'Bungalow', 8) +insert into campsite_type (company_id, name, media_id, dogs_allowed, max_campers) +values (2, 'Wooden lodge', 6, false, 7) + , (4, 'Bungalow', 8, false, 6) ; prepare campsite_type_data as @@ -123,7 +133,7 @@ reset role; select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2'); select lives_ok( - $$ insert into campsite_type(company_id, name, media_id) values (2, 'Another type', 6) $$, + $$ insert into campsite_type(company_id, name, media_id, dogs_allowed, max_campers) values (2, 'Another type', 6, true, 7) $$, 'Admin from company 2 should be able to insert a new campsite type to that company.' ); @@ -164,7 +174,7 @@ select bag_eq( ); select throws_ok( - $$ insert into campsite_type (company_id, name, media_id) values (4, 'Another type', 6) $$, + $$ insert into campsite_type (company_id, name, media_id, dogs_allowed, max_campers) values (4, 'Another type', 6, true, 6) $$, '42501', 'new row violates row-level security policy for table "campsite_type"', 'Admin from company 2 should NOT be able to insert new campsite types to company 4.' ); @@ -202,11 +212,17 @@ select bag_eq( ); select throws_ok( - $$ insert into campsite_type (company_id, name, media_id) values (2, ' ', 6) $$, + $$ insert into campsite_type (company_id, name, media_id, dogs_allowed, max_campers) values (2, ' ', 6, false, 5) $$, '23514', 'new row for relation "campsite_type" violates check constraint "name_not_empty"', 'Should not be able to insert campsite types with a blank name.' ); +select throws_ok( + $$ insert into campsite_type (company_id, name, media_id, dogs_allowed, max_campers) values (2, 'Name', 6, false, 0) $$, + '23514', 'new row for relation "campsite_type" violates check constraint "at_least_one_camper"', + 'Should not be able to insert campsite types with no campers allowed.' +); + reset role; diff --git a/test/edit_campsite.sql b/test/edit_campsite.sql index 41e6572..31b075f 100644 --- a/test/edit_campsite.sql +++ b/test/edit_campsite.sql @@ -40,10 +40,10 @@ insert into media (media_id, company_id, original_filename, content_hash) values (3, 1, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a"};')) ; -insert into campsite_type (campsite_type_id, company_id, media_id, name) -values (11, 1, 3, 'Type A') - , (12, 1, 3, 'Type B') - , (13, 1, 3, 'Type C') +insert into campsite_type (campsite_type_id, company_id, media_id, name, dogs_allowed, max_campers) +values (11, 1, 3, 'Type A', false, 5) + , (12, 1, 3, 'Type B', false, 5) + , (13, 1, 3, 'Type C', false, 5) ; insert into campsite (campsite_id, company_id, campsite_type_id, label, active) diff --git a/test/edit_campsite_type.sql b/test/edit_campsite_type.sql index 23e3255..3d50ccd 100644 --- a/test/edit_campsite_type.sql +++ b/test/edit_campsite_type.sql @@ -9,15 +9,15 @@ set search_path to camper, public; select plan(12); -select has_function('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'boolean']); -select function_lang_is('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'boolean'], 'sql'); -select function_returns('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'boolean'], 'uuid'); -select isnt_definer('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'boolean']); -select volatility_is('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'boolean'], 'volatile'); -select function_privs_are('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'boolean'], 'guest', array[]::text[]); -select function_privs_are('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'boolean'], 'employee', array[]::text[]); -select function_privs_are('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'boolean'], 'admin', array['EXECUTE']); -select function_privs_are('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'boolean'], 'authenticator', array[]::text[]); +select has_function('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'integer', 'boolean', 'boolean']); +select function_lang_is('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'integer', 'boolean', 'boolean'], 'sql'); +select function_returns('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'integer', 'boolean', 'boolean'], 'uuid'); +select isnt_definer('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'integer', 'boolean', 'boolean']); +select volatility_is('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'integer', 'boolean', 'boolean'], 'volatile'); +select function_privs_are('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'integer', 'boolean', 'boolean'], 'guest', array[]::text[]); +select function_privs_are('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'integer', 'boolean', 'boolean'], 'employee', array[]::text[]); +select function_privs_are('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'integer', 'boolean', 'boolean'], 'admin', array['EXECUTE']); +select function_privs_are('camper', 'edit_campsite_type', array ['uuid', 'integer', 'text', 'text', 'integer', 'boolean', 'boolean'], 'authenticator', array[]::text[]); set client_min_messages to warning; truncate campsite_type cascade; @@ -43,25 +43,25 @@ values (2, 1, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a , (4, 1, 'cover4.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffff00","a"};')) ; -insert into campsite_type (company_id, slug, media_id, name, description, active) -values (1, '87452b88-b48f-48d3-bb6c-0296de64164e', 2, 'Type A', '

A

', true) - , (1, '9b6370f7-f941-46f2-bc6e-de455675bd0a', 3, 'Type B', '

B

', false) +insert into campsite_type (company_id, slug, media_id, name, description, max_campers, dogs_allowed, active) +values (1, '87452b88-b48f-48d3-bb6c-0296de64164e', 2, 'Type A', '

A

', 5, false, true) + , (1, '9b6370f7-f941-46f2-bc6e-de455675bd0a', 3, 'Type B', '

B

', 4, true, false) ; select lives_ok( - $$ select edit_campsite_type('87452b88-b48f-48d3-bb6c-0296de64164e', 4, 'Type 1', '

1

', false) $$, + $$ select edit_campsite_type('87452b88-b48f-48d3-bb6c-0296de64164e', 4, 'Type 1', '

1

', 2, true, false) $$, 'Should be able to edit the first type' ); select lives_ok( - $$ select edit_campsite_type('9b6370f7-f941-46f2-bc6e-de455675bd0a', null, 'Type 2', '

2

', true) $$, + $$ select edit_campsite_type('9b6370f7-f941-46f2-bc6e-de455675bd0a', null, 'Type 2', '

2

', 9, false, true) $$, 'Should be able to edit the second type' ); select bag_eq( - $$ select slug::text, media_id, name, description::text, active from campsite_type $$, - $$ values ('87452b88-b48f-48d3-bb6c-0296de64164e', 4, 'Type 1', '

1

', false) - , ('9b6370f7-f941-46f2-bc6e-de455675bd0a', 3, 'Type 2', '

2

', true) + $$ select slug::text, media_id, name, description::text, max_campers, dogs_allowed, active from campsite_type $$, + $$ values ('87452b88-b48f-48d3-bb6c-0296de64164e', 4, 'Type 1', '

1

', 2, true, false) + , ('9b6370f7-f941-46f2-bc6e-de455675bd0a', 3, 'Type 2', '

2

', 9, false, true) $$, 'Should have updated all campsite types.' ); diff --git a/test/translate_campsite_type.sql b/test/translate_campsite_type.sql index 1337751..efb7e6c 100644 --- a/test/translate_campsite_type.sql +++ b/test/translate_campsite_type.sql @@ -43,9 +43,9 @@ values (2, 1, 'cover2.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffffff","a , (4, 1, 'cover4.xpm', sha256('static char *s[]={"1 1 1 1","a c #ffff00","a"};')) ; -insert into campsite_type (company_id, slug, media_id, name, description, active) -values (1, '87452b88-b48f-48d3-bb6c-0296de64164e', 2, 'Type A', '

A

', true) - , (1, '9b6370f7-f941-46f2-bc6e-de455675bd0a', 3, 'Type B', '

B

', false) +insert into campsite_type (company_id, slug, media_id, name, description, active, dogs_allowed, max_campers) +values (1, '87452b88-b48f-48d3-bb6c-0296de64164e', 2, 'Type A', '

A

', true, false, 4) + , (1, '9b6370f7-f941-46f2-bc6e-de455675bd0a', 3, 'Type B', '

B

', false, true, 5) ; insert into campsite_type_i18n (campsite_type_id, lang_tag, name, description) diff --git a/verify/add_campsite_type.sql b/verify/add_campsite_type.sql index a62f1a3..a90a8b6 100644 --- a/verify/add_campsite_type.sql +++ b/verify/add_campsite_type.sql @@ -2,6 +2,6 @@ begin; -select has_function_privilege('camper.add_campsite_type(integer, integer, text, text)', 'execute'); +select has_function_privilege('camper.add_campsite_type(integer, integer, text, text, integer, boolean)', 'execute'); rollback; diff --git a/verify/campsite_type.sql b/verify/campsite_type.sql index 7c76034..c64a061 100644 --- a/verify/campsite_type.sql +++ b/verify/campsite_type.sql @@ -8,6 +8,8 @@ select campsite_type_id , name , media_id , description + , max_campers + , dogs_allowed , active from camper.campsite_type where false; diff --git a/verify/edit_campsite_type.sql b/verify/edit_campsite_type.sql index 76f1e4c..4436b6e 100644 --- a/verify/edit_campsite_type.sql +++ b/verify/edit_campsite_type.sql @@ -2,6 +2,6 @@ begin; -select has_function_privilege('camper.edit_campsite_type(uuid, integer, text, text, boolean)', 'execute'); +select has_function_privilege('camper.edit_campsite_type(uuid, integer, text, text, integer, boolean, boolean)', 'execute'); rollback; diff --git a/web/templates/admin/campsite/type/form.gohtml b/web/templates/admin/campsite/type/form.gohtml index f17143c..e6ee908 100644 --- a/web/templates/admin/campsite/type/form.gohtml +++ b/web/templates/admin/campsite/type/form.gohtml @@ -52,6 +52,22 @@ {{ with .Media -}} {{ template "media-picker" . }} {{- end }} + {{ with .MaxCampers -}} + + {{- end }} + {{ with .DogsAllowed -}} + + {{ template "error-message" . }} + {{- end }} {{ with .Description -}}