~openerp-commiter/openobject-addons/trunk-extra-addons

« back to all changes in this revision

Viewing changes to sale_margin/report_margin.py

  • Committer: Fabien Pinckaers
  • Date: 2008-11-12 06:43:12 UTC
  • Revision ID: fp@tinyerp.com-20081112064312-fp85io97i1e95tuz
moved

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- encoding: utf-8 -*-
1
2
##############################################################################
2
3
#
3
 
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
4
 
#
5
 
# $Id: partner.py 1007 2005-07-25 13:18:09Z kayhman $
6
 
#
7
 
# WARNING: This program as such is intended to be used by professional
8
 
# programmers who take the whole responsability of assessing all potential
9
 
# consequences resulting from its eventual inadequacies and bugs
10
 
# End users who are looking for a ready-to-use solution with commercial
11
 
# garantees and support are strongly adviced to contract a Free Software
12
 
# Service Company
13
 
#
14
 
# This program is Free Software; you can redistribute it and/or
15
 
# modify it under the terms of the GNU General Public License
16
 
# as published by the Free Software Foundation; either version 2
17
 
# of the License, or (at your option) any later version.
18
 
#
19
 
# This program is distributed in the hope that it will be useful,
20
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 
# GNU General Public License for more details.
23
 
#
24
 
# You should have received a copy of the GNU General Public License
25
 
# along with this program; if not, write to the Free Software
26
 
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
4
#    OpenERP, Open Source Management Solution   
 
5
#    Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
 
6
#    $Id$
 
7
#
 
8
#    This program is free software: you can redistribute it and/or modify
 
9
#    it under the terms of the GNU General Public License as published by
 
10
#    the Free Software Foundation, either version 3 of the License, or
 
11
#    (at your option) any later version.
 
12
#
 
13
#    This program is distributed in the hope that it will be useful,
 
14
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
#    GNU General Public License for more details.
 
17
#
 
18
#    You should have received a copy of the GNU General Public License
 
19
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
27
20
#
28
21
##############################################################################
29
22
 
35
28
 
36
29
 
37
30
class report_account_invoice_product(osv.osv):
38
 
        _name = 'report.account.invoice.product'
39
 
        _auto = False
40
 
        _columns = {
41
 
                'name': fields.date('Month', readonly=True),
42
 
                'type': fields.selection([
43
 
                        ('out_invoice','Customer Invoice'),
44
 
                        ('in_invoice','Supplier Invoice'),
45
 
                        ('out_refund','Customer Refund'),
46
 
                        ('in_refund','Supplier Refund'),
47
 
                ],'Type', readonly=True),
48
 
                'state': fields.selection([
49
 
                        ('draft','Draft'),
50
 
                        ('proforma','Pro-forma'),
51
 
                        ('open','Open'),
52
 
                        ('paid','Paid'),
53
 
                        ('cancel','Canceled')
54
 
                ],'State', readonly=True),
55
 
                'product_id': fields.many2one('product.product', 'Product', readonly=True, relate=True),
56
 
                'amount': fields.float('Amount', readonly=True),
57
 
                'cost_price': fields.float('Cost Price', readonly=True),
58
 
                'margin': fields.float('Margin', readonly=True),
59
 
                'quantity': fields.float('Quantity', readonly=True),
60
 
        }
61
 
        _order = 'name desc'
62
 
        def init(self, cr):
63
 
                cr.execute("""
64
 
                        create or replace view report_account_invoice_product as (
65
 
                                select
66
 
                                        min(l.id) as id,
67
 
                                        substring(i.date_invoice for 7) || '-' || '01' as name,
68
 
                                        i.type,
69
 
                                        i.state,
70
 
                                        l.product_id,
71
 
                                        sum(l.quantity * l.price_unit * (1.0 - l.discount/100.0)) as amount,
72
 
                                        sum(l.quantity * l.cost_price) as cost_price,
73
 
                                        sum((l.quantity * l.price_unit * (1.0 - l.discount/100.0) - (l.quantity * l.cost_price))) as margin,
74
 
                                        sum(l.quantity) as quantity
75
 
                                from account_invoice i
76
 
                                        left join account_invoice_line l on (i.id = l.invoice_id)
77
 
                                group by l.product_id, substring(i.date_invoice for 7), i.type, i.state
78
 
                        )
79
 
                """)
 
