Skip to content

Commit c3317ea

Browse files
committedApr 3, 2024·
Upgrade to biome
1 parent bf9a285 commit c3317ea

28 files changed

+105
-160
lines changed
 

‎.eslintrc.js

-12
This file was deleted.

‎.pre-commit-config.yaml

+9-27
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
exclude: ".yarn/|yarn.lock"
1+
exclude: ".yarn/|yarn.lock|workbench/static/workbench/lib"
22
repos:
33
- repo: https://github.com/pre-commit/pre-commit-hooks
44
rev: v4.5.0
@@ -28,41 +28,18 @@ repos:
2828
rev: 1.16.0
2929
hooks:
3030
- id: django-upgrade
31-
args: [--target-version, "4.2"]
31+
args: [--target-version, "5.0"]
3232
- repo: https://github.com/astral-sh/ruff-pre-commit
33-
rev: "v0.3.0"
33+
rev: "v0.3.5"
3434
hooks:
3535
- id: ruff
3636
- id: ruff-format
37-
- repo: https://github.com/pre-commit/mirrors-eslint
38-
rev: v8.56.0
39-
hooks:
40-
- id: eslint
41-
args: [--fix]
42-
types_or: [css, scss, javascript]
43-
verbose: true
44-
additional_dependencies:
45-
- eslint
46-
- eslint-config-prettier
47-
- eslint-config-preact
48-
- eslint-plugin-compat
49-
- eslint-plugin-jest
50-
- eslint-plugin-react
51-
- eslint-plugin-react-hooks
52-
- "@babel/core"
53-
- "@babel/eslint-parser"
54-
- "@babel/preset-env"
55-
- "@babel/preset-react"
56-
- "@babel/plugin-syntax-class-properties"
57-
- "@babel/plugin-syntax-decorators"
58-
- "@babel/plugin-syntax-jsx"
59-
- jest
6037
- repo: https://github.com/pre-commit/mirrors-prettier
6138
rev: v3.1.0
6239
hooks:
6340
- id: prettier
6441
args: [--list-different, --no-semi]
65-
types_or: [css, scss, javascript]
42+
types_or: [scss]
6643
exclude: "^conf/|.*\\.html$|.*\\.json$"
6744
- repo: https://github.com/tox-dev/pyproject-fmt
6845
rev: 1.7.0
@@ -72,3 +49,8 @@ repos:
7249
rev: v0.16
7350
hooks:
7451
- id: validate-pyproject
52+
- repo: https://github.com/biomejs/pre-commit
53+
rev: "v0.1.0"
54+
hooks:
55+
- id: biome-check
56+
additional_dependencies: ["@biomejs/biome@1.6.3"]

‎absences/absences.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,19 @@ const getRowName = (id) => `person-${id}`
99

1010
// prettier-ignore
1111
const MONTHS = [
12-
"January", "February", "March", "April", "May", "June", "July", "August",
13-
"September", "October", "November", "December"
14-
].map(m => gettext(m))
12+
"January",
13+
"February",
14+
"March",
15+
"April",
16+
"May",
17+
"June",
18+
"July",
19+
"August",
20+
"September",
21+
"October",
22+
"November",
23+
"December",
24+
].map((m) => gettext(m))
1525

1626
export const Absences = ({ absencesByPerson, dateList, reasonList }) => {
1727
const scaleValues = useMemo(

‎absences/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import React from "react"
66
import { Absences } from "./absences"
77

88
function getDateList(start, end) {
9-
let list = []
9+
const list = []
1010
let currentDate = start
1111

1212
while (currentDate <= end) {
@@ -22,7 +22,7 @@ function getDateList(start, end) {
2222
}
2323

2424
document.addEventListener("DOMContentLoaded", () => {
25-
let { absencesByPerson, reasonList, timeBoundaries } = JSON.parse(
25+
const { absencesByPerson, reasonList, timeBoundaries } = JSON.parse(
2626
document.getElementById("absences-data").textContent,
2727
)
2828

‎absences/utils.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ export function getWeekNumber(d) {
4545
// Make Sunday's day number 7
4646
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7))
4747
// Get first day of year
48-
let yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1))
48+
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1))
4949
// Calculate full weeks to nearest Thursday
50-
let weekNo = Math.ceil(((d - yearStart) / 86400000 + 1) / 7)
50+
const weekNo = Math.ceil(((d - yearStart) / 86400000 + 1) / 7)
5151
// Return array of year and week number
5252
return [d.getUTCFullYear(), weekNo]
5353
}

‎biome.json

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/1.6.3/schema.json",
3+
"organizeImports": {
4+
"enabled": false
5+
},
6+
"formatter": {
7+
"enabled": true,
8+
"indentStyle": "space",
9+
"indentWidth": 2,
10+
"ignore": ["*/map/styles_*.json"]
11+
},
12+
"javascript": {
13+
"formatter": {
14+
"semicolons": "asNeeded"
15+
}
16+
},
17+
"linter": {
18+
"enabled": true,
19+
"rules": {
20+
"recommended": true
21+
}
22+
}
23+
}

