Problème modèles d'impression suite à la migration Dokos v3

Bonjour,

Je viens de réaliser une migration de dokos v2.18 vers v3.11.2 et rencontre un problème à priori bien connu dans les forums upstream, mais pour lequel je ne trouve aucune solution:

Lorsque j’affiche un format d’impression (modèle d’origine fourni avec dokos ou modèle modifié), j’ai l’erreur suivante:

J’ai tenté de faire mes devoirs avant de poster ici, mais là, j’avoue que je suis relativement bien perdu.
Des idées svp ?

Cordialement.

App Versions

{
	"erpnext": "3.11.2",
	"frappe": "3.14.1"
}

Route

print/Print Format/Societe - Devis

Trackeback

Traceback (most recent call last):
  File "apps/frappe/frappe/app.py", line 66, in application
    response = frappe.api.handle()
  File "apps/frappe/frappe/api.py", line 53, in handle
    return _RESTAPIHandler(call, doctype, name).get_response()
  File "apps/frappe/frappe/api.py", line 69, in get_response
    return self.handle_method()
  File "apps/frappe/frappe/api.py", line 79, in handle_method
    return frappe.handler.handle()
  File "apps/frappe/frappe/handler.py", line 44, in handle
    data = execute_cmd(cmd)
  File "apps/frappe/frappe/handler.py", line 82, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
  File "apps/frappe/frappe/__init__.py", line 1585, in call
    return fn(*args, **newargs)
  File "apps/frappe/frappe/www/printview.py", line 296, in get_html_and_style
    html = get_rendered_template(
  File "apps/frappe/frappe/www/printview.py", line 209, in get_rendered_template
    html = template.render(args, filters={"len": len})
  File "env/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "env/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "apps/frappe/frappe/templates/print_formats/standard.html", line 32, in top-level template code
    {{ render_field(df, doc, no_of_cols) }}
  File "env/lib/python3.10/site-packages/jinja2/sandbox.py", line 393, in call
    return __context.call(__obj, *args, **kwargs)
  File "env/lib/python3.10/site-packages/jinja2/runtime.py", line 777, in _invoke
    rv = self._func(*arguments)
  File "apps/frappe/frappe/templates/print_formats/standard_macros.html", line 5, in template
    <div>{{ frappe.render_template(df.options, {"doc": doc}) or "" }}</div>
  File "env/lib/python3.10/site-packages/jinja2/sandbox.py", line 393, in call
    return __context.call(__obj, *args, **kwargs)
  File "apps/frappe/frappe/utils/jinja.py", line 95, in render_template
    return get_jenv().from_string(template).render(context)
  File "env/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "env/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "<template>", line 21, in top-level template code
  File "env/lib/python3.10/site-packages/jinja2/sandbox.py", line 393, in call
    return __context.call(__obj, *args, **kwargs)
  File "apps/frappe/frappe/model/base_document.py", line 1094, in get_formatted
    df.fieldtype == "Currency"
AttributeError: 'NoneType' object has no attribute 'fieldtype'

Request Data

{
	"type": "POST",
	"args": {
		"doc": "{\"name\":\"Societe - Devis\",\"owner\":\"orsiris.dejong@Societe.tld\",\"creation\":\"2022-05-18 00:32:14.688848\",\"modified\":\"2022-07-24 21:15:11.073194\",\"modified_by\":\"orsiris.dejong@Societe.tld\",\"docstatus\":0,\"idx\":0,\"doc_type\":\"Quotation\",\"module\":\"Selling\",\"default_print_language\":\"fr\",\"standard\":\"No\",\"custom_format\":0,\"disabled\":0,\"print_format_type\":\"Jinja\",\"raw_printing\":0,\"margin_top\":15,\"margin_bottom\":15,\"margin_left\":15,\"margin_right\":15,\"align_labels_right\":0,\"show_section_headings\":0,\"line_breaks\":0,\"absolute_value\":0,\"font_size\":14,\"font\":\"Default\",\"page_number\":\"Hide\",\"format_data\":\"[{\\\"fieldname\\\": \\\"print_heading_template\\\", \\\"fieldtype\\\": \\\"Custom HTML\\\", \\\"options\\\": \\\"<div class=\\\\\\\"print-heading\\\\\\\">\\\\n    <h2>Devis<br>\\\\n    <small class=\\\\\\\"sub-heading\\\\\\\">{{ doc.name }}</small>\\\\n    </h2></div>\\\"}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"transaction_date\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"Date\\\"}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"Adresse et Contact\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"customer_name\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"Nom du client\\\"}, {\\\"fieldname\\\": \\\"address_display\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"Adresse\\\"}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"items\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"Articles\\\", \\\"visible_columns\\\": [{\\\"fieldname\\\": \\\"item_code\\\", \\\"print_width\\\": \\\"140px\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"item_name\\\", \\\"print_width\\\": \\\"350px\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"image\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"qty\\\", \\\"print_width\\\": \\\"60px\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"uom\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"discount_amount\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"rate\\\", \\\"print_width\\\": \\\"100px\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"amount\\\", \\\"print_width\\\": \\\"100px\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"weight_uom\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"stock_balance\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"additional_notes\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"item_booking\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}]}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"R\\\\u00e8gles de prix\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"pricing_rules\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"D\\\\u00e9tail de la r\\\\u00e8gle de prix\\\", \\\"visible_columns\\\": [{\\\"fieldname\\\": \\\"pricing_rule\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"item_code\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"margin_type\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"rate_or_discount\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"rule_applied\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}]}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"total\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"Total\\\"}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"taxes\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"Taxes et frais de vente\\\", \\\"visible_columns\\\": [{\\\"fieldname\\\": \\\"charge_type\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"row_id\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"account_head\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"description\\\", \\\"print_width\\\": \\\"300px\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"cost_center\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"rate\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"tax_amount\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"total\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"tax_amount_after_discount_amount\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"base_tax_amount\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"base_total\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"base_tax_amount_after_discount_amount\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}, {\\\"fieldname\\\": \\\"item_wise_tax_detail\\\", \\\"print_width\\\": \\\"\\\", \\\"print_hide\\\": 0}]}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"Remises additionnelles et codes promotionnels\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"coupon_code\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"Code promotionnel\\\"}, {\\\"fieldname\\\": \\\"referral_sales_partner\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"Partenaire commercial r\\\\u00e9f\\\\u00e9rent\\\"}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"base_rounded_total\\\", \\\"print_hide\\\": 0, \\\"align\\\": \\\"right\\\", \\\"label\\\": \\\"Total TTC\\\"}, {\\\"fieldname\\\": \\\"valid_till\\\", \\\"print_hide\\\": 0, \\\"align\\\": \\\"right\\\", \\\"label\\\": \\\"Valable jusqu'au\\\"}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"Termes et conditions\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"terms\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"D\\\\u00e9tails du Terme\\\"}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"R\\\\u00e9p\\\\u00e9tition Automatique\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"update_auto_repeat_reference\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"Mettre \\\\u00e0 jour la r\\\\u00e9f\\\\u00e9rence de r\\\\u00e9p\\\\u00e9tition automatique\\\"}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"Informations additionnelles\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"supplier_quotation\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"Devis Fournisseur\\\"}, {\\\"fieldname\\\": \\\"lost_reasons\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"Raisons pour avoir perdu le devis\\\"}, {\\\"fieldtype\\\": \\\"Section Break\\\", \\\"label\\\": \\\"\\\", \\\"pagebreak\\\": 0}, {\\\"fieldtype\\\": \\\"Column Break\\\"}, {\\\"fieldname\\\": \\\"_custom_html\\\", \\\"print_hide\\\": 0, \\\"label\\\": \\\"HTML personnalis\\\\u00e9\\\", \\\"fieldtype\\\": \\\"HTML\\\", \\\"options\\\": \\\"{{ frappe.db.get_value(\\\\\\\"CGVPersonalises\\\\\\\", \\\\\\\"b5ab408963\\\\\\\", \\\\\\\"cgv1\\\\\\\") }}\\\"}]\",\"print_format_builder\":0,\"print_format_builder_beta\":0,\"doctype\":\"Print Format\",\"__onload\":{\"print_templates\":[]},\"__last_sync_on\":\"2022-12-12T15:21:47.423Z\"}",
		"print_format": "Standard",
		"no_letterhead": 0,
		"letterhead": "Societe V3",
		"settings": "{}",
		"_lang": "fr"
	},
	"headers": {},
	"error_handlers": {},
	"url": "/api/method/frappe.www.printview.get_html_and_style"
}

Response Data

{
	"exception": "AttributeError: 'NoneType' object has no attribute 'fieldtype'"
}

Ah, si cela peut aider:

Python 3.10.9
pip 22.3.1
node v16.17.1
yarn 1.22.18
docli 2.5.3

Bonjour @ozy,

Le problème s’explique de la manière suivante:

  1. Vous essayer de visualiser l’impression du type de document Format d’impression (et non celui du devis, sur lequel vous vous trouvez. Pour ça il faut aller dans un devis).

  2. Dans le type de document “Format d’impression”, il y a un champ d’aide qui s’affiche quand on clique sur Format personnalisé
    Dans ce champ il y a des références à des champs fictifs qui servent d’exemples.
    Or lors de la génération du format d’impression, ces champs sont interprétés, et comme ils n’existent pas, ça tombe en erreur.

Je vais faire en sorte que ce champ d’aide ne soit pas inclus lors de la génération d’une impression pour le type de document “Format d’impression”.
Dans votre cas, je ne suis pas certain que ce soit un problème, il vous suffit d’ouvrir un devis et de visualiser le format d’impression de ce devis.

Bonne journée

Merci, en effet c’est bien plus clair, bien que cela “fasse peur” juste après une migration :wink:

1 « J'aime »