31
    _name = 'report.account.invoice.product'
 
32
    _auto = False
 
33
    _columns = {
 
34
        'name': fields.date('Month', readonly=True),
 
35
        'type': fields.selection([
 
36
            ('out_invoice','Customer Invoice'),
 
37
            ('in_invoice','Supplier Invoice'),
 
38
            ('out_refund','Customer Refund'),
 
39
            ('in_refund','Supplier Refund'),
 
40
        ],'Type', readonly=True),
 
41
        'state': fields.selection([
 
42
            ('draft','Draft'),
 
43
            ('proforma','Pro-forma'),
 
44
            ('open','Open'),
 
45
            ('paid','Paid'),
 
46
            ('cancel','Canceled')
 
47
        ],'State', readonly=True),
 
48
        'product_id': fields.many2one('product.product', 'Product', readonly=True),
 
49
        'amount': fields.float('Amount', readonly=True),
 
50
        'cost_price': fields.float('Cost Price', readonly=True),
 
51
        'margin': fields.float('Margin', readonly=True),
 
52
        'quantity': fields.float('Quantity', readonly=True),
 
53
    }
 
54
    _order = 'name desc'
 
55
    def init(self, cr):
 
56
        cr.execute("""
 
57
            create or replace view report_account_invoice_product as (
 
58
                select
 
59
                    min(l.id) as id,
 
60
                    to_char(i.date_invoice, 'YYYY-MM-01') as name,
 
61
                    i.type,
 
62
                    i.state,
 
63
                    l.product_id,
 
64
                    sum(l.quantity * l.price_unit * (1.0 - l.discount/100.0)) as amount,
 
65
                    sum(l.quantity * l.cost_price) as cost_price,
 
66
                    sum((l.quantity * l.price_unit * (1.0 - l.discount/100.0) - (l.quantity * l.cost_price))) as margin,
 
67
                    sum(l.quantity) as quantity
 
68
                from account_invoice i
 
69
                    left join account_invoice_line l on (i.id = l.invoice_id)
 
70
                group by l.product_id, to_char(i.date_invoice, 'YYYY-MM-01'), i.type, i.state
 
71
            )
 
72
        """)
80
73
report_account_invoice_product()
81
74
 
82
75
class report_account_invoice_category(osv.osv):
83
 
        _name = 'report.account.invoice.category'
84
 
        _auto = False
85
 
        _columns = {
86
 
                'name': fields.date('Month', readonly=True),
87
 
                'type': fields.selection([
88
 
                        ('out_invoice','Customer Invoice'),
89
 
                        ('in_invoice','Supplier Invoice'),
90
 
                        ('out_refund','Customer Refund'),
91
 
                        ('in_refund','Supplier Refund'),
92
 
                ],'Type', readonly=True),
93
 
                'state': fields.selection([
94
 
                        ('draft','Draft'),
95
 
                        ('proforma','Pro-forma'),
96
 
                        ('open','Open'),
97
 
                        ('paid','Paid'),
98
 
                        ('cancel','Canceled')
99
 
                ],'State', readonly=True),
100
 
                'categ_id': fields.many2one('product.category', 'Categories', readonly=True, relate=True),
101
 
                'amount': fields.float('Amount', readonly=True),
102
 
                'cost_price': fields.float('Cost Price', readonly=True),
103
 
                'margin': fields.float('Margin', readonly=True),
104
 
                'quantity': fields.float('Quantity', readonly=True),
105
 
        }
106
 
        _order = 'name desc'
107
 
        def init(self, cr):
