From 2ffa7d49c08a46e3bdefa865a993641878d72938 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 21:17:45 +0100 Subject: [PATCH] feat: provide logos via jinja method (#59) (#61) Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com> --- README.md | 16 ++++++++++++++++ eu_einvoice/hooks.py | 9 +++++---- eu_einvoice/jinja.py | 21 +++++++++++++++++++++ eu_einvoice/public/img/fx-basic.png | Bin 0 -> 5556 bytes eu_einvoice/public/img/fx-en16931.png | Bin 0 -> 5323 bytes eu_einvoice/public/img/fx-extended.png | Bin 0 -> 5606 bytes 6 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 eu_einvoice/jinja.py create mode 100644 eu_einvoice/public/img/fx-basic.png create mode 100644 eu_einvoice/public/img/fx-en16931.png create mode 100644 eu_einvoice/public/img/fx-extended.png diff --git a/README.md b/README.md index 004ee4c..8a82813 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,22 @@ The following fields of the **Sales Invoice** are currently considered for the e Document-level discounts are currently not supported, because the e invoice standard requires much more information than just the discount amount (e.g. the reason and applicable VAT rate). +#### Embedding the Factur-X logo + +If you like, you can embed one of the official Factur-X logos in your invoice PDF. This way, a human can easily identify the invoice as a Factur-X eInvoice. + +To do this, use the `get_einvoice_logo` method in your jinja **Print Format**. This method returns a base64-encoded data URL, which can be used in an `` tag. + +```jinja +{{ doc.einvoice_profile }} e-invoice logo +``` + +The following logos are available: + +BASIC | EN 16931 | EXTENDED +--- | --- | --- +![BASIC](eu_einvoice/public/img/fx-basic.png) | ![EN 16931](eu_einvoice/public/img/fx-en16931.png) | ![EXTENDED](eu_einvoice/public/img/fx-extended.png) + ### Purchase Invoice To import a new eInvoice, create a new **E Invoice Import** and upload the XML or PDF file. diff --git a/eu_einvoice/hooks.py b/eu_einvoice/hooks.py index 4ed26b0..3416e09 100644 --- a/eu_einvoice/hooks.py +++ b/eu_einvoice/hooks.py @@ -77,10 +77,11 @@ # ---------- # add methods and filters to jinja environment -# jinja = { -# "methods": "eu_einvoice.utils.jinja_methods", -# "filters": "eu_einvoice.utils.jinja_filters" -# } +jinja = { + "methods": [ + "eu_einvoice.jinja.get_einvoice_logo", + ], +} # Installation # ------------ diff --git a/eu_einvoice/jinja.py b/eu_einvoice/jinja.py new file mode 100644 index 0000000..823c51f --- /dev/null +++ b/eu_einvoice/jinja.py @@ -0,0 +1,21 @@ +import base64 +from pathlib import Path +from typing import Literal + +PROFILE_TO_LOGO = { + "BASIC": "public/img/fx-basic.png", + "EN 16931": "public/img/fx-en16931.png", + "EXTENDED": "public/img/fx-extended.png", +} + + +def get_einvoice_logo(profile: Literal["BASIC", "EN 16931", "EXTENDED"]) -> str | None: + """Return the logo for the given profile, as a base64 encoded data URL.""" + if profile not in PROFILE_TO_LOGO: + return None + + logo_path = Path(__file__).parent / PROFILE_TO_LOGO.get(profile) + logo_bytes = logo_path.read_bytes() + logo_base64 = base64.b64encode(logo_bytes).decode("utf-8") + + return f"data:image/png;base64,{logo_base64}" diff --git a/eu_einvoice/public/img/fx-basic.png b/eu_einvoice/public/img/fx-basic.png new file mode 100644 index 0000000000000000000000000000000000000000..76baec1e9da90ef095ba0c1fcfe4bcdd5a197a27 GIT binary patch literal 5556 zcmbVQbyQSe*B&~DkQhQhLWYi^nHfMNq(QnFL6Mdk=@b!=kWgvqhM`Lu38h1ZMhp;! z?*4|~`>yw0-=E)i*SY&V=ULC$`|h*Py6fH(rK_z9BxNE6002O>M@o;eJ?8c%#=}|# zU<)?@fP1B@X`rn7LX(6AM#2CkXM_V8;N%Q2AOnozUybo!0L$M3ti5fFFiH>{+ivxY z{}uxo;S>yT3Pv~;gWRo{5sr;Q27>-ek9A8+D@OtPmmV7etNgdCTQLZR4SE~#HXNMn zc6clJM{^sR@*goJ6AZ`%#mcaNnhEO)j^(j>>|6pW2>_uW0GAH{z^26s0Pq0t`2i#% z#5B@CCOJ}iC?T~JK7}|gsR#~GOjOzc@zmEZASUK*+Q-y_%&gL!+=}GnoUrgjH}^1I zLq|rAhX5jB9C8Tu`AO(x4NPB*d>h?dTf06xxw*Zrj}P`2=N235+Z0r+-$Z@5zP!A- zy1F?(zdk#?JUzWSKfl2;*H@=UhhGPV$QfZm;(9=O>6gAyn7B-#8 z+`-bPwD(_M zTo_q+c_1U><1@@`kbnQIJ#`3jbPb_omYbfKroJnWo<;*mg&OMGTADlR>e}MsGO;Va z_VcH*hV5;Qu=Qn>qh*3s*R<&vIQ4Y(Vb>qTrf`Q5O3VN!z*dbB&ddnAzP_engxBy% zZi7T*ySGh>ql(98AkOWueWn0DcH49;$n&cCzg0|r+))Q7d&pZ;G-iuvye>EzE87fA|A$;^SDB$a*gORyz|7O z$f)98@5Z!2&q4a7s@AeoeyR5>?XpGpmZ12XinW)S+N}{|>y(Z?)Ex-%a^N{}=ztHT z0C#dw8h5s|RwgBNw3N!JI-{z1%CXHt;nTTKZ7yNia1(`TZV9Y@uqZdd7J5*UB0sPA z`az-UmR~9kX8!5(N6+j7y>)Dljb4J%A+daJ^r*Z*hViEH93WYorG^S>T#yMr2Ge+U&8Jk(HjQp{2gQrMdC)7D+UI9@dRcEXNHk1UGKkWxaXusMO^L!ay8kt8YyE&t_lz($ug1^#grkp! zpkSulu#2!m5Vhc0>~{0%vnyPMMtSA63N>c8cA7#7DckHuz#ZM47K@Y4z5cy0ZaHaY zw?&Hq-2MH+tdljp!j47RvPY}TUqo+#Z()_N)x-zqs+lg@X|Vw=>~v@O(fvD3wwd_I zSqDF&nq}c%JtY+SGDUY`s|VTLuz-lz=sWn(VX^91k%SB`!d}N=DUK`{=C|vr^w<#d`%hW2EKh5* zWH!lg-P)xtRqc6LkTTq}QX?K}fNgRK6OxfD^5la8Py)Pq)`jE6^C6jsh$1{SUg+?v zwl^Q_&U-xq*@N4t9!>nNJZvrJcMr}BX3nm)!-GoT1>-&*vm9QiasRyPiX(R=J~p?8 z|IoAnCp9r>uk-_~+9KHO@B;Y!x_0Ixs_Bmb@9sup(76scZDDNib=y6X&WgXXUtGD@ zUs&6d>X4T`U768r!Tfbo_ZJcaOHLck;NQJ?w=n4$8b{xp7${fK;(k~9Pj18YH32-@ zCz)hE#ett7>qO3U zS>vsvmdpa|=`ONjZL?aQt&D_pd_?7iPOX;BAD&jY{vqS@U3HIhVmad5wLiQl?+L;& z+uZObvW6bn$wR|ikPR4{xO&0PZ0px;+3?V~^xUb#w6%u9(Mp+Zr>{Bqp$~WL^_D{s z{l-<`bAgU_+n@y*sKAAW+ZfvjiP2Q zntad}VN-HJ$VZdoyjY^aRMP6toU^^nij%8h`Lo3Tg7z7GRD!GaGf(Yi>nCWp%cYBs zq!%HJuMo==MCiu7WGzx6G?%!8yr0xvo8>DW-O=OqZbHA^9r!9Ll(&+=S{~acHtr;L z<4F#3ep~!}A7=A+xR_QNW)rNs2F67x(6OhvD%Wf0?d)Jk&qj22-h~+Q%z=gX%sl+f zNJ<+bDi`luhD@EQ&%XbuV|@?zn`C6}k^SK`zF&Y|1O!!)6`qCqQ^TP%e%4HDu~JfB`xyA`iUr42P#Zb$LX}~hwESszwI~F z(#XqsbAfe!Y`v<2hT&hw)vMW`6n-rt3P?;-A$~7eJO84DCS(31Nj^be?D(U%OP=46 zu^Hz-i`2U2?6sN5U7nY7^UV6lm({Sb_8K*5y2O1DT|ed~F|pI+!))i&3%+(>((eSg z#S%$lP=+MGK7%)zJy3*sCbdLR$z%JFk2#!qyRt5#xTc%b%bY}H23x&}Pnyh1`hTWu zHR7%Er4~50eb!#m_CSg2HtvM74);hheeN%LcG{3X@aP^GqrE{8hT0=F^t1rsNs&JZ zc^R_>1ZTfB*}P*c9HBS<^;abve8JcZ{BZ!2l^raV^hxCr7AL>tjUz2h;yn9^EKt|sAE#;1lan4cknxqvYvZ+P3w1bv+NJkU=g15^Fp zi3mVkql)P^NzKdWW<*f(kFCGqkbRWl^rc2-bdfXRA3Nm=Wd%F#;R3ol)MVfAt$%@7yc`B8EbSh420etVaMz41LZ6*G2MB!lTFaEY;xa zMDWp{JFG9AHH_Ru1iSlH(Ed{VVwiPnlKXjqeLzJLHs)-In#SbY0%OX%E|?)+Rwm@K z)dMOBoSS$X`>~^X z6sIIacQV8i^&bnJyl6#juGriqegaigrk~2&~%`zI!b)rh{y>I z^(}61r4R>4Ka>0&_G$2wt@0flKBi06MN{Vz>Q{QwS%%;Dw7lp(XuXa6#;4OI)?2$N zbT``ZGgG7Ef{H)N6SpV`W|SZ%5m3uq-hpg8IjM@4c`})aB zLNsiJa$%XmRN;h1ZdQ#VMpa6Ir@vvK^e^E6_byY;-6A&E6lWC!`c=+XP#~2CW(cQ&^T(?O@l10w|7>VCh?WTw%oq^A$Ud;6T{prHo+VI0wRv zDqhoMZ*v^$;Dq0$lun%Bp52Q>U(-)bjq&4$ZFQTkJ#}5)e|iMl2l;TR(Np3nF+a57 z5cW{!PNt0>%CiPBHl8Xaut`SMuCZNBQglbv5m%n{25cRh*l{oyY|WJ+}~!r40? z2cKVRd>;&hFrm&i9*HJpMB=uNI&u46R}=Wf zJqhg0wlpNe^OngH3qiJ#^Fj&>zWUTvJqaCC6HSd2%t_jVg~9`lS)rrf>I(SB^U=#i z&nI(ficvCFR9d2PM+2t@90M&3j9t0mij8bGM*~yhoze9RhAqAkK&~VO3{^K; z&-4M!tZtcPu3_{hH)$bUxo_Yj#op;RN&Us93}VM3E_4tZ*W|DPhullSHeBhxBrEtX zFlktmJ9F^Ms?l4?s?0+?A3 z^$w#indh^MmUjn$N)H%>#zn-$Vj_KW=ZJ^eH!&i}Brzo$e{-~3J9!Xd`KyB*FfwrI z9ZROKs!8M8^EOjVYq#B(Jyv=8(XkdPhG)r9%vKD9H6<~%n%Oi`>yX&FB&1PSXHIa2 z4Jv=(oXpvbzonv#o`FtY-{r~*zm{>@gg_`DfA*Z()eB5(4z_IK$p2ekNYLaptmiar z`D5;>dYQLhD3LIMdPM}tCs%yEu9D8jppeG=wLO@x0(`piAnyprI%DZnClJ~No+sR? zh!qStFk5M@-z8<6_02LrkPPrP-J5S|>9n80sj3L)4*=JlIlGV%D@OExC&gXO@YR4r ziHAgcjGg)vLsYnRD*h06%>}L9Kf0g~O`-^>W953qUa6X0+E1N$#lAn^qWT=)1@v@7 zn}&+p>5k=QuOhlZMZBbso_gJ-@JErh6kO?{1lf;5`b555PVmf+0%Rg2_bIr?QETqa zQj;usyO#+|IOX>mR%gdRhfuaBFd7R-ZlN&YiqsM!z0&krdg*+}*Q0GMIVCGbe`mgS zOifqaIprSuLnf~dI!FcJs{Guy+qmx~%NwtHFK>R+nDB_*e+?y9eCThPFv<62zTR)G zEi==vfIX literal 0 HcmV?d00001 diff --git a/eu_einvoice/public/img/fx-en16931.png b/eu_einvoice/public/img/fx-en16931.png new file mode 100644 index 0000000000000000000000000000000000000000..0f3838e4c5c8520881c1fb9f564d9c7640e64bc9 GIT binary patch literal 5323 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 KsZb_o5&AE#nM`K@ literal 0 HcmV?d00001 diff --git a/eu_einvoice/public/img/fx-extended.png b/eu_einvoice/public/img/fx-extended.png new file mode 100644 index 0000000000000000000000000000000000000000..b38d0f919ac3826afed03d8c572e74aba213d918 GIT binary patch literal 5606 zcmbtYcT|(zlMYpSFCkRvNKfbqy$ByQiqfU`4oWZ5rGrRS5QHEt@Ih!IpmYemMFi<0 z2tj(2w$a_Q=lA#Sd*Td{+1qc4n;e?7Ah9mt$_lM<= zot*g(3ogTd*YMX3M$Mu~4T4gFpnoe-qy_y+Ld^ohmGQSiMM5fR0I?_lUkCueHOB)0 z2m**i0A!M+^m5c7B{C)jVmdi|N{FPKv6WpwNLX@mNwp8eqfyhgWdteKH+1xL_2Z5V$fZKh0=v1n(S^H^ zvMA!=+F@1#Fe(uNaaf6sMbYuD!gF5v6h8Sk0hzKHLgWc9;#9!Z&fLLrKUL z7<>x>-%5dRz~EC!@TRy_kFZQ2xBNp+=rI_wCkeR#L#`p zZp^F*-!F2`Ud9=Pm1*$59%fEL_#w=zWebpxKQ6jSv!0kYJrH9gzp#{1S5|w!utObR zDtTiA15y3%@Je{#F(s<+j*`Eb414@Kr;Yxf!al!Q&N0ln_s-YyPv&BR(#;>2mOje@ zFPFS@g)$_EnF#+yJH-d>%u~hsV#Vq=LLvYq_{;u@C5bG=8C)czqz5lWH8c3{IVPsd z<*Qbi(a}?XM1!V~!qBNYizx1d+S6K&k`cIj;NriOi1`xT5D`P-R}cf;sTHgW`K?}6 zU#JTzT?dg87^TH5u8y{po$&DIlV(By=7|tQLO!g~ar3EVAC*7%9vS%Qt4YuqXuq>y zubJ`Y9lgMJ5_5i8Mjii~SKWy$r<{fEmo(wS9%j-2|Ia!8JS9t_5}1%Im1-GN_d4yo zOWG0kI7B6NM5aH}k|&QU8z$7m$?Hd6e*U=gkOA9p0FV+XfX(W`@{WBNu@#B^i5|HM zWNh$5-HkJtI1e=veeSZ2G(=cZZsfo4vi;}q-aXG^{GFS;z(Ss; z)6MWlvs<*~cwZJ-tyN5mbPYpFcPe^5 zjlj-H$`h!uXcgNKv`-7|j2#F4M8Beh;#kKe|A!DbuL+G$WH#x{+UGZ+T-MoWT58Zs ziNNm4-bQul{DgF@u-rYawfZ(~#^j3+{55a2YhQ1>!;6ERa;=(#pLxUK>h@N~)2ml{ zD8`v}dM5*^7(%C7$E%gtCS;|I*yrC1^QO&($sX0?hdZj81)DRJbhlnGZ+-!T6!h)5I?x>{moSaisa#ZRpd z!_@zTPBrvxA)MdX8BiCj7n2P9#=Dw&FeAFtk7qC7lJ&@2%tl`IUn&gO zqp~wf&3&$@@?566S^`)6_whnzH5I6+$7W~SSN8>?#T{dFb~kPaMh|-^;uZ}h2>Pdu zyN;;)S=&@lSG-o((QiWRONNDW-x|vRE_vB6!$WK(2nyp(L&EMsr>Q{vdT#7Zj85I# z-X#vxhgLEZU<8`doqVt3S4vEx#(wE{FdULRTFs7p3l?E2*OXH2xL|=WSm-Z&mp0)h37c(+1A^TDdL) zZ+fluX~?o;cc!qw?}|5ekv}#L9G>_#MKzmVZofIL7wHcQi%Lj>>kj+SeGQl(rh{57 z>kNTv-$_8xhjt#tl1h1vclO8Dvab&rf4;K{Hsg!w7iU6Y=Si=7ZIjJTFAuH*uQG+fNPovaCYzrJ;?)o(ZPUU9Kux@S_CO8;geqYP%$#`Glc;Cv& z;UsN-3v-T5<=iBiosjRRZD)o~&IBe1Cdb`k*?|ANFCup<6z1@=jLTYL$02+6!Yhz) zZ^9*u<1?`E$6W!Lt|d}*LzWP!tiYIko z#>GIgNjOvOvtv#Khj)@{T|0K~5Z(P%<&o%1XNEJAxVH+cw7CZS0)nG^BgFZRtHqVs z6gpn*-Fz#9Tgzm`*UqZ0G7_9gq!6kR#F1;aziy3GYlQ43vz#6!%HG(>8wCfHCUT%kyAsPP;bl? zs%6V0y&TL_y(v^k17fpcj z#JWs%l_$NOlB+G-p~9<1=s`(v zQ@$BDN@TB&0s5-GKPN;AXyL#rQY@wGurNorI@%e8W$k!zKj2O)WQ(r}nZbxhHhq#R zVv)n}nte#Xx*8(n{Lu}2{7u|rpP|q24Nm7yjx-WD>@r4Kw)^glYSr$O}^~B$=o%O$v$@KN+PJv2OG(BEO9V( zjH=38J&15oW_)%0DAo33>p+FI@9tJNa#ZB&+761elbn)6@Uk4c&)ZRc+^lZ&j8)nhC9&%X@JU5RMC)*rvwlm+9Fj-`(Y0O3b|eTc;g z`dhAf4&-*oKi;Kp?t6_H58PS2tF=enGYw^liE&Dac!B8`B=>!yq2DFg`sjY-k3&Sx zTGiHN)B2@+dRX((a!F&Sj$OI@qbY?rb2m8XgRDm*k;kD=e{^Ow`E9C3e$0SfzL9$N zf|Fc&ScS0F9{XL!6n3)RkS%@^m5g-!_<;zL8NVYGMTT878FMHBjg74MlyTBf_e8@kk4_EN<0Yl&42!}FXLTw zT76bl*P0F38)3KIUEKEMn9^BwoaZFeaOB zAs1b1Me*t#xKgg5;zE4c?w-8$hi;xD@e8)lsk?0f1cfO!1VRhPT)A`0H`FW&Ugvgw z`wZdjM6byrb8-;jy*JIjK&>IBbt~z5Px2gp*%kH18e@B?;9l7F&0+ z5=2miHU=XpOZii6D2d1o0I$7>{&hL1;!>&xyO?*0a=tfGK*ZlDtC2v|bi`S#14zgm zrjcGJcPnd2yAKy{s$A=3fd32+G-u*{+!Ai2N8%3Ztc=$9&X`lj&p@W_Sv zE2Di>MValu7W`|&w(*-~>qFuZ4hiNv1nIMhL}pC6I%FuCpZkm_$~uKxX_K$3^%ibja;oKT(GxFq`-s{w;9kZOJj*J_}RMKJm0LwQa$oA zFU?Yd!KPO&HkIrt_+{G1f~4<6dZj*?&_EH|NQ}H;uX|}_|1Zy4muK^w;%lVo z=bD!_-zpz;rm?!eEvk^5&ss61AmOfrTi2$dv;Ea7xZ7;)z9xFw)k=4NsEppdyM-qk!-K!CQF=leB^TkOd~!sK z_w|RF_oz2*-ZE$bIqyxlRp9tRI#jcmiax+X;0_^n?ce!rOB%V_UMKfNb)X27g=p;e z06Wo>r|K?D{>|o_4{1{?LHJy*O&<}k*T9z>M k@%Oc(8XZxQI>QZsVF`oB9a@ozdsYSLXc}nLs@X*U7xT-sTmS$7 literal 0 HcmV?d00001