feat(18-01): add the cabana money field (task 1)
- type: money on fields.yaml with currency or currencyFrom, scale (2..4, default 4) and max; boot fails naming the field on two sources, none, a bad scale or max, a column that is not a string or a Scanner/Valuer, or a currencyFrom that is not a string column - a save answers 422 money.invalid, money.too_precise or money.too_large on the field and fills the accepted decimal string unchanged; the same check runs on controller, settings and relation child saves - backend::lang money.* phrases in en and pl - admin SPA: money.ts (parseMoneyInput, trimMoneyDisplay, formatMoney over Intl with the string itself), MoneyField.vue with the currency suffix, blur validation and the read-only box, preview through the control, the field scope on PreviewView; regenerated OpenAPI and TS types, rebuilt modules/boardwalk/dist - acme.payments fixture with TestMoneyFieldCompile and the Docker TestMoneyFieldSmoke; forms.md Money section and cabana README
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/lagoon"
|
||||
"git.golem15.com/golem15/summercms/modules/pact"
|
||||
"git.golem15.com/golem15/summercms/modules/phrasebook"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
@@ -33,7 +34,12 @@ type SettingsResult struct {
|
||||
}
|
||||
|
||||
// SettingsService reads and transactionally updates compiled singleton rows.
|
||||
type SettingsService struct{ DB *gorm.DB }
|
||||
// Tr localizes the 422 messages of the settings Put (a money value outside
|
||||
// its field's scale or max); nil keeps the phrase keys.
|
||||
type SettingsService struct {
|
||||
DB *gorm.DB
|
||||
Tr *phrasebook.Translator
|
||||
}
|
||||
|
||||
// compileSettingLink registers a settings entry that opens an admin
|
||||
// controller. It declares no singleton form and no model; the controller ID
|
||||
@@ -115,6 +121,11 @@ func compileSettingWithTypes(pluginID string, item pact.SettingsItem, fsys fs.FS
|
||||
return nil, fmt.Errorf("cabana: setting %s: %w", item.Code, err)
|
||||
}
|
||||
}
|
||||
if field.Type == moneyType {
|
||||
if err := checkMoneyType(model, field); err != nil {
|
||||
return nil, fmt.Errorf("cabana: setting %s: %w", item.Code, err)
|
||||
}
|
||||
}
|
||||
writable = append(writable, WritableField{Name: field.Name, FillKey: field.Name})
|
||||
}
|
||||
return &CompiledSetting{PluginID: pluginID, Item: item, Form: form, Writable: writable}, nil
|
||||
@@ -151,6 +162,9 @@ func (s SettingsService) Put(ctx context.Context, setting *CompiledSetting, body
|
||||
if err := requireSettingInputs(setting, body); err != nil {
|
||||
return SettingsResult{}, err
|
||||
}
|
||||
if details := moneyDetails(ctx, s.Tr, setting.Form.Fields, body, nil); len(details) > 0 {
|
||||
return SettingsResult{}, &ValidationError{Details: details}
|
||||
}
|
||||
var result SettingsResult
|
||||
err := s.DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
model, err := newSettingModel(setting)
|
||||
|
||||
Reference in New Issue
Block a user