108
 
                cr.execute("""
109
 
                        create or replace view report_account_invoice_category as (
110
 
                                select
111
 
                                        min(l.id) as id,
112
 
                                        substring(i.date_invoice for 7) || '-' || '01' as name,
113
 
                                        i.type,
114
 
                                        i.state,
115
 
                                        t.categ_id,
116
 
                                        sum(l.quantity * l.price_unit * (1.0 - l.discount/100.0)) as amount,
117
 
                                        sum(l.quantity * l.cost_price) as cost_price,
118
 
                                        sum((l.quantity * l.price_unit * (1.0 - l.discount/100.0) - (l.quantity * l.cost_price))) as margin,
119
 
                                        sum(l.quantity) as quantity
120
 
                                from account_invoice i
121
 
                                        left join account_invoice_line l on (i.id = l.invoice_id)
122
 
                                        left join product_product p on (p.id = l.product_id)
123
 
                                        left join product_template t on (t.id = p.product_tmpl_id)
124
 
                                group by t.categ_id, substring(i.date_invoice for 7), i.type, i.state
125
 
                        )
126
 
                """)
 
76
    _name = 'report.account.invoice.category'
 
77
    _auto = False
 
78
    _columns = {
 
79
        'name': fields.date('Month', readonly=True),
 
80
        'type': fields.selection([
 
81
            ('out_invoice','Customer Invoice'),
 
82
            ('in_invoice','Supplier Invoice'),
 
83
            ('out_refund','Customer Refund'),
 
84
            ('in_refund','Supplier Refund'),
 
85
        ],'Type', readonly=True),
 
86
        'state': fields.selection([
 
87
            ('draft','Draft'),
 
88
            ('proforma','Pro-forma'),
 
89
            ('open','Open'),
 
90
            ('paid','Paid'),
 
91
            ('cancel','Canceled')
 
92
        ],'State', readonly=True),
 
93
        'categ_id': fields.many2one('product.category', 'Categories', readonly=True),
 
94
        'amount': fields.float('Amount', readonly=True),
 
95
        'cost_price': fields.float('Cost Price', readonly=True),
 
96
        'margin': fields.float('Margin', readonly=True),
 
97
        'quantity': fields.float('Quantity', readonly=True),
 
98
    }
 
99
    _order = 'name desc'
 
100
    def init(self, cr):
 
101
        cr.execute("""
 
102
            create or replace view report_account_invoice_category as (
 
103
                select
 
104
                    min(l.id) as id,
 
105
                    to_char(i.date_invoice, 'YYYY-MM-01') as name,
 
106
                    i.type,
 
107
                    i.state,
 
108
                    t.categ_id,
 
109
                    sum(l.quantity * l.price_unit * (1.0 - l.discount/100.0)) as amount,
 
110
                    sum(l.quantity * l.cost_price) as cost_price,
 
111
                    sum((l.quantity * l.price_unit * (1.0 - l.discount/100.0) - (l.quantity * l.cost_price))) as margin,
 
112
                    sum(l.quantity) as quantity
 
113
                from account_invoice i
 
114
                    left join account_invoice_line l on (i.id = l.invoice_id)
 
115
                    left join product_product p on (p.id = l.product_id)
 
116
                    left join product_template t on (t.id = p.product_tmpl_id)
 
117
                group by t.categ_id, to_char(i.date_invoice, 'YYYY-MM-01'), i.type, i.state
 
118
            )
 
119
        """)
127
120
report_account_invoice_category()
128
121
 
129
122
class report_account_invoice_partner(osv.osv):
130
 
        _name = 'report.account.invoice.partner'
131
 
        _auto = False
132
 
        _columns = {
133
 
                'name': fields.date('Month', readonly=True),
134
 
                'type': fields.selection([
135
 
                        ('out_invoice','Customer Invoice'),
136
 
                        ('in_invoice','Supplier Invoice'),
137
 
                        ('out_refund','Customer Refund'),
138
 
                        ('in_refund','Supplier Refund'),
139
 
                ],'Type', readonly=True),
140
 
                'state': fields.selection([
141
 
                        ('draft','Draft'),
142
 
                        ('proforma','Pro-forma'),
143
 
                        ('open','Open'),
144
 
                        ('paid','Paid'),
145
 
                        ('cancel','Canceled')
146
 
                ],'State', readonly=True),
147
 
                'partner_id': fields.many2one('res.partner', 'Partner', readonly=True, relate=True),
148
 
                'amount': fields.float('Amount', readonly=True),
149
 
                'cost_price': fields.float('Cost Price', readonly=True),
150
 
                'margin': fields.float('Margin', readonly=True),
151
 
                'quantity': fields.float('Quantity', readonly=True),
152
 
        }