‎fabfile.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ def _do_deploy(conn, folder, rsync):
2828
with conn.cd(folder):
2929
fl.run(
3030
conn,
31-
"DOTENV=.env/{} venv/bin/python manage.py collectstatic --noinput".format(
32-
fl.config.installations[0]
33-
),
31+
f"DOTENV=.env/{fl.config.installations[0]} venv/bin/python manage.py collectstatic --noinput",
3432
)
3533

3634

‎package.json

-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
"scripts": {
33
"build-bootstrap": "webpack -p --config webpack.config.bootstrap.js"
44
},
5-
"eslintIgnore": [
6-
"workbench/static/workbench/lib"
7-
],
85
"dependencies": {
96
"bootstrap": "^4.6.0",
107
"fh-webpack-config": "^2.0.1",

‎planning/index.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const clamp = (min, value, max) => Math.max(Math.min(value, max), min)
1414
const opacityClamp = (value) => clamp(0.3, value, 1)
1515
const gettext = window.gettext || ((t) => t)
1616
const pgettext = window.pgettext || ((ctx, t) => t)
17-
const fixed = (s, decimalPlaces) => parseFloat(s).toFixed(decimalPlaces)
17+
const fixed = (s, decimalPlaces) => Number.parseFloat(s).toFixed(decimalPlaces)
1818

1919
document.addEventListener("DOMContentLoaded", () => {
2020
const data = JSON.parse(document.querySelector("#planning-data").textContent)
@@ -41,7 +41,7 @@ function months(weeks) {
4141
const months = []
4242
let month = null
4343
for (let index = 0; index < weeks.length; ++index) {
44-
let week = weeks[index]
44+
const week = weeks[index]
4545
if (week.month !== month) {
4646
month = week.month
4747
months.push({ index, month })
@@ -69,8 +69,8 @@ function Planning({ data }) {
6969
const [collapse, setCollapse] = useState(getCollapse())
7070
const toggleCollapse = (id) => {
7171
const storage = window.localStorage.getItem("planningCollapse")
72-
let storageData = storage ? JSON.parse(storage) : []
73-
let index = storageData.indexOf(id)
72+
const storageData = storage ? JSON.parse(storage) : []
73+
const index = storageData.indexOf(id)
7474
if (index >= 0) storageData.splice(index, 1)
7575
else storageData.push(id)
7676
window.localStorage.setItem("planningCollapse", JSON.stringify(storageData))
@@ -201,7 +201,7 @@ function TotalByWeek({ by_week, title }) {
201201
column={FIRST_DATA_COLUMN + idx}
202202
className="planning--range planning--small is-total"
203203
style={{
204-
opacity: opacityClamp(0.3 + parseFloat(hours) / 20),
204+
opacity: opacityClamp(0.3 + Number.parseFloat(hours) / 20),
205205
}}
206206
>
207207
{fixed(hours, 0)}
@@ -374,7 +374,7 @@ function Project({
374374
)}
375375
{external_view ||
376376
by_week.map((hours, idx) => {
377-
hours = parseFloat(hours)
377+
hours = Number.parseFloat(hours)
378378
if (!hours) return null
379379

380380
return (
@@ -410,7 +410,7 @@ function Project({
410410
function WorkedHours({ project }) {
411411
const ctx = useContext(RowContext)
412412
const row = ctx.next()
413-
const sum = project.worked_hours.reduce((a, b) => a + parseFloat(b), 0)
413+
const sum = project.worked_hours.reduce((a, b) => a + Number.parseFloat(b), 0)
414414

415415
return (
416416
<>
@@ -422,7 +422,7 @@ function WorkedHours({ project }) {
422422
</Cell>
423423

424424
{project.worked_hours.map((hours, idx) => {
425-
hours = parseFloat(hours)
425+
hours = Number.parseFloat(hours)
426426
if (!hours) return null
427427

428428
return (
@@ -906,7 +906,7 @@ function UserAbsences({ user }) {
906906
{user[1].map((absences, idx) => {
907907
if (!absences.length) return null
908908

909-
const hours = absences.reduce((a, b) => a + parseFloat(b[0]), 0)
909+
const hours = absences.reduce((a, b) => a + Number.parseFloat(b[0]), 0)
910910

911911
return (
912912
<Cell
@@ -925,13 +925,13 @@ function UserAbsences({ user }) {
925925
}
926926

927927
function findContiguousWeekRanges(hours_per_week) {
928-
hours_per_week = hours_per_week.map((hours) => parseFloat(hours))
928+
hours_per_week = hours_per_week.map((hours) => Number.parseFloat(hours))
929929

930930
let rangeStart = -1
931931
// const ranges = [{start: 0, length: hours_per_week.length - 1}]
932932
// return ranges
933933

934-
let ranges = []
934+
const ranges = []
935935

936936
for (let i = 0; i < hours_per_week.length; ++i) {
937937
if (hours_per_week[i]) {

‎pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ extend-select = [
5151
# flake8-logging
5252
"LOG",
5353
# ruff
54-
"RUF005", "RUF006", "RUF007", "RUF008", "RUF009", "RUF010", "RUF011",
54+
"RUF005", "RUF006", "RUF007", "RUF008", "RUF009", "RUF010",
5555
"RUF015", "RUF016", "RUF017", "RUF100", "RUF200",
5656
]
5757
extend-ignore = [

‎timer/actions.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export async function sendLogbook(dispatch, { activity, current }) {
119119
}
120120

121121
export function overwriteSeconds(dispatch, { activity, current }) {
122-
const seconds = parseInt(
122+
const seconds = Number.parseInt(
123123
prompt(gettext("Overwrite seconds"), Math.ceil(activity.seconds)),
124124
10,
125125
)

‎timer/store.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const serialize = (data) => {
2222

2323
const deserialize = (blob) => {
2424
const deserializeRaw = () => {
25-
let parsed = JSON.parse(blob)
25+
const parsed = JSON.parse(blob)
2626
if (!parsed || !parsed._v) return {}
2727
const { _v, ...data } = parsed
2828
if (_v == VERSION) {
@@ -60,7 +60,7 @@ export function configureStore() {
6060
} catch (e) {
6161
/* intentionally empty */
6262
}
63-
let store = createStore(
63+
const store = createStore(
6464
reducer,
6565
initialState,
6666
compose(
@@ -79,7 +79,7 @@ export function configureStore() {
7979

8080
if (module.hot) {
8181
module.hot.accept(() => {
82-
let reducer = require("./reducers").default
82+
const reducer = require("./reducers").default
8383
store.replaceReducer(reducer)
8484
})
8585
}

‎workbench/audit/models.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,7 @@ class Meta:
5252
verbose_name_plural = _("logged actions")
5353

5454
def __str__(self):
55-
return "{} {} by {} at {}".format(
56-
self.get_action_display(),
57-
self.table_name,
58-
self.user_name,
59-
self.created_at,
60-
)
55+
return f"{self.get_action_display()} {self.table_name} by {self.user_name} at {self.created_at}"
6156

6257
@cached_property
6358
def user_id(self):

‎workbench/awt/models.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,7 @@ class Meta:
110110
def __str__(self):
111111
if self.date_until.year > 3000:
112112
return _("since %s") % local_date_format(self.date_from)
113-
return "{} - {}".format(
114-
local_date_format(self.date_from),
115-
local_date_format(self.date_until),
116-
)
113+
return f"{local_date_format(self.date_from)} - {local_date_format(self.date_until)}"
117114

118115
def save(self, *args, **kwargs):
119116
super().save(*args, **kwargs)
@@ -234,10 +231,7 @@ def pretty_status(self):
234231

235232
@property
236233
def pretty_period(self):
237-
return "{} - {}".format(
238-
local_date_format(self.starts_on),
239-
local_date_format(self.ends_on or self.starts_on),
240-
)
234+
return f"{local_date_format(self.starts_on)} - {local_date_format(self.ends_on or self.starts_on)}"
241235

242236

243237
class VacationDaysOverride(models.Model):

‎workbench/deals/test_deals.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,7 @@ def test_values_and_attributes(self):
184184
response = self.client.get(deal.urls["update"])
185185
self.assertContains(
186186
response,
187-
'<input class="form-check-input" type="radio" name="attribute_{g}" value="{a}" class="my-2" required id="id_attribute_{g}_0" checked>'.format(
188-
g=attribute1_1.group_id, a=attribute1_1.id
189-
),
187+
f'<input class="form-check-input" type="radio" name="attribute_{attribute1_1.group_id}" value="{attribute1_1.id}" class="my-2" required id="id_attribute_{attribute1_1.group_id}_0" checked>',
190188
html=True,
191189
)
192190

‎workbench/expenses/models.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,7 @@ class Meta:
4242
verbose_name_plural = _("expense reports")
4343

4444
def __str__(self):
45-
return "{}, {}, {}".format(
46-
self.owned_by.get_full_name(),
47-
local_date_format(self.created_at.date()),
48-
currency(self.total),
49-
)
45+
return f"{self.owned_by.get_full_name()}, {local_date_format(self.created_at.date())}, {currency(self.total)}"
5046

5147
def save(self, *args, **kwargs):
5248
if self.pk:

‎workbench/expenses/views.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,7 @@ def get(self, request, *args, **kwargs):
6868
(
6969
"%d." % (next(counter),),
7070
MarkupParagraph(
71-
"{}<br />{}: {}<br />{}<br />&nbsp;".format(
72-
local_date_format(cost.rendered_on),
73-
cost.service.project,
74-
cost.service,
75-
cost.description,
76-
),
71+
f"{local_date_format(cost.rendered_on)}<br />{cost.service.project}: {cost.service}<br />{cost.description}<br />&nbsp;",
7772
pdf.style.normal,
7873
),
7974
currency(cost.third_party_costs)

‎workbench/generic.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,7 @@ def get_template_names(self):
4343
if self.template_name is not None:
4444
return [self.template_name]
4545
return [
46-
"{}/{}{}.html".format(
47-
self.model._meta.app_label,
48-
self.model._meta.object_name.lower(),
49-
self.template_name_suffix,
50-
),
46+
f"{self.model._meta.app_label}/{self.model._meta.object_name.lower()}{self.template_name_suffix}.html",
5147
"generic/object%s.html" % self.template_name_suffix,
5248
]
5349

‎workbench/invoices/test_invoices.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -750,8 +750,8 @@ def test_change_paid_invoice(self):
750750
self.assertContains(
751751
response,
752752
"You are attempting to set status to &#x27;In preparation&#x27;,"
753-
" but the invoice has already been closed on {}."
754-
" Are you sure?".format(local_date_format(dt.date.today())),
753+
f" but the invoice has already been closed on {local_date_format(dt.date.today())}."
754+
" Are you sure?",
755755
)
756756

757757
response = self.client.post(

‎workbench/logbook/test_logbook.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,8 @@ def test_log_and_create_service(self):
197197
)
198198
self.assertContains(
199199
response,
200-
'<a href="{}#service{}">service title: service description' "</a>".format(
201-
project.get_absolute_url(), entry.service.id
202-
),
200+
f'<a href="{project.get_absolute_url()}#service{entry.service.id}">service title: service description'
201+
"</a>",
203202
)
204203

205204
def test_log_and_create_service_with_flat_rate(self):
@@ -361,9 +360,9 @@ def test_update_old_disabled_fields(self):
361360
)
362361
self.assertContains(
363362
response,
364-
'<input type="date" name="modal-rendered_on" value="{}"'
363+
f'<input type="date" name="modal-rendered_on" value="{hours.rendered_on.isoformat()}"'
365364
' class="form-control" required disabled id="id_modal-rendered_on">'
366-
"".format(hours.rendered_on.isoformat()),
365+
"",
367366
html=True,
368367
)
369368

‎workbench/notes/models.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,7 @@ class Meta:
4444
verbose_name_plural = _("notes")
4545

4646
def __str__(self):
47-
return "{} - {} {} - {}".format(
48-
self.title,
49-
self.content_type.name,
50-
self.object_id,
51-
self.created_by.get_short_name(),
52-
)
47+
return f"{self.title} - {self.content_type.name} {self.object_id} - {self.created_by.get_short_name()}"
5348

5449
def get_absolute_url(self):
5550
model = self.content_type.model_class()

‎workbench/planning/models.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,7 @@ def clean_fields(self, exclude=None):
112112

113113
@property
114114
def pretty_from_until(self):
115-
return "{} – {}".format(
116-
local_date_format(min(self.weeks)),
117-
local_date_format(max(self.weeks) + dt.timedelta(days=6)),
118-
)
115+
return f"{local_date_format(min(self.weeks))}{local_date_format(max(self.weeks) + dt.timedelta(days=6))}"
119116

120117
@property
121118
def ranges(self):
@@ -135,10 +132,7 @@ def _find_ranges(weeks):
135132
yield {
136133
"from": from_,
137134
"until": until_,
138-
"pretty": "{} – {}".format(
139-
local_date_format(from_),
140-
local_date_format(until_ + dt.timedelta(days=6)),
141-
),
135+
"pretty": f"{local_date_format(from_)}{local_date_format(until_ + dt.timedelta(days=6))}",
142136
}
143137

144138
@property

‎workbench/reporting/test_reporting.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ def test_labor_costs(self):
3939
self.assertEqual(response.status_code, 200)
4040

4141
response = self.client.get(
42-
"/report/labor-costs/?cost_center={}".format(
43-
factories.CostCenterFactory.create().pk
44-
)
42+
f"/report/labor-costs/?cost_center={factories.CostCenterFactory.create().pk}"
4543
)
4644
self.assertEqual(response.status_code, 200)
4745

‎workbench/static/workbench/workbench.js

+15-20
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,16 @@ function doSubmit(el) {
1313
}
1414

1515
$(() => {
16-
const gettext =
17-
window.gettext ||
18-
function (t) {
19-
return t
20-
}
16+
const gettext = window.gettext || ((t) => t)
2117

2218
// AJAX modals
23-
const dismissModals = function () {
19+
const dismissModals = () => {
2420
// LOL, dismiss.
2521
$(".modal, .modal-backdrop").remove()
2622
$(document.body).removeClass("modal-open").removeAttr("style")
2723
}
2824

29-
const initModal = function (data) {
25+
const initModal = (data) => {
3026
dismissModals()
3127

3228
const $data = $(data)
@@ -48,7 +44,7 @@ $(() => {
4844
}
4945

5046
window.initModal = initModal
51-
window.openModalFromUrl = function (url) {
47+
window.openModalFromUrl = (url) => {
5248
$.ajax({
5349
url,
5450
success(data) {
@@ -124,7 +120,7 @@ $(() => {
124120

125121
const fd = new FormData(form)
126122
let params = new URLSearchParams()
127-
for (let part of fd) {
123+
for (const part of fd) {
128124
if (part[1]) params.append(part[0], part[1])
129125
}
130126
params.sort()
@@ -146,12 +142,11 @@ $(() => {
146142
// Calling debounce returns a new anonymous function
147143
return function () {
148144
// reference the context and args for the setTimeout function
149-
let context = this,
150-
args = arguments
145+
const args = arguments
151146

152147
// Should the function be called now? If immediate is true
153148
// and not already in a timeout then the answer is: Yes
154-
let callNow = immediate && !timeout
149+
const callNow = immediate && !timeout
155150

156151
// This is the basic debounce behaviour where you can call this
157152
// function several times, but it will only execute once
@@ -170,12 +165,12 @@ $(() => {
170165
// Call the original function with apply
171166
// apply lets you define the 'this' object as well as the arguments
172167
// (both captured before setTimeout)
173-
func.apply(context, args)
168+
func.apply(this, args)
174169
}
175170
}, wait)
176171

177172
// Immediate mode and no wait timer? Execute the function..
178-
if (callNow) func.apply(context, args)
173+
if (callNow) func.apply(this, args)
179174
}
180175
}
181176

@@ -304,17 +299,17 @@ $(() => {
304299
$(document.body).on("click", "[data-hours-button]", function () {
305300
this.blur()
306301
const value = prompt(this.dataset.hoursButton)
307-
if (parseFloat(value)) {
302+
if (Number.parseFloat(value)) {
308303
$("#id_modal-days")
309-
.val((parseFloat(value) / 8).toFixed(2))
304+
.val((Number.parseFloat(value) / 8).toFixed(2))
310305
.focus()
311306
}
312307
})
313308

314309
$(document.body).on("click", "[data-multiply-cost]", function (e) {
315310
e.preventDefault()
316-
const factor = parseFloat(this.dataset.multiplyCost),
317-
tpc = parseFloat($("#id_modal-third_party_costs").val()),
311+
const factor = Number.parseFloat(this.dataset.multiplyCost),
312+
tpc = Number.parseFloat($("#id_modal-third_party_costs").val()),
318313
cost = $("#id_modal-cost")
319314

320315
if (tpc && factor) {
@@ -467,7 +462,7 @@ function initWidgets() {
467462
// const form = $(this)
468463
//
469464
const read = (sel, root = document) =>
470-
parseFloat(root.querySelector(sel).value) || 0
465+
Number.parseFloat(root.querySelector(sel).value) || 0
471466
const write = (sel, value, root = document) =>
472467
(root.querySelector(sel).value = value.toFixed(2))
473468

@@ -506,7 +501,7 @@ function initWidgets() {
506501

507502
window.addInlineForm = function addInlineForm(slug, onComplete) {
508503
const totalForms = $(`#id_${slug}-TOTAL_FORMS`),
509-
newId = parseInt(totalForms.val(), 10) || 0
504+
newId = Number.parseInt(totalForms.val(), 10) || 0
510505

511506
totalForms.val(newId + 1)
512507
const empty = $(`#${slug}-empty`),

‎workbench/test_history.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ def test_deleted(self):
8585
response = self.client.get(f"/history/contacts_person/id/{person.pk}/")
8686
self.assertContains(
8787
response,
88-
'<a href="/history/contacts_organization/id/{}/" data-toggle="ajaxmodal">'
89-
"Deleted organization instance</a>".format(pk),
88+
f'<a href="/history/contacts_organization/id/{pk}/" data-toggle="ajaxmodal">'
89+
"Deleted organization instance</a>",
9090
)
9191

9292
response = self.client.get(f"/history/contacts_organization/id/{pk}/")
@@ -291,9 +291,7 @@ def test_deal_visibility(self):
291291
def test_costcenter_visibility(self):
292292
"""Cost centers are invisible without LABOR_COSTS"""
293293
self.client.force_login(factories.UserFactory.create())
294-
url = "/history/reporting_costcenter/id/{}/".format(
295-
factories.CostCenterFactory.create().pk
296-
)
294+
url = f"/history/reporting_costcenter/id/{factories.CostCenterFactory.create().pk}/"
297295
self.assert_404_without_feature(url, feature=FEATURES.LABOR_COSTS)
298296

299297
def test_everything(self):

‎workbench/test_tools.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ def test_deletion(self):
6969
self.assertEqual(
7070
messages(response),
7171
[
72-
"Cannot delete '{}' because of related objects (Any service: Bla)."
73-
"".format(project)
72+
f"Cannot delete '{project}' because of related objects (Any service: Bla)."
73+
""
7474
],
7575
)
7676

‎workbench/tools/pdf.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,7 @@ def services_row_with_details(self, service):
322322
None,
323323
[
324324
(
325-
"{} {} à {}/h".format(
326-
hours(service.effort_hours),
327-
service.effort_type,
328-
currency(service.effort_rate),
329-
)
325+
f"{hours(service.effort_hours)} {service.effort_type} à {currency(service.effort_rate)}/h"
330326
)
331327
if service.effort_hours and service.effort_rate
332328
else "",

‎workbench/tools/vcard.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ def person_to_vcard(person):
3535
attr.value = vcard.Address(street=address.postal_address_override)
3636
else:
3737
attr.value = vcard.Address(
38-
street="{} {}\n{}".format(
39-
address.street, address.house_number, address.address_suffix
40-
),
38+
street=f"{address.street} {address.house_number}\n{address.address_suffix}",
4139
code=address.postal_code,
4240
city=address.city,
4341
country=address.country.name,

0 commit comments

Comments
 (0)
Please sign in to comment.