153
 
        _order = 'name desc'
154
 
        def init(self, cr):
155
 
                cr.execute("""
156
 
                        create or replace view report_account_invoice_partner as (
157
 
                                select
158
 
                                        min(l.id) as id,
159
 
                                        substring(i.date_invoice for 7) || '-' || '01' as name,
160
 
                                        i.type,
161
 
                                        i.state,
162
 
                                        i.partner_id,
163
 
                                        sum(l.quantity * l.price_unit * (1.0 - l.discount/100.0)) as amount,
164
 
                                        sum(l.quantity * l.cost_price) as cost_price,
165
 
                                        sum((l.quantity * l.price_unit * (1.0 - l.discount/100.0) - (l.quantity * l.cost_price))) as margin,
166
 
                                        sum(l.quantity) as quantity
167
 
                                from account_invoice i
168
 
                                        left join account_invoice_line l on (i.id = l.invoice_id)
169
 
                                group by i.partner_id, substring(i.date_invoice for 7), i.type, i.state
170
 
                        )
171
 
                """)
 
123
    _name = 'report.account.invoice.partner'
 
124
    _auto = False
 
125
    _columns = {
 
126
        'name': fields.date('Month', readonly=True),
 
127
        'type': fields.selection([
 
128
            ('out_invoice','Customer Invoice'),
 
129
            ('in_invoice','Supplier Invoice'),
 
130
            ('out_refund','Customer Refund'),
 
131
            ('in_refund','Supplier Refund'),
 
132
        ],'Type', readonly=True),
 
133
        'state': fields.selection([
 
134
            ('draft','Draft'),
 
135
            ('proforma','Pro-forma'),
 
136
            ('open','Open'),
 
137
            ('paid','Paid'),
 
138
            ('cancel','Canceled')
 
139
        ],'State', readonly=True),
 
140
        'partner_id': fields.many2one('res.partner', 'Partner', readonly=True),
 
141
        'amount': fields.float('Amount', readonly=True),
 
142
        'cost_price': fields.float('Cost Price', readonly=True),
 
143
        'margin': fields.float('Margin', readonly=True),
 
144
        'quantity': fields.float('Quantity', readonly=True),
 
145
    }
 
146
    _order = 'name desc'
 
147
    def init(self, cr):
 
148
        cr.execute("""
 
149
            create or replace view report_account_invoice_partner as (
 
150
                select
 
151
                    min(l.id) as id,
 
152
                    to_char(i.date_invoice, 'YYYY-MM-01') as name,
 
153
                    i.type,
 
154
                    i.state,
 
155
                    i.partner_id,
 
156
                    sum(l.quantity * l.price_unit * (1.0 - l.discount/100.0)) as amount,
 
157
                    sum(l.quantity * l.cost_price) as cost_price,
 
158
                    sum((l.quantity * l.price_unit * (1.0 - l.discount/100.0) - (l.quantity * l.cost_price))) as margin,
 
159
                    sum(l.quantity) as quantity
 
160
                from account_invoice i
 
161
                    left join account_invoice_line l on (i.id = l.invoice_id)
 
162
                group by i.partner_id, to_char(i.date_invoice, 'YYYY-MM-01'), i.type, i.state
 
163
            )
 
164
        """)
172
165
report_account_invoice_partner()
173
166
 
174
167
class report_account_invoice_partner_product(osv.osv):
175
 
        _name = 'report.account.invoice.partner.product'
176
 
        _auto = False
177
 
        _columns = {
178
 
                'name': fields.date('Month', readonly=True),
179
 
                'type': fields.selection([
180
 
                        ('out_invoice','Customer Invoice'),
181
 
                        ('in_invoice','Supplier Invoice'),
182
 
                        ('out_refund','Customer Refund'),
183
 
                        ('in_refund','Supplier Refund'),
184
 
                ],'Type', readonly=True),
185
 
                'state': fields.selection([
186
 
                        ('draft','Draft'),
187
 
                        ('proforma','Pro-forma'),
188
 
                        ('open','Open'),
189
 
                        ('paid','Paid'),
190
 
                        ('cancel','Canceled')
191
 
                ],'State', readonly=True),
192
 
                'partner_id': fields.many2one('res.partner', 'Partner', readonly=True, relate=True),
193
 
                'product_id': fields.many2one('product.product', 'Product', readonly=True, relate=True),
194
 
                'amount': fields.float('Amount', readonly=True),
195
 
                'cost_price': fields.float('Cost Price', readonly=True),
196
 
                'margin': fields.float('Margin', readonly=True),
197
 
                'quantity': fields.float('Quantity', readonly=True),
198
 
        }
199
 
        _order = 'name desc'
200
 
        def init(self, cr):
201
 
                cr.execute("""
202
 
                        create or replace view report_account_invoice_partner_product as (
203
 
                                select
204
 
                                        min(l.id) as id,
205
 
                                        substring(i.date_invoice for 7) || '-' || '01' as name,
206
 
                                        i.type,
207
 
                                        i.state,
208
 
                                        i.partner_id,
209
 
                                        l.product_id,
210
 
                                        sum(l.quantity * l.price_unit * (1.0 - l.discount/100.0)) as amount,
211
 
                                        sum(l.quantity * l.cost_price) as cost_price,
212
 
                                        sum((l.quantity * l.price_unit * (1.0 - l.discount/100.0) - (l.quantity * l.cost_price))) as margin,
213
 
                                        sum(l.quantity) as quantity
214
 
                                from account_invoice i
215
 
                                        left join account_invoice_line l on (i.id = l.invoice_id)
216
 
                                group by i.partner_id, l.product_id, substring(i.date_invoice for 7), i.type, i.state
217
 
                        )
218
 
                """)
 
168
    _name = 'report.account.invoice.partner.product'
 
169
    _auto = False
 
170
    _columns = {
 
171
        'name': fields.date('Month', readonly=True),
 
172
        'type': fields.selection([
 
173
            ('out_invoice','Customer Invoice'),
 
174
            ('in_invoice','Supplier Invoice'),
 
175
            ('out_refund','Customer Refund'),
 
176
            ('in_refund','Supplier Refund'),
 
177
        ],'Type', readonly=True),
 
178
        'state': fields.selection([
 
179
            ('draft','Draft'),
 
180
            ('proforma','Pro-forma'),
 
181
            ('open','Open'),
 
182
            ('paid','Paid'),
 
183
            ('cancel','Canceled')
 
184
        ],'State', readonly=True),
 
185
        'partner_id': fields.many2one('res.partner', 'Partner', readonly=True),
 
186
        'product_id': fields.many2one('product.product', 'Product', readonly=True),
 
187
        'amount': fields.float('Amount', readonly=True),
 
188
        'cost_price': fields.float('Cost Price', readonly=True),
 
189
        'margin': fields.float('Margin', readonly=True),
 
190
        'quantity': fields.float('Quantity', readonly=True),
 
191
    }
 
192
    _order = 'name desc'
 
193
    def init(self, cr):
 
194
        cr.execute("""
 
195
            create or replace view report_account_invoice_partner_product as (
 
196
                select
 
197
                    min(l.id) as id,
 
198
                    to_char(i.date_invoice, 'YYYY-MM-01') as name,
 
199
                    i.type,
 
200
                    i.state,
 
201
                    i.partner_id,
 
202
                    l.product_id,
 
203
                    sum(l.quantity * l.price_unit * (1.0 - l.discount/100.0)) as amount,
 
204
                    sum(l.quantity * l.cost_price) as cost_price,
 
205
                    sum((l.quantity * l.price_unit * (1.0 - l.discount/100.0) - (l.quantity * l.cost_price))) as margin,
 
206
                    sum(l.quantity) as quantity
 
207
                from account_invoice i
 
208
                    left join account_invoice_line l on (i.id = l.invoice_id)
 
209
                group by i.partner_id, l.product_id, to_char(i.date_invoice, 'YYYY-MM-01'), i.type, i.state
 
210
            )
 
211
        """)
219
212
report_account_invoice_partner_product()
220
213
 
221
214
 
222
215
class report_account_invoice(osv.osv):
223
 
        _name = 'report.account.invoice'
224
 
        _auto = False
225
 
        _columns = {
226
 
                'name': fields.date('Month', readonly=True),
227
 
                'type': fields.selection([
228
 
                        ('out_invoice','Customer Invoice'),
229
 
                        ('in_invoice','Supplier Invoice'),
230
 
                        ('out_refund','Customer Refund'),
231
 
                        ('in_refund','Supplier Refund'),
232
 
                ],'Type', readonly=True),
233
 
                'state': fields.selection([
234
 
                        ('draft','Draft'),
235
 
                        ('proforma','Pro-forma'),
236
 
                        ('open','Open'),
237
 
                        ('paid','Paid'),
238
 
                        ('cancel','Canceled')
239
 
                ],'State', readonly=True),
240
 
                'amount': fields.float('Amount', readonly=True),
241
 
                'cost_price': fields.float('Cost Price', readonly=True),
242
 
                'margin': fields.float('Margin', readonly=True),
243
 
                'quantity': fields.float('Quantity', readonly=True),
244
 
        }
245
 
        _order = 'name desc'
246
 
        def init(self, cr):
247
 
                cr.execute("""
248
 
                        create or replace view report_account_invoice as (
249
 
                                select
250
 
                                        min(l.id) as id,
251
 
                                        substring(i.date_invoice for 7) || '-' || '01' as name,
252
 
                                        i.type,
253
 
                                        i.state,
254
 
                                        sum(l.quantity * l.price_unit * (1.0 - l.discount/100.0)) as amount,
255
 
                                        sum(l.quantity * l.cost_price) as cost_price,
256
 
                                        sum((l.quantity * l.price_unit * (1.0 - l.discount/100.0) - (l.quantity * l.cost_price))) as margin,
257
 
                                        sum(l.quantity) as quantity
258
 
                                from account_invoice i
259
 
                                        left join account_invoice_line l on (i.id = l.invoice_id)
260
 
                                group by substring(i.date_invoice for 7), i.type, i.state
261
 
                        )
262
 
                """)
 
216
    _name = 'report.account.invoice'
 
217
    _auto = False
 
218
    _columns = {
 
219
        'name': fields.date('Month', readonly=True),
 
220
        'type': fields.selection([
 
221
            ('out_invoice','Customer Invoice'),
 
222
            ('in_invoice','Supplier Invoice'),
 
223
            ('out_refund','Customer Refund'),
 
224
            ('in_refund','Supplier Refund'),
 
225
        ],'Type', readonly=True),
 
226
        'state': fields.selection([
 
227
            ('draft','Draft'),
 
228
            ('proforma','Pro-forma'),
 
229
            ('open','Open'),
 
230
            ('paid','Paid'),
 
231
            ('cancel','Canceled')
 
232
        ],'State', readonly=True),
 
233
        'amount': fields.float('Amount', readonly=True),
 
234
        'cost_price': fields.float('Cost Price', readonly=True),
 
235
        'margin': fields.float('Margin', readonly=True),
 
236
        'quantity': fields.float('Quantity', readonly=True),
 
237
    }
 
238
    _order = 'name desc'
 
239
    def init(self, cr):
 
240
        cr.execute("""
 
241
            create or replace view report_account_invoice as (
 
242
                select
 
243
                    min(l.id) as id,
 
244
                    to_char(i.date_invoice, 'YYYY-MM-01') as name,
 
245
                    i.type,
 
246
                    i.state,
 
247
                    sum(l.quantity * l.price_unit * (1.0 - l.discount/100.0)) as amount,
 
248
                    sum(l.quantity * l.cost_price) as cost_price,
 
249
                    sum((l.quantity * l.price_unit * (1.0 - l.discount/100.0) - (l.quantity * l.cost_price))) as margin,
 
250
                    sum(l.quantity) as quantity
 
251
                from account_invoice i
 
252
                    left join account_invoice_line l on (i.id = l.invoice_id)
 
253
                group by to_char(i.date_invoice, 'YYYY-MM-01'), i.type, i.state
 
254
            )
 
255
        """)
263
256
report_account_invoice()
 
257
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
 
258